CSS (селекторы, свойства, единицы измерения)
О чём пойдёт речь
Неужели мы сейчас будем учить CSS? Ничего подобного. Предполагается, что вы уже знаете CSS, во всяком случае понимаете его на таком уровне, который позволяет делать Web-страницы.
Особенность квалификации JavaScript-разработчика заключается в том, что он не обязан выбирать цвета, рисовать иконки, «делать красиво». Он также не обязан верстать макет в HTML, разве что если является по совместительству специалистом-верстальщиком.
Вот что он должен уметь абсолютно точно – так это и разработать такую структуру HTML/CSS для элементов управления, которая не сломается, и с которой ему же потом удобно будет взаимодействовать.
Это требует отличного знания CSS в области позиционирования элементов, включая тонкости работы display
, margin
, border
, outline
, position
, float
, border-box
и остальных свойств, а также подходы к построению структуры компонент (CSS layouts).
Многое можно сделать при помощи JavaScript. И зачастую, не зная CSS, так и делают. Но мы на это ловиться не будем.
Если что-то можно сделать через CSS – лучше делать это через CSS.
Причина проста – обычно, даже если CSS на вид сложнее – поддерживать и развивать его проще, чем JS. Поэтому овчинка стоит выделки.
Кроме того, есть ещё одно наблюдение.
Знание JavaScript не может заменить знание CSS.
Жить становится приятнее и проще, если есть хорошее знание и CSS, и JavaScript.
Чек-лист
Ниже находится «чек-лист». Если хоть одно свойство незнакомо – это стоп-сигнал для дальнейшего чтения этого раздела.
- Блочная модель, включая:
- Текст:
- Различные курсоры
cursor
. - Позиционирование:
position
,float
,clear
,display
,visibility
- Центрирование при помощи CSS
- Перекрытие
z-index
и прозрачностьopacity
- Селекторы:
- Сброс браузерных стилей, reset.css
Почитать
Книжек много, но хороших – как всегда, мало.
С уверенностью могу рекомендовать следующие:
- Большая книга CSS3. Дэвид Макфарланд.
- CSS. Каскадные таблицы стилей. Подробное руководство. Эрик Мейер
- Отладка CSS Ахмад Шадид
Дальнейшие статьи раздела не являются учебником CSS, поэтому пожалуйста, изучите эту технологию до них.
Это очерки для лучшей систематизации и дополнения уже существующих знаний.
Единицы измерения: px, em, rem и другие
В этом очерке я постараюсь не только рассказать о различных единицах измерения, но и построить общую картину – что и когда выбирать.
Пиксели: px
Пиксель px
– это самая базовая, абсолютная и окончательная единица измерения.
Количество пикселей задаётся в настройках разрешения экрана, один px
– это как раз один такой пиксель на экране. Все значения браузер в итоге пересчитает в пиксели.
Пиксели могут быть дробными, например размер можно задать в 16.5px
. Это совершенно нормально, браузер сам использует дробные пиксели для внутренних вычислений. К примеру, есть элемент шириной в 100px
, его нужно разделить на три части – волей-неволей появляются 33.333...px
. При окончательном отображении дробные пиксели, конечно же, округляются и становятся целыми.
Для мобильных устройств, у которых много пикселей на экране, но сам экран маленький, чтобы обеспечить читаемость, браузер автоматически применяет масштабирование.
Относительно шрифта: em
Можно брать любые пропорции от текущего шрифта: 2em
, 0.5em
и т.п.
Размеры в em
– относительные, они определяются по текущему контексту.
Например, давайте сравним px
с em
на таком примере:
24
пикселей – и в Африке 24
пикселей, поэтому размер шрифта в <div>
одинаков.
А вот аналогичный пример с em
вместо px
:
Так как значение в em
высчитывается относительно текущего шрифта, то вложенная строка в 1.5
раза больше, чем первая.
Выходит, размеры, заданные в em
, будут уменьшаться или увеличиваться вместе со шрифтом. С учётом того, что размер шрифта обычно определяется в родителе, и может быть изменён ровно в одном месте, это бывает очень удобно.
Что такое «размер шрифта»? Это вовсе не «размер самой большой буквы в нём», как можно было бы подумать.
Размер шрифта – это некоторая «условная единица», которая встроена в шрифт.
Она обычно чуть больше, чем расстояние от верха самой большой буквы до низа самой маленькой. То есть, предполагается, что в эту высоту помещается любая буква или их сочетание. Но при этом «хвосты» букв, таких как р
, g
могут заходить за это значение, то есть вылезать снизу. Поэтому обычно высоту строки делают чуть больше, чем размер шрифта.
В спецификации указаны также единицы ex и ch, которые означают размер символа "x"
и размер символа "0"
.
Эти размеры присутствуют в шрифте всегда, даже если по коду этих символов в шрифте находятся другие значения, а не именно буква "x"
и ноль "0"
. В этом случае они носят более условный характер.
Эти единицы используются чрезвычайно редко, так как «размер шрифта» em
обычно вполне подходит.
Проценты %
Проценты %
, как и em
– относительные единицы.
Когда мы говорим «процент», то возникает вопрос – «Процент от чего?»
Как правило, процент будет от значения свойства родителя с тем же названием, но не всегда.
Это очень важная особенность процентов, про которую, увы, часто забывают.
Отличный источник информации по этой теме – стандарт, Visual formatting model details.
Вот пример с %
, он выглядит в точности так же, как с em
:
В примере выше процент берётся от размера шрифта родителя.
А вот примеры-исключения, в которых %
берётся не так:
При установке свойства margin-left
в %
, процент берётся от ширины родительского блока, а вовсе не от его margin-left
.
При установке свойства line-height
в %
, процент берётся от текущего размера шрифта, а вовсе не от line-height
родителя. Детали по line-height
и размеру шрифта вы также можете найти в статье Свойства font-size и line-height.
Для width/height
обычно процент от ширины/высоты родителя, но при position:fixed
, процент берётся от ширины/высоты окна (а не родителя и не документа). Кроме того, иногда %
требует соблюдения дополнительных условий, за примером – обратитесь к главе Особенности свойства height в %.
Единица rem: смесь px и em
px
– абсолютные, чёткие, понятные, не зависящие ни от чего.em
– относительно размера шрифта.%
– относительно такого же свойства родителя (а может и не родителя, а может и не такого же – см. примеры выше).
Может быть, пора уже остановиться, может этого достаточно?
Э-э, нет! Не все вещи делаются удобно.
Вернёмся к теме шрифтов. Бывают задачи, когда мы хотим сделать на странице большие кнопки «Шрифт больше» и «Шрифт меньше». При нажатии на них будет срабатывать JavaScript, который будет увеличивать или уменьшать шрифт.
Вообще-то это можно сделать без JavaScript, в браузере обычно есть горячие клавиши для масштабирования вроде Ctrl++, но они работают слишком тупо – берут и увеличивают всю страницу, вместе с изображениями и другими элементами, которые масштабировать как раз не надо. А если надо увеличить только шрифт, потому что посетитель хочет комфортнее читать?
Какую единицу использовать для задания шрифтов? Наверно не px
, ведь значения в px
абсолютны, если менять, то во всех стилевых правилах. Вполне возможна ситуация, когда мы в одном правиле размер поменяли, а другое забыли.
Разницы между ними здесь нет, так как при задании font-size
в процентах, эти проценты берутся от font-size
родителя, то есть ведут себя так же, как и em
.
Вроде бы, использовать можно, однако есть проблема.
Попробуем использовать этот подход для <li>
.
Пока это обычный вложенный список.
Теперь уменьшим размер шрифта до 0.8em
, вот что получится:
Проблема очевидна. Хотели, как лучше, а получилось… Мелковато. Каждый вложенный <li>
получил размер шрифта 0.8
от родителя, в итоге уменьшившись до нечитаемого состояния. Это не совсем то, чего мы бы здесь хотели.
Можно уменьшить размер шрифта только на одном «корневом элементе»… Или воспользоваться единицей rem
, которая, можно сказать, специально придумана для таких случаев!
Единица rem
задаёт размер относительно размера шрифта элемента <html>
.
Как правило, браузеры ставят этому элементу некоторый «разумный» (reasonable) размер по умолчанию, который мы, конечно, можем переопределить и использовать rem
для задания шрифтов внутри относительно него:
Получилось удобное масштабирование для шрифтов, не влияющее на другие элементы.
Элементы, размер которых задан в rem
, не зависят друг от друга и от контекста – и этим похожи на px
, а с другой стороны они все заданы относительно размера шрифта <html>
.
Единица rem
не поддерживается в IE8-.
Относительно экрана: vw, vh, vmin, vmax
Во всех современных браузерах, исключая IE8-, поддерживаются новые единицы из черновика стандарта CSS Values and Units 3:
vw
– 1% ширины окнаvh
– 1% высоты окнаvmin
– наименьшее из (vw
,vh
), в IE9 обозначаетсяvm
vmax
– наибольшее из (vw
,vh
)
Эти значения были созданы, в первую очередь, для поддержки мобильных устройств.
Их основное преимущество – в том, что любые размеры, которые в них заданы, автоматически масштабируются при изменении размеров окна.
Этот текст написан с размером `5vh`.
Вы сможете легко увидеть, как работает vh
, если поменяете высоту окна браузера. Текст выше будет расти/уменьшаться.
Итого
Мы рассмотрели единицы измерения:
px
– абсолютные пиксели, к которым привязаны и потому не нужныmm
,cm
,pt
иpc
. Используется для максимально конкретного и точного задания размеров.em
– задаёт размер относительно шрифта родителя, можно относительно конкретных символов:"x"
(ex
) и"0"
(ch
), используется там, где нужно упростить масштабирование компоненты.rem
– задаёт размер относительно шрифта<html>
, используется для удобства глобального масштабирования: элементы которые планируется масштабировать, задаются вrem
, а JS меняет шрифт у<html>
.%
– относительно такого же свойства родителя (как правило, но не всегда), используется для ширин, высот и так далее, без него никуда, но надо знать, относительно чего он считает проценты.vw
,vh
,vmin
,vmax
– относительно размера экрана.