При переходе на широкую ногу 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 с уменьшенным количеством дублирования (для того, что мы можем выполнить без императивного кода).
Выводы
Это не ракетостроение , и я надеюсь, что вы уже знали многие из этих трюков; но применение принципов чистого кода в любой ситуации, даже в графическом дизайне, — это разница между новичком и мастером.