Skip to content

Latest commit

 

History

History
126 lines (86 loc) · 11.6 KB

README.ru.md

File metadata and controls

126 lines (86 loc) · 11.6 KB

Nest-CSS

Общие сведения

Корневой элемент

Nest-CSS — это методика, основанная на структуре элементов страницы. Должен присутствовать один или несколько уникальных элементов, которые будут выступать корневыми по отношению к своим внутренним элементам. Оформление внутренних элементов задаётся с жёсткой привязкой к своим корневым элементам.

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

Специальный виджет или пользовательский элемент (Custom Element) может также выступать корневым элементом, чтобы впоследствии он мог использоваться в любом месте страницы. При этом для конкретного его расположения могут быть даны уточнения (отступы, размеры и т. п.), с привязкой уже к корневому элементу страницы.

Корнем может быть выбрана и специальная область, которая задаётся, например, наличием класса на некотором элементе. Это может быть полезно для создания набора правил оформления, которые можно будет применить ко внутреннему содержимому любого элемента — например содержимое, пришедшее из пользовательского редактора WYSIWYG, или что-то подобное. С этим вариантом нужно быть наиболее осторожным, чтобы не получить неожиданные пересечения стилей оформления.

Допускается существование правил, задающих оформление элементам глобально, но такие правила должны быть максимально неконфликтными. По сути, они должны быть простыми корректировками стандартных стилей браузера (например, цвет ссылок и подобное).

Путь к элементам от корня задаётся посредством структуры директорий, названных соответственно селектору родительского элемента, начиная от корневого.

Внутренние элементы

Элементы внутри корневого связываются в общем случае посредством дочернего комбинатора (>). Допускается использование комбинатора потомка ( или >>) для отдельных случаев, когда необходимо задать общее оформление элемента независимо от уровня его вложенности. Так стоит поступать только или с небольшими участками дерева элементов, или имея дело с достаточно уникальными элементами. Внутренние элементы, будучи достаточно крупными или независимыми, помещаются в файлы, названные в соответствии с правилами именования (см. ниже).

Комбинаторы соседства (+ и ~) используются стандартным образом по мере необходимости, и не имеют специальных правил для формирования имён файлов — они считаются зависимыми от конкретных элементов, заданных через дочерний, или комбинатор потомка.

Учёт каскада

Методика использует применение стилей оформления по каскаду.

Правильная специфичность достигается путём строгого учёта вложенности элемента. Для модификации оформления, селектор элемента должен быть дополнен соответственно новому состоянию (добавлением псевдо-класса, класса, атрибута), что естественным образом увеличит специфичность селектора относительно его базового состояния.

Нужно учитывать распространение свойств по каскаду. Если свойство наследуется и задано у вышестоящего элемента, его не следует дублировать в данном элементе. Если свойство не наследуется по каскаду, но логически зависит от соответствующего свойства вышестоящего элемента, следует воспользоваться значением inherit. Значение currentColor также может помочь, для учёта связи по цвету.

Структура файлов

Важной частью методики является обеспечение соответствия структуры файлов структуре документа HTML — это обеспечивает удобство работы с большими уровнями вложенности и простоту навигации по коду.

При этом действуют следующие правила:

  • Простые элементы (с малым количеством дочерних, или простым их оформлением) размещаются в файле, названном соответственно их непосредственному селектору: a.css, span.title.css, h1,h2.css (общий стиль для двух уровней заголовков), ul.css (при этом li для списка описан внутри), и т. д.
  • Более сложные элементы формируют директорию, названную соответственно их непосредственному селектору, и содержит дочерние элементы в виде файлов или директорий: html/body/h1.css, my-element/p.css и т. д.
  • При этом стили оформления для самого элемента, заданного директорией, размещаются в файле &.css (частный случай первого правила — & здесь и является селектором самого элемента внутри директории). Также, если нужно описать состояние с модификатором, то используется соответствующий селектор в имени файла, например &.active.css, или даже директория — &.active/&.css.
  • Директории, которые начинаются с _, не воспринимаются как часть селектора и могут использоваться для простой группировки: путь html/body/_headings/h1.css соответствует селектору html > body > h1, а путь _text/a.cssa.
  • Файлы, начинающиеся с _, игнорируются и не включаются в итоговый CSS — такие файлы предназначены для явного импорта через @import. Таким образом можно создавать наборы переменных или примесей (mixins), используемых в нескольких элементах.
  • Если в начале имени файла или директории поставить символ !, то при формировании селектора перед ней будет использован наследственный комбинатор , вместо дочернего >: путь html/body/main/!table.css соответствует селектору html > body > main table.

Инструменты

Сборка по структуре директорий

gulp-css-nbd

Плагин для Gulp, который добавляет к файлу селектор, сформированный на основании пути к нему в файловой системе.

Должен применяться перед другой обработкой или конкатенацией файлов.

gulp.src( './styles/src/**/*.css' )
	.pipe( require( 'gulp-css-nbd' ) )
	// Обработка
	.pipe( require( 'gulp-concat' )( 'common.css' ) )
	.pipe( gulp.dest( './styles/' ) );

Вспомогательные селекторы

postcss-closest

Плагин для PostCSS, который позволяет от текущего элемента сослаться на любой вышестоящий элемент, и добавить к нему модификатор.

Создан для того, чтобы облегчить описание реакции оформления элемента на некоторое глобальное состояние, например класс на body, html или у виджета, без необходимости создания отельной структуры директорий от этого элемента до текущего.

Файл html\body\main\p.css:

html > body > main > p:closest(body with .index)
{
	...
}

На выходе:

html > body.index > main > p
{
	...
}

Без плагина пришлось бы создать файл html\body\&.index\main\p.css.

Использование

var gulp = require( 'gulp' );
var sourcemaps = require( 'gulp-sourcemaps' );

var cssNdb = require( 'gulp-css-nbd' );
var concat = require( 'gulp-concat' );

var postcss = require( 'gulp-postcss' );
var precss = require( 'precss' );
var autoprefixer = require( 'autoprefixer' );
var closest = require( 'postcss-closest' );

gulp.task(
	'styles',
	function ()
	{
		var precssOptions = {
			extension: 'pcss',
			// Текущая версия postcss-partial-import в PreCSS не поддерживает `dirs`
			dirs: ['./styles/src/_globals/']
		};
		
		gulp.src( './styles/src/**/*.pcss' )
			// .pipe( sourcemaps.init() )
			// gulp-css-nbd в настоящий момент не работает с sourcemaps
			.pipe( cssNdb() )
			.pipe( postcss( [precss( precssOptions ), closest, autoprefixer] ) )
			.pipe( concat( 'common.css' ) )
			// .pipe( sourcemaps.write( '.' ) )
			.pipe( gulp.dest( './styles/' ) );
	}
);