Автор иллюстрации SitePoint/Natalia Balska.
Итак, давайте посмотрим на подборку уже этого года дюжины малоизвестных фактов о CSS. Я уверен, что многим из вас известны, по крайней мере, некоторые из них, но вы можете дать мне знать в комментариях сколько из фактов оказались для вас новыми.
1. Оригинальная статья изобилует рабочими демонстрациями с CodePen. Хабр, к сожалению, не поддерживает вставки с подобных ресурсов, а заменять рабочие динамические примеры статичными картинками, думаю, не имеет смысла. Поэтому статья получилась немного «лысой» простыней, но, я надеюсь, заинтересованные читатели будут открывать недостающие примеры по ссылкам в новом окне.
2. Хотя я имею непосредственное отношение к верстке, перевод получился большим и не таким простым, как показался поначалу. Замечания по ошибкам, опечаткам, терминологии и т.п. просьба присылать личным сообщением в хабрапочту.
1. В свойстве border-radius
можно использовать «слэш» синтаксис
Об этом я уже писал на SitePoint больше четырех лет назад, но я думаю, что многие начинающие и даже некоторые опытные разработчики не знают о такой возможности.
Верьте или нет, но следующий код валидный:
.box {
border-radius: 35px 25px 30px 20px / 35px 25px 15px 30px;
}
Если вы никогда не видели подобного синтаксиса, он может показаться немного запутанным, поэтому приведу объяснение из спецификации:
Если значения указаны до и после слэша, то значения перед слэшем устанавливают горизонтальный радиус, а значения после слеша — вертикальный. Если слэш не используется — значения обоих радиусов (и горизонтального и вертикального) считаются одинаковыми.
В спецификации также приведена следующая схема:
В пояснении к картинке сказано: «Два значения border-top-left-radius: 55pt 25pt
определяют кривизну угла».
Таким образом, использование слэша в значениях свойства border-radius
позволяет создавать несимметрично изогнутые углы (прим. переводчика: скруглы). Если вы хотите более подробно разобраться в этом, прочтите мою статью (ссылка на которую выше приводилась), или лучше посмотрите удобную интерактивную демонстрацию от MDN.
Большинство border-radius
генераторов не позволяют использовать эти необязательные значения. Из тех, что я нашел, генератор от MDN единственный поддерживает «слэш» синтаксис.
2. Свойство font-weight
поддерживает ключевые слова относительности
Обычно, когда вы видите описание свойства
font-weight
, значение в нем либо normal
, либо bold
. Вы также могли видеть целые значения с инкрементом в сотню: 100
, 200
, и т.д. вплоть до 900
.
Однако, есть два значения, о которых часто забывают: bolder
и lighter
.
Согласно спецификации, эти ключевые слова делают шрифт жирнее или тоньше относительно наследуемого значения. Самое главное — это действует, когда вы имеете дело со шрифтом, в котором поддерживаются несколько степеней «жирности», где поддерживается начертания толще, чем обычный bold
, и тоньше, чем просто нормальный текст.
В синтаксисе, основанном на целых значениях, 700
означает bold
и 400
значит normal
. Итак, если ваш шрифт поддерживает толщину 300
, но не меньше, значение lighter
будет использовать толщину 300
, если наследуемая толщина шрифта 400
. Если же шрифт не поддерживает более тонкого начертания (т.е. значение по умолчанию 400
является самым тонким), то толщина так и останется 400
, и значение lighter
не произведет никакого эффекта на текст.
Посмотрите на следующий пример.
В этом примере я использую шрифт Exo 2, который поддерживает 18 разных начертаний. В моем демо не используются курсивные начертания, но шрифт их поддерживает для каждого значения от 100
до 900
.
Пример включает в себя 12 вложенных элементов «box» с различными значениями font-weight
, включая bolder
и lighter
, чтобы вы могли видеть как это влияет на «жирность» текста в разных случаях наследования. Ниже под спойлером приведен CSS из примера. Обратите внимание на комментарии в коде, и помните, что каждый следующий элемент «box» вложен в предыдущий:
.box {
font-weight: 100;
}
.box-2 {
font-weight: bolder; /* переключает на 400 */
}
.box-3 {
font-weight: bolder; /* переключает на 700 */
}
.box-4 {
font-weight: 400;
}
.box-5 {
font-weight: bolder; /* переключает на 700 */
}
.box-6 {
font-weight: bolder; /* переключает на 900 */
}
.box-7 {
font-weight: 700;
}
.box-8 {
font-weight: bolder; /* переключает на 900 */
}
.box-9 {
font-weight: bolder; /* переключает на 900 */
}
.box-10 {
font-weight: lighter; /* переключает на 700 */
}
.box-11 {
font-weight: lighter; /* переключает на 400 */
}
.box-12 {
font-weight: lighter; /* переключает на 100 */
}
В этом случае ключевые сова «bolder» и «lighter» устанавливают
font-weight
на значения 100
, 400
, 700
и 900
. С девятью разными стилями эти ключевые слова никогда не приведут к значениям 200
, 300
, 500
, 600
и 800
.
Так получается потому что вы говорите браузеру выбрать следующий шрифт в серии, который «жирнее» или «тоньше». Но браузер выбирает не просто следующий вариант жирнее или тоньше, а вариант начертания жирнее или толще относительно текущего. Однако, если самое тонкое начертание шрифта начинается со значения 300
(как у шрифта Open Sans), а значение по умолчанию 400
, то использование ключевого слова «lighter» установит font-weight
на значение 300
.
Это может показаться запутанным, но вы можете поиграться с примером, чтобы понять как работают эти ключевые слова.
3. Свойство outline-offset
Свойство
outline
хорошо известно благодаря своему удобству при отладке верстки (контур элемента никак не влияет на окружающие его элементы). В спецификации, однако, также добавлено свойство outline-offset
, которое осуществляет именно то, что следует из его названия — оно позволяет задать отступ контура от элемента.
В этом примере подвигайте слайдер вправо/влево, чтобы увидеть как это влияет на отступ контура от элемента. В данном случае отступ меняется от 0px
до 30px
, но в CSS вы можете задать любой отступ. Следует помнить, что хоть outline
и универсальное свойство (одновременно устанавливающее цвет, стиль и толщину внешней границы), оно не включает в себя outline-offset
. Поэтому при необходимости outline-offset
каждый раз нужно прописывать отдельно.
Единственный минус outline-offset
— он поддерживается всеми браузерами, кроме Internet Explorer (не поддерживает даже IE 11).
4. В CSS есть свойство table-layout
Вы, наверное, скажете: «Ха, старо как мир. Я знаю о
display:table
. Простейший способ вертикального центрирования». Но это не то, о чем я хочу рассказать. Заметьте, я сказал свойство table-layout
, а не display
.
Свойство table-layout
не самая простая CSS фича, чтобы объяснить как оно работает. Поэтому давайте заглянем в спецификацию, а потом рассмотрим пример. Спецификация гласит:
При этом (быстром) алгоритме горизонтальная разбивка таблицы не зависит от контента в ячейках; зависит только от ширины таблицы, ширины колонок и бордюров или расстояния между ячейками.
Это, похоже, первый раз, когда в W3C спецификации что-то трудно понять… Хах, прост шутканул (прим. переводчика: в оригинале «LOL JK»).
А если серьезно, как всегда нам поможет живой пример. В этом демо таблице в CSS добавлено table-layout: fixed
. Кликайте по кнопке, чтобы выключать/включать это свойство.
На этом примере вы можете видеть преимущество использования table-layout: fixed
над table-layout: auto
. Такой подход не всегда будет лучшим выбором и не всегда необходим, но не плохо бы о нем знать, когда речь идет о таблицах с клетками непостоянной ширины.
В прошлом году Крис Коер (Chris Coyier) написал отличную статью о table-layout
, поэтому если вы хотите больше узнать об этом свойстве — советую почитать.
5. Свойство vertical-align
в ячейках таблицы работает по-другому, нежели в других элементах
Если вы занимались созданием сайтов в середине 2000-х и раньше или часто верстаете HTML письма для email рассылок, вы, наверное, предполагаете, что CSS свойство
vertical-align
является аналогом старого HTML4 атрибута valign
, который в HTML5 уже не поддерживается.
Но CSS свойство vertical-align
работает не так-же, особенно с таблицами. Это, на мой взгляд, странновато, но все же лучше, чем если бы свойство вообще не работало в таблицах.
Так в чем же разница между применением свойства к обычным элементам и к ячейкам таблиц?
Если vertical-align
применяется не к ячейкам таблиц, то следует этим простым правилам:
- работает только с
inline
иinline-block
элементами; - не влияет на соседние элементы в контенте, но влияет на выравнивание элемента относительно соседних
inline
иinline-block
элементов; - на свойство влияют настройки шрифта, такие как
line-height
, и размер соседнихinline
иinline-block
элементов.
В этом примере свойство
vertical-align
присвоено элементу input
. Нажимая на кнопки вы можете устанавливать свойству значения, написанные на кнопках. Обратите внимание, как каждое значение меняет позицию элемента input
.
В целом, это довольно простенькая демонстрация работы свойства. Для более глубокого анализа прочтите прошлогоднюю статью Кристофера Оуе (Christopher Aue).
Когда дело доходит до таблиц, vertical-align
работает совсем по-другому. В этом случае вы применяете свойство к одной и более ячейкам, и выравнивание контента ячеек зависит от выбранного значения. Пример на CodePen.
Как показано в примере, только 4 значения свойства vertical-align
применимы к ячейкам таблиц. Кроме того, значение baseline
влияет не только на ячейку, к которой проставляется, но и на соседние ячейки в строке таблицы.
6. Псевдоэлемент ::first-letter
умнее, чем вы думали
Псевдоэлемент
::first-letter
позволяет стилизовать первую букву любого элемента и дает возможность реализовать эффект буквицы (прим. переводчика: позволил себе сослаться на русскоязычную страницу wiki), который был распространен в печати в течение многих лет.
Хорошая новость в том, что, похоже, браузеры имеют одинаковое представление о «первой букве» элемента. Впервые я прочел об этом в твите Мэта Эндрюса (Matt Andrews), хотя, такое поведение браузеров ему явно не понравилось. Вы можете посмотреть его пример на CodePen.
Мне кажется, что большая четверка браузеров работает с этим свойством одинаково, и это круто, так как я считаю, что это правильное поведение. Было бы немного странно, если бы открывающая скобка считалась первой буквой. В таком случае это было бы похоже на «first character» (первый символ), который мог бы стать самостоятельным псевдоклассом.
7. В HTML вы можете использовать недопустимые символы в качестве разделителя в списке классов элемента
Этот подход обсуждался в 2013 году Бэном Эвардом (Ben Everard), и, я думаю, стоит подробнее рассмотреть эту тему.
В публикации Бэна говорилось об использовании символа слэша ("/") для разделения в HTML списков классов на группы, чтобы сделать код легче для прочтения и понимания. Автор указывает на то, что хотя слеш является недопустимым символом, браузеры не споткнутся на нем, а просто его проигнорируют.
Предположим, у вас такой HTML:
<div class="col col-4 col-8 c-list bx bx--rounded bx--transparent">
Со слешами он будет выглядеть так:
<div class="col col-4 col-8 / c-list / bx bx--rounded bx--transparent">
В качестве разделителей вы можете использовать любые символы (и допустимые, и недопустимые):
<div class="col col-4 col-8 ** c-list ** bx bx--rounded bx--transparent">
<div class="col col-4 col-8 || c-list || bx bx--rounded bx--transparent">
<div class="col col-4 col-8 && c-list && bx bx--rounded bx--transparent">
Все подобные конструкции отлично работают, можете протестировать на этом демо.
Конечно, эти разделители не могут быть использованы в качестве классов, поэтому я называю их «недопустимыми». Следующий код будет нерабочим и не применит стили к элементу:
./ {
color: blue;
}
Если вы хотите использовать подобные символы в именах классов, сохраняя их работоспособность, вы можете экранировать их, воспользовавшись этим инструментом. Предыдущий пример будет работать, только если CSS будет выглядеть так:
.\/ {
color: blue;
}
Углубляясь в подробности скажу, что символы юникода не нужно экранировать, поэтому вы можете использовать подобные безумные конструкции:
<div class="♥ ★"></div>
С таким CSS:
.♥ {
color: hotpink;
}
.★ {
color: yellow;
}
Есть так же возможность экранировать и символы данного типа, вместо их непосредственной вставки. Следующий код эквивалентен предыдущему:
.\2665 {
color: hotpink;
}
.\2605 {
color: yellow;
}
8. Количество повторов анимации может принимать дробные значения
Вероятно вы в курсе, что при использовании keyframe-анимаций вы можете использовать свойство
animation-iteration-count
, чтобы установить количество повторов анимации:
.example {
animation-iteration-count: 3;
}
Целое значение в данном случае говорит о том, что анимацию нужно повторить 3 раза. Но, возможно, вы не в курсе, что можно устанавливать и дробные значения:
.example {
animation-iteration-count: .5;
}
В данном случае будет запущена только половина анимации (она остановится на половине первой итерации). Давайте посмотрим на пример, в котором анимируются два шарика. У верхнего шарика счетчик повторов установлен на «1», у нижнего на «0.5».
Что интересно, счетчик повторов не зависит от свойства/значения, которые анимируются. Другими словами, если вы анимируете какие-то 100 пикселей, это не значит, что на половине повтора анимация остановится на 50 пикселях. Предыдущий пример использует тайминг-функцию linear
, что гарантирует остановку второго мячика на половине пути.
Вот еще две анимации, но тут уже используется тайминг-функция ease
: пример. Обратите внимание, что сейчас второй мячик также прошел до остановки половину анимации. Повторю, так получается из-за различных тайминг-функций.
Если вы понимаете тайминг-функции, вы поймете, почему при ease-in-out
мячик остановится в той-же позиции, что и при linear
. Поиграйтесь с различными дробными значениями и тайминг-функциями чтобы увидеть, как это влияет на результат.
9. Animation
может не работать из-за имени анимации
Некоторые разработчики обнаружили это случайно на своем опыте, хотя в спецификации на этот счет есть предупреждение. Предположим, у вас есть следующий код анимации:
@keyframes reverse {
from {
left: 0;
}
to {
left: 300px;
}
}
.example {
animation: reverse 2s 1s;
}
Заметьте, для анимации я использую имя
reverse
. На первый взгляд код выглядит рабочим, но обратите внимание что произойдет, если мы используем его на живом примере.
Анимация не работает, так как «reverse» — это зарезервированное ключевое слово для свойства animation-direction
. Это произойдет с любой анимацией, имя которой совпадает с зарезервированными ключевыми словами, используемыми в универсальном (кратком) способе записи. При подробной форме записи, с раздельным указанием animation-name
и других параметров, анимация будет работать.
Имена анимации, которые могут сломать краткую форму записи, включают в себя имена тайминг-функций, таких как infinite
, alternate
, running
, paused
и т.д.
10. Вы можете выбирать диапазон элементов
Не знаю кто первый использовал эту возможность, но я впервые узнал о ней из этого примера от Гуннара Битерсманна (Gunnar Bittersmann). Скажем, у вас есть нумерованный список из 20 элементов и вы хотите выделить элементы с 7 по 14 включительно. Вот как это можно сделать одним селектором:
ol li:nth-child(n+7):nth-child(-n+14) {
background: lightpink;
}
Посмотрите демо работы селектора.
Дополнение: Как отметили в комментариях, в Safari есть баг, из-за которого эта техника не работает. К счастью, решение, предложенное Мэтом Помаски (Matt Pomaski), похоже работает: просто разверните цепочку псевдоклассов, чтобы получился такой селектор ol li:nth-child(-n+14):nth-child(n+7)
. В ночных сборках WebKit такого бага нет, поэтому со временем и в Safari подобная конструкция будет работать нормально.
Этот код использует связку псевдоклассов с выражениями. Хотя выражения могут показаться запутанными, вы можете видеть выделяемый диапазон элементов в числах, использованных в этих выражениях.
Как это работает: В первой части связки выражение говорит «выбрать 7-ой элемент и каждый после него». Во второй части говорится «выбрать 14-ый элемент и каждый до него». Но так как селекторы в связке — каждый ограничивает область выборки другого. Так вторая часть связки не дает первой выбраться за пределы 14-ого элемента, а первая часть не дает второй опуститься в выборке ниже 7-ого элемента.
Для более детального изучения этих типов селекторов и выражений вы можете прочитать мой старый пост на эту тему.
11. Псевдоэлементы могут быть применены к некоторым одиночным тегам
Возможно вы, как и я, в какой-то момент пытались применить псевдоэлементы к изображениям или элементам форм. Этого сделать не получится, потому что псевдоэлементы не работают с заменяемыми элементами. Я думаю, многие разработчики предполагают, что это касается всех одиночных тегов (не имеющих закрывающего тега). Но это не так.
Вы можете применить псевдоэлементы к некоторым одиночным тегам, которые не являются заменяемыми элементами. Это касается и элемента hr
, как видно из этого примера.
Закрашенная область в этом примере — это горизонтальный очерк (элемент hr
), и к нему применены оба псевдоэлемента ::before
и ::after
. Интересно, но мне не удалось получить тот-же результат с br
, хотя он и является незаменяемым однотеговым элементом.
Вы также можете добавить псевдоэлементы к элементам meta
и link
, если вы достаточно ненормальны, чтобы сделать их блоковыми display: block
, как показано в следующем примере.
12. Некоторые значения в селекторах атрибутов регистронезависимы
В завершение рассмотрим одну небольшую неясность. Предположим, у вас следующий HTML:
<div class="box"></div>
<input type="email">
Вы можете применить стили к каждому из этих элементов, используя селекторы атрибутов, как тут:
div[class="box"] {
color: blue;
}
input[type="email"] {
border: solid 1px red;
}
Такие стили сработают нормально. А что если сделать так?
div[class="BOX"] {
color: blue;
}
input[type="EMAIL"] {
border: solid 1px red;
}
Обратите внимание, что значения атрибутов указаны теперь в верхнем регистре. В этом случае к элементу
.box
стили не будут применены, так как атрибут class
является регистрозависимым. С другой стороны, к полю email стили применятся, потому что значения атрибута type
не чувствительны к регистру. Тут нет никакого открытия, но, возможно, вы не знали об этом.
Народ, пора закругляться
В этот момент опускается занавес, и надеюсь-не-слишком-дрянной сиквел заканчивается.
Чувствуется, что каждую неделю я натыкаюсь на небольшие CSS интересности и изучаю их, и, я надеюсь, что что-то из описанного выше оказалось познавательным для большинства из вас. Какие у вас любимые малоизвестные CSS трюки или техника? Знаете ли вы свойства или возможности CSS, которые вы считаете малоизвестными, но хорошо поддерживаемыми браузерами? Поделитесь ими в комментариях.
This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.
Комментариев нет:
Отправить комментарий