Как можно определить, что ваш CSS пованивает? Какие признаки указывают на то, что код неоптимален или что разработчик писал его спустя рукава? На что вы смотрите в первую очередь, чтобы определить, плох или хорош код?
Я подумал, что могу расширить и дополнить ответ Криса исходя из собственного опыта.
Я работаю в BSkyB. Я делаю большие сайты — над последним из них я тружусь уже больше года. Плохой код CSS доставляет мне очень много проблем. Когда занимаешься одним сайтом месяцами, ты просто не можешь себе позволить плохой код, и его обязательно надо исправлять.
Я хочу поделиться несколькими вещами, на которые я обращаю внимание прежде всего, чтобы составить впечатление о качестве, сопровождаемости и чистоте кода CSS.
Отмена стилей
Любые правила CSS, которые отменяют ранее установленные стили (кроме случая сброса стилей) — это тревожный звоночек. Каскадные таблицы стилей по определению должны наследовать предыдущим определениям и дополнять их, а не отменять.
Любое определение вроде:
border-bottom:none; padding:0; float:none; margin-left:0;
обычно не значит ничего хорошего. Если вам приходится обнулять border
, то, скорее всего вы слишком рано его установили. Это трудно объяснить, поэтому приведу пример:
h2{ font-size:2em; margin-bottom:0.5em; padding-bottom:0.5em; border-bottom:1px solid #ccc; }
Здесь мы задаём элементам h2
не только размер шрифта и отступы, но и поля, и подчёркивание снизу, чтобы визуально отделить заголовок от остального контента. Но, очень может быть, что в другом месте нам не понадобятся ни поля, ни подчёркивание. Возможно, мы напишем что-то вроде:
h2{ font-size:2em; margin-bottom:0.5em; padding-bottom:0.5em; border-bottom:1px solid #ccc; } .no-border{ padding-bottom:0; border-bottom:none; }
Теперь у нас уже 10 строк кода и уродливое имя класса. Гораздо лучше будет сделать так:
h2{ font-size:2em; margin-bottom:0.5em; } .headline{ padding-bottom:0.5em; border-bottom:1px solid #ccc; }
8 строк, никакой отмены стилей и красивое, осмысленное имя класса.
Продвигаясь вниз по файлу стилей, добавляйте правила, а не отнимайте. Если вам приходится отменять ранее установленные стили, скорее всего вы добавили их слишком рано.
Представьте себе CSS-файл на десяток тысяч строк с подобными отменами стилей. Куча лишнего кода! Постепенно добавляйте новые определения поверх старых, более простых, не начинайте сооружать слишком сложные правила слишком рано, иначе вы напишете гораздо больше кода, а делать он будет гораздо меньше.
Когда я вижу, что какое-то правило отменяет предыдущее, я почти наверняка знаю, что стили организованы неправильно и нуждаются в переработке.
Магические числа
Их я особенно ненавижу! Магическое число — это бессмысленное значение, которое используется потому, что оно «просто работает». Например:
.site-nav{ /* [styles] */ } .site-nav > li:hover .dropdown{ position:absolute; top:37px; left:0; }
top:37px;
— это магическое число. Единственная причина, по которой оно здесь — так получилось, что элементы списка имеют 37 пикселей в высоту, и выпадающие подменю должны появляться внизу элемента меню.
Проблема в том, что эти 37 пикселей — чистая случайность, и на эту константу совершенно нельзя положиться. Что если кто-то изменит размер шрифта в пункте меню, и он будет иметь 29, а не 37 пикселей в высоту? Что если в Chrome пункт меню будет иметь 37 пикселей высоту, а в IE — 36? Это число работает только в одном конкретном случае.
Никогда, никогда не используйте значения которые «просто работают». В предыдущем примере гораздо лучше было бы написать top:100%;
вместо top:37px;
И это не единственная проблема с магическими числами. Кроме ненадёжности они создают ещё и проблему коммуникации. Как другой разработчик сможет понять откуда взялось это число? Если ваш код больше и сложнее приведённого выше примера, и какое-то из магических чисел вдруг перестало работать, вы столкнётесь с тем, что:
- другой разработчик, не зная, откуда взялось это число, будет вынужден писать правильный стиль для этого случая с нуля;
- или же, если он очень осторожен, он оставит число на месте и попытается решить проблему, не трогая его. Таким образом кривой и некрасивый костыль рискует остаться в коде навечно и обрасти новыми костылями.
Магические числа — это плохо. Они быстро устаревают, они мешают другим разработчикам, их нельзя объяснить и на них нельзя положиться.
Нет ничего хуже, чем наткнуться на такое необъяснимое число в чужом коде. Зачем оно здесь? Что оно значит? Можно ли его трогать или не стоит? Я задаю эти вопросы всякий раз, как вижу такое число. И самый главный вопрос: «Как можно добиться такого же результата без магии?»
Бегите от магических чисел как от чумы!
Излишне узкие селекторы
Примерно вот такие:
ul.nav{} a.button{} div.header{}
Это селекторы, в которые добавлены совершенно лишние уточнения. Они плохи потому что:
- их практически невозможно использовать повторно;
- они увеличивают специфичность;
- от них страдает производительность.
На самом деле их можно (и нужно) было бы записать так:
.nav{} .button{} .header{}
Вот теперь можно применить .nav
к ol
, .button
к input
и быстро заменить div
с классом .header
на элемент header
, когда будем приводить сайт в соответствие с HTML5.
Хотя производительность браузера страдает от таких селекторов не очень сильно, она всё же страдает. Зачем заставлять его перебирать все элементы a
в поисках класса .button
, если можно ограничиться одним лишь классом? Вот ещё более экстремальные примеры:
ul.nav li.active a{} div.header a.logo img{} .content ul.features a.butto
Все они могут быть сильно сокращены или переписаны:
.nav .active a{} .logo > img {} .features-button{}
Каждый раз, когда я натыкаюсь на чересчур подробные селекторы, я пытаюсь выяснить, почему они заданы именно так, и нельзя ли их сократить.
Жестко заданные, абсолютные значения
Так же как и магические числа, они не сулят ничего хорошего. Вот пример:
h1{ font-size:24px; line-height:32px; }
Гораздо лучше было бы написать: line-height:1.333;
Интерльиньяж всегда лучше задавать относительно, чтобы код был гибче. При изменении размера шрифта он будет меняться автоматически. А если вы зададите его в пикселях, то вам придётся писать что-то вроде этого:
h1{ font-size:24px; line-height:32px; } /** * Main site `h1` */ .site-title{ font-size:36px; line-height:48px; }
И так каждый раз, когда изменится размер шрифта заголовка. Вот так гораздо лучше:
h1{ font-size:24px; line-height:1.333; } /** * Main site `h1` */ .site-title{ font-size:36px; }
Вроде бы, разница невелика, но в крупном проекте она может иметь большое значение.
Кстати, это относится не только к line-height
. Практически любое жестко вписанное в код абсолютное значение должно вызывать подозрение.
Единственный случай, когда действительно имеет смысл захардкодить абсолютное значение — это в случае работы со вещами, которые всегда должны иметь определённый размер, например, спрайтами.
Грубая сила
Это один из крайних частных случаев жёстко заданных магических чисел и некоторых других приёмов, которые используются, чтобы заставить вёрстку работать:
.foo{ margin-left:-3px; position:relative; z-index:99999; height:59px; float:left; }
Это ужасный стиль! Все эти уродливые правила наворочены с единственной целью — запихнуть элемент на нужное место любой ценой. Такой код говорит либо об очень плохо спроектированной вёрстке, либо о недостаточном понимании того, как работает блочная модель CSS, либо о том и другом одновременно.
Если вы хорошо продумали вёрстку и разбираетесь в блочной модели, вам вряд ли придётся использовать грубую силу. Если я вижу подобный код, я сразу стараюсь разобраться, в чём проблема, и не надо ли вернуться на несколько шагов назад, чтобы избавиться от необходимости писать такие костыли.
Опасные селекторы
Под опасными селекторами я понимаю такие, которые намного шире, чем необходимо.Вот самый простой и очевидный пример такого селектора:
div{ background-color:#ffc; padding:1em; }
Зачем, зачем накрывать каждый div
на странице этой ковровой бомбардировкой? Зачем кому-нибудь может понадобиться селектор вроде aside{}
? Или header{}
, или ul{}
? Такие селекторы намного, намного шире чем необходимо, и ведут к тому, что нам придется отменять стили, о чём мы уже говорили.
Давайте рассмотрим пример с header{}
более подробно. Многие используют этот элемент, чтобы создать шапку страницы, что совершенно правильно. Но если вы пишете стили для него вот так:
header{ padding:1em; background-color:#BADA55; color:#fff; margin-bottom:20px; }
то это уже совсем не так правильно. Элемент header
вовсе не обязательно подразумевает шапку всей страницы, он может использоваться несколько раз в разных контекстах. Гораздо лучше использовать класс, например .site-header{}
.
Задавать такие подробные стили для такого общего селектора очень опасно. Они просочатся в совершенно непредсказуемые места, как только вы начнёте повторно использовать этот элемент.
Убедитесь, что ваши селекторы бьют точно в цель.
Вот ещё пример:
ul{ font-weight:bold; } header .media{ float:left; }
Когда я вижу, как стили применяются к элементу или к сильно обобщённому классу, как в этом примере, я начинаю паниковать. Я знаю, что они чересчур универсальны и у меня будут проблемы. Эти стили могут быть унаследованы в таких местах, в которых это будет совершенно нежелательно, и мне придётся их отменять.
Реактивное использование !important
Использовать !important
можно. И это действительно важный инструмент. Тем не менее, его стоит использовать с умом.
!important
надо использовать проактивно, а не реактивно.
Это значит, что его можно использовать тогда, когда вы абсолютно уверены, что вам всегда будет нужно, чтобы это стиль имел приоритет, и вы знаете об этом заранее.
Например, в уверены в том, что вы всегда хотите видеть ошибки красными:
.error-text{ color:#c00!important; }
Даже если сообщение об ошибке будет выведено внутри блока, в котором цвет текста синий, мы можем быть уверены, что ошибка останется красной. Мы всегда хотим сообщать об ошибке красным цветом, и поэтому мы сразу пишем !important
.
А вот когда мы используем !important
реактивно, то есть в ответ на возникшую проблему, когда мы запутались и вместо того, чтобы разобраться, прём напролом, тогда это плохо.
Реактивное использование !important
не решает проблему, а только прячет её. Надо лечить болезнь, а не симптомы. Проблема никуда не делась, мы просто перекрыли её сверх-специфичным селектором, тогда как нужно было заняться рефакторингом и архитектурой.
ID
Этот вид «дурного запаха» очень важен при работе в большой команде. Я уже писал о том, что id — это плохо, потому что они сильно увеличивают специфичность селекторов. От них нет никакого толку, и их никогда не стоит использовать в CSS. Используйте их, чтобы связать элементы HTML с кодом на JavaScript, но не для того, чтобы задавать их стиль.
Причины этого просты:
- id можно использовать на странице только один раз;
- класс можно использовать сколько угодно;
- большинство правил, применяемых к id можно разбросать по нескольким классам;
- id в 255 раз специфичнее класса;
- Это значит, что вам понадобится применить 256 классов к элементу, чтобы перевесить один id.
Если вам этого мало, то я уже и не знаю, что тут ещё сказать…
Если я вижу id, я тут же стараюсь заменить его классом. Излишняя специфичность селекторов губит большие проекты, поэтому жизненно важно удерживать её как можно более низкой.
Напоследок — маленькое упражнение. Попробуйте элегантно решить эту проблему. Подсказка: так — не элегантно; и так — тоже.
Расплывчатые имена классов
Расплывчатое имя — это такое, которое недостаточно конкретно описывает назначение класса. Представьте себе класс .card
. Что он делает?
Это очень расплывчатое имя, а расплывчатые имена плохи из-за двух главных причин:
- вы не сможете догадаться, что оно означает;
- оно настолько общее, что легко может быть случайно переопределено другим разработчиком.
Первый пункт очень прост: что означает .card
? Стиль чего он задаёт? Карточки задач в системе управления проектами? Игральную карту в онлайн-казино? Изображение кредитной карты? Трудно сказать, потому что имя слишком туманное. Допустим, мы имеем в виду кредитную карту. Тогда намного лучше назвать класс .сredit-card-image{}
. Да, намного длиннее, но и намного, намного лучше!
Вторая проблема с расплывчатыми именами — их очень легко случайно переопределить. Допустим, вы работаете над сайтом интернет-магазина. Вы используете класс .card
, подразумевая номер кредитки, привязанной к аккаунту. А другой разработчик в это время добавляет возможность купить подарок и приложить к нему карточку с поздравлением. И он тоже называет класс .card
, и пишет для него свои правила, которые конфликтуют с вашими.
Этого легко можно избежать, если использовать более точные имена классов. Классы вроде .card
или .user
слишком туманны. Они малоинформативны и их легко случайно переопределить. Имена классов должны быть точны, насколько возможно.
Заключение
Итак, мы рассмотрели несколько примеров кода «с душком». Это вещи, о которых надо помнить всегда и избегать их изо всех сил, вернее, только малая их часть, на самом деле их гораздо больше. Работая над крупным проектом, который длится месяцы и годы, жизненно важно держать код в хорошей форме.
Кончено, из каждого правила есть исключения, но к ним нужно подходить индивидуально. В большинстве же случаев, такого кода нужно тщательно избегать.
ссылка на оригинал статьи http://habrahabr.ru/post/160177/
Добавить комментарий