Skip to content

Instantly share code, notes, and snippets.

@beautyfree
Created August 26, 2014 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beautyfree/49c97efeab9c71ea7fc8 to your computer and use it in GitHub Desktop.
Save beautyfree/49c97efeab9c71ea7fc8 to your computer and use it in GitHub Desktop.

#CSS & HTML Development Spec#

##Браузеры## Если не оговорено отдельно, то считать эти версии минимально поддерживаемыми. Никакой поддержки IE6 и IE7, даже бесплатно делать не нужно и запрещается! Под Graceful Degardation подразумевается частичный отказ функционала, скругленные углы, тени, анимация. Главное что бы верстка не разваливалась. Если вы знаете браузер, которого нет в этом списке его поддержка не нужна и запрещена.

Вся верстка должна быть mobile ready. Это значит, что сайт должен правильно отображаться на мобильных устройствах (список ниже). Элементы не должны ехать, зум должен работать, при перевороте устройств, все должно правильно репозиционироваться. В случае если не используется responsive design.

####Graceful Degradation####

  • IE9

####Full Support####

  • IE10+
  • Chrome
  • Firefox
  • Opera 11+
  • Safari 6+

####Mobile Browsers####

  • iOS 5+
  • Android 3+
  • WP 7+

##CSS3## Используем CSS3, в случае graceful degradation просто стараемся сохранить каркас, если не оговорено иначе. Весь код должен быть написан в SCSS. Стараемся не просто писать в SCSS а использовать его функционал, наследование, миксины. SCSS должен быть разбит на файлы (header, footer, mixins, globals, pages..) которые инклудсятся через основной файл app.scss

Иконки и маленькие картинки должны быть вынесены в спрайты, если у сайта в папке с изображением насчитывается больше 20 файлов - это показатель к оптимизации. Хороший сервис по генерации спрайтов.

Все изображения должны быть оптимизированы, мы используем TinyPNG и Kraken, каждая картинка прогоняется по обоим сервисам и сравнивается где лучше сжалось. Разница огромная.

Стараемся писать правильные и быстрые селекторы. Если кто не знает они работают справа на лево. Соответсвенно:

<!-- Bad -->
#container header nav {...}

<!-- Good -->
.primary-nav {...}

<!-- Bad -->
article.feat-post {...}

<!-- Good -->
.feat-post {...}

Если необходимо использовать хаки, то можно воспользоваться этим сайтом

##HTML5## Пишем только используя HTML5. Доктайп только .

Стандартный каркас шаблона Twitter Bootstrap 3. Используем 3 версию. Слайдеры, модалки и прочие JavaScript компоненты должны быть взяты из Bootsrtap если они используются. Сторонние библиотеки запрещены.

Обязательно использование header, footer, aside, section тегов, верстка должна быть семантической.

Обязательно нужно проверять проект на увеличение\уменьшение (+-), до 3 раз, то есть изменение на 30% размера в обе стороны. Верстка не должна ехать.

Обязательна проверка элементов на выход за границу блока, в случае если текст будет слишком большим.

Inline стили строго запрещены.

##JavaScript##

####Документация####

JavaScript можно писать как на чистом JS, так и на CoffeeScript.

Оптимизируем JS селекторы

// Beginning your selector with an ID is always best.
// fast
$("#container div.robotarm");
// super-fast
$("#container").find("div.robotarm");

// Be specific on the right-hand side of your selector, and less specific on the left.
// unoptimized
$("div.data .gonzalez");
// optimized
$(".data td.gonzalez");

// Avoid excessive specificity.
$(".data table.attendees td.gonzalez");
// better: drop the middle if possible
$(".data td.gonzalez");

// Avoid the Universal Selector
$(".buttons > *");  // extremely expensive
$(".buttons").children();  // much better
 
$(".gender :radio");  // implied universal selection
$(".gender *:radio"); // same thing, explicit now
$(".gender input:radio"); // much better

Оптимизируем JS при работе с массивами данных

// WRONG WAY
var list = document.querySelector('ul');
ajaxResult.items.forEach(function(item) {
    var li = document.createElement('li');
    li.innerHTML = item.text;

    // Do some normal operations on the LI here,
    // like add classes, modify attributes, add event listeners, etc.

    // Immediately place LI into the parent UL element
    list.apppendChild(li);
});

/*
 * The code above illustrates the wrong way to go about populating the <ul> with items -- a DOM operation 
 * per list item is slow. If you truly want to use document.createElement and handle the item as a node, 
 * it would be much more performant to use a DocumentFragement instead.
 
 * DocumentFragments are a parent-less, "virtual store" for a set of child nodes. In the case of our example, 
 * think of a DocumentFragment as an invisible <ul> element, outside of the DOM, that will hold your nodes until 
 * they are injected into the DOM. The original code sample would be optimized with a DocumentFragment with the 
 * following code:
 */
 
// GOOD WAY
var frag = document.createDocumentFragment();
ajaxResult.items.forEach(function(item) {
    var li = document.createElement('li');
    li.innerHTML = item.text;

    // Do some normal operations on the LI here,
    // like add classes, modify attributes, add event listeners, etc.

    // *Instead place the LI into the fragment*
    frag.appendChild(li);
});

// Lastly, mass-inject all list items via the DocumentFragment
document.querySelector('ul').appendChild(frag);

Еще один подход - удалить элементы из DOM, произвести над ними работу и вернуть их.

var table = $('#some-table');
var parent = table.parent();

table.detach();
table.addLotsAndLotsOfRows();
parent.append(table);

Обязательно использовать debounce при сложных обсчетах или при частом файре ивентов.

function debounce(func, wait, immediate) {
	var timeout;
	return function() {
		var context = this, args = arguments;
		clearTimeout(timeout);
		timeout = setTimeout(function() {
			timeout = null;
			if (!immediate) func.apply(context, args);
		}, wait);
		if (immediate && !timeout) func.apply(context, args);
	};
};

var myEfficientFn = debounce(function() {
	// All the taxing stuff you do
}, 250);

window.addEventListener('resize', myEfficientFn);

Используем базовые библиотеки:

  • jQuery 2.1.0

Для модальных окон, слайдеров, динамического текста и прочего - пишем моки.

Дополнительные библиотеки рекомендованные к использованию, если указана библиотека которая решает конкретную задачу, к примеру WYSIWYG, то используем только ее, никаких TinyMCE и прочих библиотек решающих ту же задачу.

##Файловая структура##

В случае если не использовался yeoman для создания структуры, используем следующую:

/media
|- / vendor
|- - jquery.min.js
|- - angular.min.js
|- - ....
|- / css
|- - app.scss
|- - _header.scss
|- - _footer.scss
|- - ....
|- / js
|- - application.js
|- / img
|- - / temp
|- - - temp_file.png
|- - - .....
|- - sprite.png
|- - ....
|- / fonts
|- - helvetica.ttf
|- - ....
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment