12 малоизвестных возможностей CSS

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

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

 не только текст красит

Начнем, пожалуй, с простых вещей. Свойство color используется разработчиками постоянно. Те из вас, у кого не так много опыта работы с CSS, возможно, и не знали, что это свойство определяет не только цвет текста!4dbac04fa083210b1aba9946c94ba88a
HTML

<img alt="Example alt text" width="200" height="200">

<ul>
  <li>Example list item</li>
</ul>

<ol>
  <li>Example list item</li>
</ol>

<hr>

CSS

body {
  color: yellow;
  background: #444;
  font-size: 20px;
  font-family: Arial, sans-serif;
  text-align: center;
}

ul {
  border: solid 2px;
  text-align: left;
}

ol {
  text-align: left;
}

hr {
  border-color: inherit;
}

Обратите внимание, что в CSS свойство color:yellow используется лишь раз применительно к элементу body. Как видите, всё окрасилось в желтый цвет:

  • Альтернативный текст на месте отсутствующего изображения
  • Рамка у элементов списка
  • Маркер ненумерованного списка
  • Номер упорядоченного списка
  • Элемент hr

Интересно, что по умолчанию элемент hr не наследует значение свойства color, однако этого можно достичь, установив свойству border-color значение inherit. Как по мне, так это несколько странное поведение. Продемонстрированное подтверждается спецификацией:

Данное свойство описывает цвет переднего плана текстового содержимого элемента. В дополнение к этому оно может косвенно использоваться другими свойствами, которые принимают значения цвета.

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

Свойство visibility может иметь значение collapse

Вам наверняка доводилось использовать свойство visibility, и не раз. «Обычные» значения — visible (по умолчанию у всех элементов) и hidden, которое скрывает элемент, оставляя при этом под него место (в отличие от display:none).
Третье, редко используемое значение — collapse. Работает так же, как и hidden применительно ко всем элементам, кроме табличных рядов, колонок и их групп. В случае с элементами таблиц предполагается, что значение collapse скроет их подобно display:none таким образом, что на ранее занимаемом ими месте расположится другое содержимое таблицы.
33b2fb0d5fe6e40589f88e57fc9a38ea
Ожидаемое поведение
К сожалению, не все браузеры одинаково обрабатывают данное значение. По этой причине альманах CSS-Tricks вообще не рекомендует использовать данное свойство. Попробуйте демо.
Из того, что обнаружил я:

  • В Хроме разницы между collapse и hidden не наблюдается (посмотрите этот баг репорт и комментарии)
  • В Файрфоксе, Опере и ИЕ 11 collapse, похоже, работает как следует: ряд таблицы удаляется, а тот, что был ниже, поднимается наверх

Теперь вы знаете чуточку больше, тем не менее из-за разного поведения браузеров использовать visibility:collapse вряд ли имеет смысл.

Новые значения свойства background

В CSS 2.1 короткая запись свойства background включала в себя пять значений следующих свойств: background-color, background-image, background-repeat, background-attachment и background-position. Начиная с CSS 3 добавилось еще три значения, так что данное свойство теперь выглядит так:

background: [background-color] [background-image] [background-repeat] [background-attachment] [background-position] / [background-size] [background-origin] [background-clip]

Обратите внимание на слеш, который ставится там подобно короткой записи свойства font и border-radius [ссылка]. Этот слеш позволит вам включить значение background-size после background-position в тех браузерах, которые это поддерживают. Также вы можете добавить еще два значения: background-origin и background-clip. Итоговый синтаксис:

.example {
     background: aquamarine url(img.png)
              no-repeat
              scroll
              center center / 50%
              content-box content-box;
}

Попробовать можно здесь
Новые значения работают во всех современных браузерах, однако и про старичков забывать не стоит, предлагая адекватную замену.

Свойство clip работает только на абсолютно спозиционированных элементах

Наверняка вы в курсе свойства clip. Используется оно так:

.example {
    clip: rect(110px, 160px, 170px, 60px);
}

Данное правило «обрежет» элемент с четырех сторон на указанное количество пикселей. Единственный нюанс состоит в том, что элемент, к которому вы применяете данное свойство, должен быть спозиционирован абсолютно.

.example {
    position: absolute;
    clip: rect(110px, 160px, 170px, 60px);
}

А теперь посмотрите, как свойство clip перестает работать, если мы уберем абсолютное позиционирование элемента. Помимо position:absolute вы также можете использовать position:fixed, поскольку, согласно документации, зафиксированные элементы также квалифицируются как «абсолютно спозиционированные».

Вертикальные проценты рассчитываются относительно ширины контейнера, а не его высоты

По началу это трудно понять, и я об этом писал. Возможно, вы знаете, что длины элементов, указанные в процентах, рассчитываются, исходя из длины их контейнера. Так вот, верхние и нижние внутренние отступы (padding) и те же внешние (margin) тоже рассчитываются исходя из ширины контейнера, а не его высоты. Посмотрите демо
Заметьте, что вложенный элемент имеет три отступа, заданных в процентах (верхний и нижний внутренние отступы и нижний внешний отступ). Слайдер изменяет только ширину контейнера. Однако её изменение влияет на просчет отступов. Зависимость именно от ширины контейнера показана в выводе величин на страницу.

Свойство border

Все мы когда-либо делали это:

.example {
  border: 1px solid black;
}

