Нюансы CSS

Лев Солнцев

Редактура Вадим Макеев

Многие используют CSS для оформления сайтов и веб-страниц, знают основные приёмы вёрстки, а если и нет, то быстро найдут решение в интернете, или им подскажут в тематических сообществах. Тем не менее многие широко используемые решения не оптимальны, и если ознакомиться со спецификациями чуть глубже, можно написать лучший код.

К примеру многие знают, что цвет в шестнадцатеричной нотации вида #RRGGBB можно писать сокращённо как #RGB, если каждый старший разряд совпадает с младшим, или что нуль можно писать без единиц измерения, таких как «px» или «em», так как нуль — в любой системе измерения нуль.

Что считает браузер#

Также широко известно, что можно отцентрировать блок с шириной меньше родительского элемента при помощи margin: 0 auto. Однако мало кто задумывается, что почти во всех случаях дело касается непозиционированных элементов, и в этом случае значение margin-top: auto или margin-bottom: auto устанавливается равным нулю, а значит данное правило можно сократить до простого margin: auto.

Правила margin-left: auto и margin-right: auto при ширине блока меньше ширины контейнера равномерно распределяют оставшееся место. Так, задав только margin-left: auto, можно выровнять элемент по правому краю.

В обычном потоке элементы идут сверху вниз, поэтому margin-top: auto устанавливается нулевым. Однако для абсолютно спозиционированных элементов действует то же распределение свободного места, и аналогичным образом можно сделать центрирование по вертикали при заданных высоте и top с bottom (не работает в IE7).

Сокращения и значения по умолчанию#

Не менее широко распространено использование спрайтов, например: background: url(icons.png) 0 0 no-repeat. Однако, background-position: 0 0 является значением по умолчанию, поэтому 0 0 в таком случае можно опустить.

Но если в background-position задана хоть одна координата: будь то top, left или 100%, то вторая принимает значение 50%. Это может быть полезно для значков, выровненных посередине строки по вертикали — достаточно указать лишь положение слева или справа.

Не все знают, что опущенные в сокращённой записи правила принимают своё значение по умолчанию. Поэтому уточняющие правила надо писать после или делать сильнее общей сокращённой надписи, как background-position уточняет положение каждого спрайта после background в предыдущем примере.

При подобном написании:

h1 {
    font: 2em/1 Arial,sans-serif;
}

задаётся не только шрифт, его размер и интерлиньяж, но и сразу сбрасывается полужирное написание (font-weight: normal), а также другие свойства, такие как font-style (курсив) и font-variant (капитель). Некоторые авторы совершенно зря дописывают в font значение normal. Непонятно даже к какому правилу из перечисленных трёх оно могло бы относиться — порядок следования в сокращённых свойствах неважен, и неучитывание порядка могло приводить к ошибкам лишь в устаревших браузерах.

Другими недопонятыми, но тоже полезными сокращёнными записями являются отдельные правила рамок border-width, border-style и border-color. Например, благодаря им можно задать верхнюю и нижнюю одинаковые рамки не дублированием кода в border-top и в border-bottom, а подобным образом:

border: solid gray;
border-width: 3px 0;

Кроме меньшего размера кода, такая запись полезна тем, что каждое значение написано только один раз, и поменять, скажем, solid на double не составляет труда.

Более того, если будет использоваться border-image, то здесь явно задано, что размер боковых рамок нулевой. В противном случае border-image приводит к неявному появлению рамок, что может дать неожиданный эффект в углах.

Есть возможность, что border-radius может быть включен в сокращённую запись border (предлагался вариант с косой чертой «/»), поэтому записывайте на всякий случай border-radius после border.

Переусложенение#

Часто, чтобы избавиться от рамки на картинке внутри ссылки, пишут:

a img {
    border: 0;
}

Однако в таком случае бразуер будет на каждой картинке проверять, не находится ли она в ссылке. Если для простых страниц это кажется несущественным (вы и глазом моргнуть не успеете за те несколько миллисекунд, на которое задержится отображение страницы), то в какой-нибудь фотогалерее со сложной анимацией это может лишить вас нескольких кадров в секунду, прибавляя ощущения «тормознутости». Куда проще написать так:

img {
    border: 0;
}

Эффект будет тот же самый. Уточнение, что рамка появляется на ссылках a в данном случае совершенно излишне.

Из тех же соображений производительности, как правило, незачем писать имя тэга вместе с классом и уж тем более с идентификатором, который сам по себе уникален. В данном правиле могут быть только два исключения: уточнение для конкретного тэга (возможно в этом случае у вас очень общий класс), и обход недостатка IE7, где эффекты при наведении :hover тормозят, если в селекторе не указан тэг (то есть надо писать a.class:hover { color: #FC0; }).

Наследование#

Ещё одна недооценённая многими возможность CSS: наследование стилей. Например, может не устраивать, что по умолчанию содержимое ячеек таблиц центрируется по вертикали, при этом используются следующие правила:

th {
    vertical-align: bottom;
}

td {
    vertical-align: top;
}

Вроде бы всё здорово, но, сделав так, вы лишаетесь простого способа переопределить выравнивание для целого ряда:

tr.images {
    vertical-align: middle;
}

Этого можно избежать, воспользовавшись тем, что ячейки таблицы th и td наследуют правила от рядов tr, а те в свою очередь от блоков thead, tfoot и tbody.

thead {
    vertical-align: bottom;
}

tbody,
tfoot {
    vertical-align: top;
}

Стоит отметить, что все браузеры, кроме IE8, наследуют еще и значение text-align для th, а сам IE8 понимает ключевое слово inherit, что также позволяет наследовать значение text-align.

Заключение#

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