При переходе на широкую ногу CSS довольно легко начать использовать сложные селекторы в каждом углу таблиц стилей и распространять нашу (возможно, сгенерированную) разметку с помощью классов и идентификаторов с целью более точного выбора.
Но вот новость: CSS состоят из кода. Если вы не используете препроцессоры CSS или таблицы стилей на основе PHP, это в основном декларативный код, и он обычно присутствует в довольно небольшом количестве по отношению к коду Java, Python, PHP или HTML того же проекта.
Однако без надлежащего обслуживания каждый вид кода подвержен одному и тому же повреждению: дублирование, отсутствие симметрии и инкапсуляции, неплотные абстракции.
В этой статье мы рассмотрим пример рефакторинга небольшого набора правил CSS для устранения их запахов. Чистый код экономит ваше время и деньги, и это верно также в отношении CSS-файлов , размер которых может достигать тысяч строк.
Запахи и тестирование
Для начала обратите внимание, что между разметкой (файлы HTML и PHTML или JSP) и используемыми вами селекторами CSS существует внутренняя связь. Таким образом, рефакторинг одного из них означает изменение другого.
Сначала мы сосредоточимся на поиске запахов в нашем CSS-коде и на их устранении. В нашем распоряжении не так много инструментов, таких как классы и методы, но многие ситуации можно улучшить.
В нашем примере цели рефакторинга:
- дублирование кода в любой форме; селекторы и правила.
- завышение , когда селекторы слишком точны.
- поддельная абстракция , когда имена селекторов включают физические характеристики.
К сожалению, нет автоматизированных сред тестирования для веб-дизайна (не так ли?), Поэтому мы должны полагаться на ручное тестирование. Эти структуры можно построить, просто сделав снимок страниц, просмотренных во время тестов Selenium, и проверив расположение элементов и цвет. Тем не менее, этот подход очень хрупкий, и тест будет нарушаться каждый раз, когда изменяется черта дизайна, даже при разнице в 1 пиксель.
Снимок 1
Давайте начнем с кода. Пример состоит из небольшого меню, созданного с помощью div.
<style> div.menu { float: left; width: 80px; padding: 1px; border: 1px solid gray; } div.menu_item { float: left; width: 80px; background-color: gray; margin-top: 2px; } a.menu_blue_link { color: #003366; text-decoration: none; } br.clear { clear: both; } </style> <div class="menu"> <div class="menu_item"><a class="menu_blue_link" href="/">Home</a></div> <div class="menu_item"><a class="menu_blue_link" href="/contacts">Contacts</a></div> <div class="menu_item"><a class="menu_blue_link" href="/portfolio">Portfolio</a></div> <div class="menu_item"><a class="menu_blue_link" href="/prices">Prices</a></div> </div> <br class="clear" />
Мы собираемся выполнить следующие операции:
- измените разметку на более семантическую. Div используются слишком много в наше время , учитывая их общее чувство.
- пропустите объявление элементов из селекторов, так как они уже довольно уникальны (убрав из спецификации сверхспецификацию, чтобы мы могли многократно изменять div для других элементов, больше не касаясь CSS).
- изменить имена menu_blue_link на menu_link ; это форма дырявой и бесполезной абстракции: что если мы изменим цвет? В итоге мы вынуждены были бы также изменить класс CSS, чтобы избежать зеленой ссылки menu_blue_link. То же самое будет сделано для печально известного <div class = «right»>.
Снимок 2
<style> .menu { float: left; width: 80px; padding: 1px; border: 1px solid gray; } .menu_item { float: left; width: 80px; background-color: gray; margin-top: 2px; list-style-type: none; } .menu_link { color: #003366; text-decoration: none; } br.clear { clear: both; } </style> <ul class="menu"> <li class="menu_item"><a class="menu_link" href="/">Home</a></li> <li class="menu_item"><a class="menu_link" href="/contacts">Contacts</a></li> <li class="menu_item"><a class="menu_link" href="/portfolio">Portfolio</a></li> <li class="menu_item"><a class="menu_link" href="/prices">Prices</a></li> </ul> <br class="clear" />
Сейчас ситуация немного улучшилась, но у нас еще много работы:
- мы можем встроить класс, который показывает себя с его именем: ясно. Это происходит только в <br>, и хотя де-факто стандартом является использование классов с именем clear, я утверждаю, что они также являются утечкой уровня абстракции.
- Мы также можем использовать селекторы включения для объединения различных классов .menu * .
- Мы вводим компромисс использования тега <li> в относительном селекторе CSS вместо класса. Однако теперь в разметке мы будем ссылаться на один класс меньше.
- menu_link будет когда-либо применяться только к элементу, поэтому было бы неправильно абстрагировать его (занижение): мы просто будем ссылаться на него в селекторе.
Снимок 3
<style> .menu { float: left; width: 80px; padding: 1px; border: 1px solid gray; } .menu li { float: left; width: 80px; background-color: gray; margin-top: 2px; list-style-type: none; } .menu a { color: #003366; text-decoration: none; } </style> <ul class="menu"> <li><a href="/">Home</a></li> <li><a href="/contacts">Contacts</a></li> <li><a href="/portfolio">Portfolio</a></li> <li><a href="/prices">Prices</a></li> </ul> <br stye="clear: both;" />
Теперь у нас есть намного более чистая разметка, которая показывает его семантические свойства с элементами списка, и набор правил CSS с уменьшенным количеством дублирования (для того, что мы можем выполнить без императивного кода).
Выводы
Это не ракетостроение , и я надеюсь, что вы уже знали многие из этих трюков; но применение принципов чистого кода в любой ситуации, даже в графическом дизайне, — это разница между новичком и мастером.