Свойство border объединяет значения свойств border-width, border-style и border-color в единую конструкцию. Но не забывайте, что каждое из свойств, значение которых содержит border, само по себе является сокращенной записью. Так, например, border-width может быть записано следующим образом:

.example {
  border-width: 2px 5px 1px 0;
}

Таким образом мы установим разную ширину рамки для всех четырех сторон элемента. То же относится и к свойствам border-style и border-color. Нечто вот такое ужасное можно получить:

HTML
<div class="box"></div>
<p>Please don't ever do this.</p>

CSS

body {
  font-family: Arial, sans-serif;
}

.box {
  width: 150px;
  height: 150px;
  margin: 20px auto;
  border-color: peachpuff chartreuse thistle firebrick;
  border-style: solid dashed dotted double;
  border-width: 10px 3px 1px 8px;
}

p {
  text-align: center;
}

Можно пойти еще дальше и задать эти значения по отдельности с помощью свойств border-left-style, border-top-width, border-bottom-color и так далее.
Фишка в том, что с помощью border вы не сможете задать разные значения для разных сторон. Таким образом, получается нечто вроде сокращенной записи внутри сокращенной записи внутри сокращенной записи.

Свойство text-decoration — теперь сокращенная запись

Я знал: что-нибудь из этого списка обязательно вскружит вам голову. А спецификация гласит, что теперь это стандарт.

a {
  text-decoration: overline aqua wavy;
}

Данное свойство теперь может содержать в себе значения трех свойств: text-decoration-line, text-decoration-color и text-decoration-style. К сожалению, Файрфокс — единственный браузер, который поддерживает новые свойства, но при этом (видимо, для обеспечения обратной совместимости) не поддерживает сокращенный синтаксис.

Ожидаемый результат
Попробуйте эту демку в Файрфоксе. В ней новые свойства используются по отдельности. С ними надо быть аккуратнее, ибо в данное время браузеры не смогут распарсить дополнительные значения у свойства text-decoration и просто пропустят его. А это нехорошо с точки зрения обратной совместимости.

Свойство border-width поддерживает ключевые значения

Это, конечно, не нечто из ряда вон выходящее, да и не ново, тем не менее помимо обычных значений ширины (напр., 5px или 1em) border-width поддерживает три ключевых значения: medium, thin и thick.
По факту, начальное значение свойства border-width — medium. Ниже продемонстрировано значение thick:

В спецификации CSS конкретная ширина для ключевых значений не прописана, однако все браузеры используют 1px, 3px и 5px соответственно.

«Никто не использует border-image»

Не так давно я писал о свойстве border-image на SitePoint. Оно поддерживается всеми современными браузерами, за исключением IE 10 и ниже. Но кому какая разница? border-image — весьма забавное свойство, которое позволяет обрамлять контейнер неким изображением.

Также посмотрите демо.
К сожалению, border-image — одна из новинок, пользующаяся недостаточной популярностью. Хотя, возможно, я не прав. Если у вас есть примеры использования border-image — добро пожаловать в комментарии!

Есть такое свойство empty-cells

И оно поддерживается всеми браузерами, включая IE 8:

table {
  empty-cells: hide;
}

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

Свойство font-style поддерживает значение oblique

Наиболее используемые значения данного свойства — normal и italic. Но есть еще и oblique.

И что же это значит? Почему текст выглядит так же, как италик? Спецификация объясняет данное поведение следующим образом:

… выбирает шрифт, помеченный как наклонная гарнитура, иначе — италик.

Описание италика в спецификации — примерно о том же. Термин «наклонный» (oblique) — из типографики, обозначает, собственно, наклоненный текст, но не настоящий италик.

CSS обрабатывает наклонный текст таким образом, что значение oblique взаимозаменяемо с italic (так говорится в спецификации) до тех пор, пока используемый шрифт не имеет отдельной наклонной гарнитуры. Не знаю шрифтов, которые бы имели наклонную гарнитуру, но я могу ошибаться. (Ошибается. Сам привести конкретных названий шрифтов не могу (они однозначно существуют), но в комментариях к оригинальной статье в пример приводят шрифт Helvetica, который имеет наклонную гарнитуру. — прим. переводчика)

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

word-wrap — то же, что и overflow-wrap

Свойство word-wrap используется не так часто, однако в некоторых случаях может оказаться полезным. Очень распространенный пример — разбиение длинной непрерывной строки текста во избежание выхода за пределы контейнера. Поскольку данное свойство придумали в Microsoft, оно поддерживается всеми браузерами, в том числе IE с версии 5.5.
Несмотря на кросс-браузерность и надлежащую поддержку, W3C решило заменить свойство word-wrap на overflow-wrap: по всей видимости, они посчитали прежнее название неправильным. 
overflow-wrap имеет те же значения, что и word-wrap, а последнее сейчас рассматривается как «альтернативное».

Несмотря на то, что поддержка overflow-wrap еще мало распространена, не стоит переживать, ибо мы все так же можем использовать word-wrap: браузеры его поддерживают в том числе и в целях обратной совместимости.
Что до overflow-wrap — там уж когда все популярные браузеры обновятся, а пока я не вижу смысла что-то менять.

Много ли нового узнали вы из всего этого?

Хоть что-нибудь — уже хорошо. Наверняка крутые ребята знают большую часть, если не всё из вышеперечисленного. Но менее продвинутым разработчикам это узнать весьма полезно.