Статьи

CSS рефакторинг

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

Выводы

Это не ракетостроение , и я надеюсь, что вы уже знали многие из этих трюков; но применение принципов чистого кода в любой ситуации, даже в графическом дизайне, — это разница между новичком и мастером.