В Хроме и бете Сафари (на момент написания) появился нативный CSS nesting, то есть возможность вкладывать одни css правила в другие, подобно тому, как это позволяют делать препроцессоры вроде SCSS. О том, почему я не большой поклонник этой фичи читайте далее:)

CSS нестинг противоречит практике разделения разметки/структуры HTML и стилизации CSS, что в свою очередь увеличивает связанность кода, делает код менее читаемым и решает задачи, которые уже решают другие подходы без вышеперечисленных проблем. Давайте разберем каждый пункт.

Связанность

Про связанность кода часто говорят в контексте внутри самого CSS, когда речь идет об использовании слишком общих селекторов по элементам и вложенности селекторов. Например, селектор .some-list a может выглядеть безобидно сегодня, но завтра окажется, что в каждом пункте меню не один тип ссылок, а несколько.

Примерно та же проблема возникает, когда мы тянем структуру страницы из HTML в CSS. Посмотрим на пример от создателей нового Internet Explorer Safari:

скриншот кода

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

Я вижу несколько проблем предлагаемого решения:

  1. У списка компонента нет класса. Это может привести к проблемам в будущем. Если что-то поменяется в структуре (в компоненте появится другой список) придется переписывать правило. Но если бы у этих списков был свой класс вся эта конструкция была бы не нужна в принципе (заглянувшие в теги могут догадаться, к чему я веду:)
  2. Собственно, абсолютно все примеры улучшения css нестингом, которые я видел, состоят из совершенно кошмарного изначально кода, вроде такого:

    Да, это не совсем проблема нестинга, но если это единственное, что можно им улучшить, то возможно стоит сначала взяться за изначальные проблемы.
  3. Из этого css непонятно, можно ли будет использовать этот список вне компонента. Если да, то опять же это создаст дополнительную работу.

Читаемость

При использовании нестинга (с любой реализацией), страдает читаемость кода. В обычном CSS правиле есть только два уровня индентации. Верхний с селектором и внутренний со свойствами. Это позволяет максимально быстро пробежать глазами по коду, легко считать и найти нужное. А что с нестингом?

  1. С нестингом вы не знаете заранее, что именно будет стоять на внутреннем отступе: свойство или селектор. Мозгу сложнее отделять строки. Конечно, это отчасти решается подсветкой синтаксиса, но сокращает способы считываемости.
  2. Кроме того вложенность может обозначаться в любую сторону (как в первом примере). Что еще больше увеличивает нагрузку на мозг.
  3. А еще можно вкладывать многоуровневые медиа-запросы. Посмотрите на этот ужас из спецификации:

    Представьте, что вам нужно убрать правило для ориентации экрана, но оставить для ширины. Где это сделать будет быстрее?

В целом я не вижу причин не следовать и здесь золотому правилу “не усложняйте без необходимости”)

Решение

Решение всех этих и многих других проблем уже давно известно и многими в разной форме используется. Это методологии именования классов. Одна из них - БЭМ, которую я использую и могу посоветовать вам. Впрочем, какую именно методологию использовать не так важно, как принципы, на которые они обычно опираются.

Один из таких принципов - давать уникальные классы всем уникальным сущностям. Я не буду здесь углубляться в то, как именно это делается по БЭМу вы можете почитать про это сами по ссылкам в моей подборке или даже попасть на мою лекцию, если она проводится.

Но пока просто предлагаю сравнить два примера:

	ul {
	  padding-left: 1em;
	  .component & {
	    padding-left: 0;
	  }
	}
	ul {
		padding-left: 1em;
	}
	.component__list {
		padding-left: 0;
	}

Какой из них проще понять? Какой будет проще переиспользовать и какой вызовет меньше проблем в будущем?

Методология решает все вышеперечисленные проблемы. Специфичность и каскад не вызовут проблем, если использовать уникальные селекторы без вложенности. Подробнее о решении этих проблем по БЭМу можно почитать в доках.

Тут стоит отметить, что хотя БЭМ допускает применение каскада, но использовать его без крайней необходимости не рекомендуется. Нестинг же по сути построен на предположении, что каскад через вложенные селекторы используется регулярно.

“А как же правило для всех списков?” - спросите вы - “это ведь не по БЭМу”. Да, таких общих стилей лучше избегать. Но, если речь идет об одном селекторе по тегу, то правила с классом его перепишут, так что это не самое страшное, что можно сделать. В целом же БЭМ это не высеченные в граните заповеди, а принципы. Они могут принести пользу, но только, если перед их использованием подумать, что и зачем вы делаете.

Но главное отличие этих подходов с моей точки зрения можно выразить так: нестинг тащит структуру в стили, методология же следует задачам. Поэтому с БЭМом, как ни странно, проще понять, о какой структуре идет речь, не заглядывая в html. Ведь классы описывают ее семантически.

Конечно, нет смысла использовать БЭМ, не думая заранее, что и где нужно будет переиспользовать. И, да, задачи могут поменяться. Но рефакторить элементы в блоки по-моему полегче, чем пытаться переиспользовать вот это чудо:

На всякий случай добавлю, что все вышесказанное относится к любому нестингу, не только нативному, но и из препроцессоров. Просто с распространением натива, наверняка еще больше разработчиков станет все это использовать. И возможно есть задачи, в которых нестинг может чем-то помочь, как и любая другая технология. Я всего-лишь хочу предостеречь от бездумного хватания за этот синтаксис по умолчанию. Вот и весь хот тейк, а кто скушал молодец)