Главная » Статьи » Область видимости в CSS

Область видимости в CSS

Область видимости в CSS

От автора: сегодня мы рассматриваем сложную проблему области видимости CSS. Джаваскриптеры справедливо считают, что тот факт, что все селекторы CSS находятся в глобальной области видимости, усложняет их приложения. Что мы можем с этим поделать?

Я написал объяснение ниже. Как обычно, я бы хотел услышать, подходит ли это объяснение для вас или, наоборот, смущает.

Глобальная область видимости

Любой селектор CSS действителен во всем документе. Если вы используете p span, то он выберет все span в пределах р во всем документе. Здесь каждый span в пределах p в документе имеет красный фон.

p span { background-color: red;
}

Иногда нам этого не нужно. Иногда нам нужно выбрать только span в р в конкретном модуле. Это ядро проблемы контекста в CSS: как ограничить определения стиля только тем модулем, над которым вы работаете.

Основным решением является добавление имени класса или идентификатора перед фактическим селектором; что — то вроде #myModule p span. Теперь объявление распространяется на элемент myModule.

В этом примере кода промежутки в p имеют красный цвет, кроме случаев, когда они находятся в элементе myModule; тогда они голубые.

#myModule { border: 1px solid black; padding: 1em;
} p span { background-color: red;
} #myModule p span { background-color: blue;
}

Да, для областей видимости это подходит, но файл CSS превращается в беспорядочный набор селекторов, переопределений и других вещей. Для примера, где именно нам поместить правило #myModule p span? Я всегда помещаю его после глобального селектора, который отменяет его, как в примере выше, но я могу понять, почему люди установили его сразу после #myModule. Все становится совсем интересно, когда вы беретесь за чужой CSS.

Области видимости CSS-селекторов со здравым, читаемым синтаксисом — одна из целей многих решений CSS-in-JS, которые сейчас привлекают внимание разработчиков. (Другая цель — убедиться, что идентификаторы областей видимости не повторяются — если ваш HTML содержит два элемента с id = «myModule», у вас снова возникает та же проблема с областями видимости.)

Тем не менее, похоже, что проблема определения области видимости CSS будет решена в недалеком будущем. Ограниченный локальный охват уже существует, и готовится полное решение.

Пользовательские свойства CSS

Пользовательские свойства CSS (также называемые переменными CSS) уже имеют область видимости. Можно переопределить значение пользовательского свойства для конкретного элемента и его потомков. Возьмем этот пример:

body { --color: red;
} #myModule { border: 1px solid black; padding: 1em; --color: blue
} p span { background-color: var(--color);
}

Теперь span в p имеет красный фон, за исключением myModule, где он имеет синий фон. На практике, элементы html и body считаются глобальной областью; большинство других элементов — локальными областями видимости.

Пользовательские свойства могут содержать любое допустимое значение CSS, и они работают для любого объявления. Таким образом, мы могли бы расширить пример следующим образом:

body { --color: red; --spandisplay: inline;
} #myModule { border: 1px solid black; padding: 1em; --color: blue --spandisplay: block;
} p span { background-color: var(--color); display: var(--spandisplay);
}

Теперь для span в p в myModule задано display: block, а для span в p в других местах — display: inline. Нет сомнений в том, что с введением пользовательских свойств в CSS появилась локальная область видимости. Также нет сомнений в том, что система может стать неуклюжей, если вы хотите использовать локальную область видимости в больших масштабах.

Теоретически можно определить квазиллион пользовательских свойств в myModule для внутреннего использования, а также определить те же свойства с другими значениями в otherModule. Однако это предполагает, что внутренне модули будут иметь одинаковую структуру. Например, в простом примере, приведенном выше, предполагается, что каждый модуль на всей странице использует p span аналогичным образом. Если бы otherModule использовал вместо этого p strong, вам нужно было бы добавить новые объявления. Все это не невозможно, но сомнительно, решает ли это проблему определения области видимости CSS оптимальным способом.

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

Вложение CSS

Спецификация CSS Nesting предлагает новый способ сортировки локальных селекторов CSS. Обратите внимание, что эта спецификация является относительно новой, и потребуется некоторое время, прежде чем браузеры ее реализуют.
CSS-препроцессоры уже давно выполняют вложения, и предлагаемый синтаксис очень близок к SASS:

p span { background-color: red; /* display: inline is the default anyway; no need to define it */
} #myModule { border: 1px solid black; padding: 1em; & p span { background-color: blue; display: block; }
}

& p span принимает значение #myModule p span; другими словами, & — это родительский селектор. Обратите внимание, что использование & обязательно: CSS должен знать, куда вставить родительский селектор.

С одной стороны, CSS Nesting предлагает синтаксический сахар, но ничего принципиально нового. Мы уже видели, как написать пример на современном CSS.

С другой стороны, вложенный вариант гораздо удобнее для чтения и предлагает простой способ указать, является ли определенный селектор локальным или глобальным. Совершенно ясно, что & p span — это локальный селектор, и что его стили не будут применяться вне myModule. С другой стороны p span вне блока являются глобальными.

Это значительно упрощает определение области видимости селекторов и делит CSS-файлы. Если вы работаете с myModule, вы добавляете стили в блок myModule. Если вы определяете стили вне этого блока, становится ясно, что они являются глобальными.

Поможет ли нам вложение CSS?

Сегодняшний вопрос для джаваскриптеров: думаете ли вы, что вложение CSS значительно облегчит вашу работу? Мне кажется — да, но я являюсь старым фронт-энд разработчиком и мало знаком с современными экосистемами JavaScript, поэтому я могу что-то упустить.

Источник: https://www.quirksmode.org

Редакция: Команда webformyself.