От автора: как и для чего использовать в JavaScript CSS? Те, кто знаком с веб-платформой, хорошо разбираются в ее двух дополнительных технологиях: HTML для документов и их структуры, а также JavaScript для взаимодействия и стилизации.
До тех пор, пока кто-либо помнит, стилизация документов — влияющая на их внешний вид — была упрощена с помощью JavaScript свойства style, которое существует для любого поддерживающего узла DOM.
1 |
node.style.color = 'red'; |
До появления стилизации API, авторы HTML должны были писать атрибуты style в DOM вручную, что препятствовало процессу редактирования.
В сочетании с механизмом выбора узлов JavaScript мы можем одновременно создавать несколько элементов. В следующем примере все p узлы имеют красный цвет текста.
1 2 3 4 |
const nodes = document.querySelectorAll('p'); Array.prototype.forEach.call(nodes, node => { node.style.color = 'red'; }); |
Одна из замечательных особенностей этого движка селекторов заключается в том, что он позволяет одновременно настраивать разные типы элементов, предоставляя список, разделенный запятыми.
1 |
const nodes = document.querySelectorAll ('p, li, dd'); |
То, что менее просто, заключается в прикреплении нескольких стилей к любому узлу. Следующий подход быстро становится многословным.
1 2 3 4 |
node.style.color = 'red'; node.style.backgroundColor = 'black'; node.style.padding = '1rem'; // etc. |
Единственной стандартизированной альтернативой является использование свойства cssText:
1 |
node.style.cssText = 'color: red; background-color: black; padding: 1rem; '; |
Проблемно управлять несколькими стилями как одной строкой. Это затрудняет обновление, удаление или замену отдельных стилей в будущем.
По этой причине авторы изобрели способы управления информацией о стилях в объектах, часто манипулируя прототипом интерфейса Element.
1 2 3 4 5 |
Element.prototype.styles = function(attrs) { Object.keys(attrs).forEach(attr => { this.style[attr] = attrs[attr]; }); } |
Добавить стилей к узлу теперь можно так:
1 2 3 4 5 |
node.styles({ 'color': 'red', 'backgroundColor': 'black', 'padding': '1rem' }); |
Этот подход к присвоению имеет тенденцию широко использоваться во всем приложении и его жизненном цикле. Очень трудно понять, куда положить все это, или как четко отделить от сценариев взаимодействия, которые являются другой обязанностью JavaScript.
Но есть еще одна, более фундаментальная проблема: эти свойства стиля не реактивны. Например, допустим, я установил некоторые стили для отключенных кнопок:
1 2 3 4 5 6 7 |
const disableds = document.querySelectorAll('[disabled]'); Array.prototype.forEach.call(disableds, disabled => { disabled.styles({ 'opacity': '0.5', 'cursor': 'not-allowed' }); }); |
Эти стили применяются только к отключенным кнопкам, которые уже находятся в DOM. Любые отключенные кнопки, добавленные в DOM или кнопки, которые приобретают свойство / атрибут disabled, не будут автоматически принимать соответствующий стиль.
1 2 |
button.disabled = true; button.style // nothing new here |
Можно прослушать изменение атрибута и отреагировать на него с помощью mutationObserver:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
const button = document.querySelector('button'); var config = { attributes: true } var callback = function(mutationsList) { for(var mutation of mutationsList) { if (mutation.type == 'attributes') { if (button.disabled) { button.styles({ 'opacity': '0.5', 'cursor': 'not-allowed' }); } } } } var observer = new MutationObserver(callback); observer.observe(button, config); |
Я думаю, мы можем согласиться, что кода довольно много, тем более, что он делает только один экземпляр одного типа элементов, реагирующих на изменение одного типа атрибута. Это также изменяет стиль только в одном направлении: нам нужно будет обрабатывать стили при отключении свойства disabled. Непросто, поскольку мы не знаем начальных значений для opacity или cursor.
Как бы мне не нравился JavaScript, я не думаю, что он хорошо заточен, когда речь заходит о задачах стилизации. Это, в конце концов, процедурный и основанный на событиях язык, тогда как стиль — это то, что у вас есть или нет.
Мы тратим слишком много времени на то, чтобы писать и поддерживать стили с помощью JavaScript, и я думаю, что пришло время для перемен. Вот почему я с удовольствием объявляю о появлении нового веб-стандарта под названием CSS.
CSS
CSS — это декларативное подмножество JavaScript, оптимизированное для задач стилизации. Файл CSS принимает расширение .css и, что важно, полностью анализируется отдельно для стандартных файлов JavaScript. С CSS наконец можно отделить стиль от поведения. Вы можете создавать свои приложения без необходимости касаться своей бизнес-логики!
Синтаксический сахар
Одна из первых вещей, которую вы заметите — это более чистый синтаксис, который понравятся поклонникам CoffeeScript:
1 2 3 4 |
[disabled] { opacity: 0.5; cursor: not-allowed; } |
Объектно-подобная структура остается, но вам больше не нужно явно вызывать querySelectorAll для итерации по узлам DOM. Итерация позаботится о себе вместо этого, делая ее более эффективной.
Вышеприведенный пример автоматически затрагивает все узлы DOM с disabled атрибутом. Еще лучше: любые новые кнопки, использующие отключенное свойство, сразу же принимают связанные стили. Реактивный из коробки!
Каскад
CSS — это каскадные таблицы стилей. Каскадная часть, пожалуй, самая лучшая ее особенность. Рассмотрим следующий CSS.
1 2 3 4 5 6 7 |
button { background-color: blue; cursor: pointer; } [disabled] { cursor: not-allowed; } |
Стили для блока [disabled] идут после блока button в таблице стилей. Любые стили, объявленные в блоке [disabled] с теми же ключами (именами свойств), что и в предыдущем блоке button становятся переопределениями. Результатом является то, что добавление disabled атрибута / свойства к кнопке только обновляет соответствующие стили. В приведенном выше примере cursor обновляется, но background-color остается неизменным. Это своего рода система фильтрации.
Кроме того, если disabled атрибут / свойство удаляется, стили по умолчанию автоматически восстанавливаются — потому что теперь узел только соответствует блоку button дальше каскада. Не нужно «помнить», какие стили были применены и при каких условиях.
Упругость
При стилизации с использованием JavaScript любые непризнанные свойства стиля или синтаксические ошибки прекращают парсинг скрипта. Любые последующие стили или взаимодействия будут просто отброшены в массовом порядке, и ваше приложение будет падать.
CSS более надежный. В большинстве случаев непризнанное свойство или синтаксическая ошибка приведет к тому, что одно, ошибочное объявление (пара свойств / значения) будет удалено.
Это нововведение признает, что различные браузеры поддерживают различные свойства стиля и что отдельные стили не являются критическими. Устойчивость CSS означает, что больше пользователей получают доступ к функциональному интерфейсу.
Заключение
Хорошим признаком того, что технология не подходит для цели, является то, как много мы должны полагаться на обходные пути и лучшие практики. Другим признаком является то, сколько кода нам нужно написать, чтобы сделать простые вещи. Когда дело доходит до стиля, JavaScript — это та технология.
CSS решает проблемы стилизации JavaScript, и делает это элегантно. Вопрос в следующем: согласны ли вы принять изменения или вы связаны более низкой методологией?
Автор: Heydon
Источник: //medium.com/
Редакция: Команда webformyself.