|
|||||||
Странности CSS, о которых полезно знать
Время создания: 26.04.2018 09:49
Автор: https://habr.com/users/ru_vds/
Текстовые метки: css tricks
Раздел: CSS
Запись: Velonski/mytetra-database/master/base/15247181804zr5342wf1/text.html на raw.githubusercontent.com
|
|||||||
|
|||||||
В наших публикациях регулярно появляются статьи о CSS. Среди них — материал об истории CSS, рассказ о подборе имён для CSS-сущностей, статья о CSS-стилях для печати, о которых многие забывают. Мы писали о том, как работают CSS-селекторы, сравнивая происходящее с автосалоном, о сравнительно новой технологии CSS Grid Layout, и о том, что CSS — это не чёрная магия. Сегодня предлагаем вашему вниманию перевод материала, который посвящён странностям CSS, о которых, как полагает автор этого материала, мало кто знает. image Вертикальные поля Что станет с элементом, если назначить ему свойство padding-top: 50%? Интуитивно понятно, что подобное свойство устанавливает размер поля от верхнего края содержимого элемента, размер которого составляет 50%… От чего берутся эти 50%? Собственно говоря, в определённый момент интуиция при разборе особенностей этого свойства оказывается бесполезной. Дело в том, что эти вот 50% берутся от ширины родительского элемента того элемента, которому назначают верхнее поле. Вот пример, подготовленный средствами CodePen. Такие примеры вы найдёте и во многих других разделах этого материала. Вышесказанное справедливо и для нижнего поля, задаваемого свойством padding-bottom. Знание этой особенности, в частности, позволяет создавать отзывчивые элементы, сохраняющие соотношение сторон: .square { width: 100%; height: 0; padding-bottom: 100%; } О непостоянном схлопывании отступов Расстояние между следующими элементами будет 20px, а не 40px: <div style="margin-bottom:20px">foo</div> <div style="margin-top:20px">foo</div> → Пример Однако так бывает не всегда. Отступы не схлопываются при работе со следующими элементами: Плавающие элементы. Абсолютно позиционированные элементы. Строчно-блочные (inline-block) элементы. Элементы с параметром overflow, установленным в любое значение кроме visible (они не схлопывают отступы со своими элементами-потомками). Элементы, к которым применено правило clear (их верхние отступы не схлопываются с нижними отступами их родительских блоков). Корневой элемент дерева документа. Уровень прозрачности и порядок наложения элементов Предположим, что имеются три элемента <div>, каждый из них позиционирован абсолютно. Они содержат другие элементы, которым назначено свойство z-index со значениями от 1 до 3. Каждый следующий такой элемент выводится поверх предыдущего. Если теперь назначить z-index: 10 самому нижнему элементу, он будет выведен поверх двух других, порядок расположения которых не изменится. Пока всё выглядит так, как и ожидается. Если теперь назначить первому элементу <div>, тому, который теперь находится выше других, свойство opacity: 0.99, то он окажется под двумя другими. → Пример Подробности о том, почему это происходит, можно найти здесь. Кастомные свойства и переменные CSS Используя SASS или LESS, можно решить, что кастомные свойства и переменные CSS эквивалентны возможностям, доступным в этих препроцессорах. Однако, тут имеются несколько отличий, на которые стоит обратить внимание. Сначала рассмотрим основы: // задавать и использовать кастомные свойства можно так :root { --foo: #000; } button { background-color: var(--foo); //чёрный фон } Кастомные свойства, кроме того, наследуемы, то есть, если переназначить локальную переменную, это подействует на все элементы-потомки, и, в отличие от препроцессора, браузер, когда подобное происходит, пересчитывает все выражения, где применяются такие переменные. При применении кастомных свойств резервные значения можно перечислить через запятую. В список резервных значений могут входить и другие переменные. .foo { color: var(—-my-var, 'blue'); } Это приводит нас к основной разнице с препроцессорами: переменные CSS знают о структуре DOM и об изменениях, которые там происходят. ::root { --default-color: #000000; } header { --primary-color: #ff0000; } a { color: var(--primary-color, --default-color); } <a href="">this is black</a> <header> <a href="">this is red.</a> </header> В отличие от первого примера, демонстрирующего наследование, этот пример полагается на резервные значения, на которые влияет то, было ли задано кастомное свойство в родительском элементе DOM или нет. → Пример Более того, их легко можно менять, используя средства JavaScript: // получить переменную из inline-стиля element.style.getPropertyValue("--my-var"); // установить переменную в inline-стиле element.style.setProperty("--my-var", jsVar + 4); Эта возможность поддерживается начиная с Edge 15. Конструкция vertical align: top | middle | bottom Конструкция vertical align: top | middle | bottom работает только для inline-элементов (в том числе и для inline-block) и элементов table-cell. Этот способ не подходит для выравнивания элементов внутри их родительских элементов. Для этого нужно использовать средства flexbox-вёрстки, или то, что известно как «douchebag vertical align» (ниже мы об этом поговорим). Свойство height: 100% может не давать ожидаемого эффекта То, о чём мы говорили в предыдущем разделе, справедливо и для свойства height: 100%. Во многих случаях установка этого свойства не приводит к тому, чего ожидает разработчик. Причина подобного кроется в том, что не задана высота родительского элемента. Рассмотрим пример: <html> <body> <div style="height:100%;background:red;"></div> </body> </html> Показанный здесь элемент <div> не закрасит всю страницу в красный цвет. Для того чтобы этого добиться, нужно установить свойство height в 100% и для элемента <body>, и для элемента <html>. Стили идентификаторов и стили классов Стили идентификаторов переопределяют стили, заданные на уровне классов. Происходит это из-за того, что id-селекторы точнее, чем селекторы классов. Так, например, правило, заданное для .foo.bar переопределит правила, заданные отдельно для .foo и для .bar. #foo { color: red; } .bar { color: green; } <h1 id="foo" class="bar">this will be red not green</h1> Выбор элементов с определённым атрибутом Средствами CSS можно выбирать элементы на основе конкретных атрибутов и их содержимого. Например, это может быть содержимое атрибутов src или href. // выбираем все ссылки на zip-файлы (нечувствительно к регистру) a[href$=".zip" i] { } // сделаем красными ссылки на google.com [href*="google.com"] { color: red; } Этот приём может оказаться полезным при отладке, например, для выделения всех элементов img с пустым атрибутом alt: img:not([alt]) { border: 2px dashed red; } img[alt=""] { border: 2px dashed red; } Если вы используете Angular, этот подход, кроме того, может быть полезен для выбора элементов, которые содержат [ng-click]. Или, если надо, так можно визуально разделить ссылки на локальные ресурсы, и ссылки, которые начинаются с http или https. → Пример О порядке следования свойств при указании значений параметров по горизонтали и вертикали Когда задают некие значения, имеющие отношения к горизонтальной и вертикальной осям, первое число обычно задаёт вертикальное значение, а второе — горизонтальное. Например, в выражении padding: 10px 20px; 10px — это верхнее и нижнее поле, 20px — это правое и левое поле. Именно так это выглядит при настройке полей, отступов, границ, в целом — это так практически для всего, за исключением свойства border-spacing в таблицах, где значения расположены с точностью до наоборот: первое число устанавливает значение по горизонтали, второе — по вертикали. Несколько фоновых изображений для одного элемента Одному и тому же элементу можно назначать несколько фоновых изображений, разделив их запятой. При этом каждое из них можно по-разному настраивать, например — позиционировать. background: url(example1.png’) no-repeat center 50px, url(‘example2.jpg’) no-repeat bottom top; Эта возможность поддерживается начиная с IE11. Наложение CSS-анимаций Так же, как и при работе с фонами, можно накладывать друг на друга CSS-анимации: @keyframes foo { 0% { opacity: 0; } 100% { opacity: 1; } } @keyframes bar { 0% { transform: translateX(-100px); } 100% { transform: translateX(0px); } } .element { animation: foo 2s 0s, bar 1s 0s; } О странном поведении position: fixed при использовании трансформации translateZ Добавление трансформации translateZ(0); к контейнеру, который включает в себя элемент со свойством position: fixed; приводит к выравниванию элемента относительно контейнера, а не относительно окна. → Пример Стилизация элементов, на которые осуществляется переход по адресам, содержащим символ решётки (/#foo) Псевдо-класс :target можно использовать для стилизации элементов, на которые осуществляется переход при щелчке по ссылке с символом решётки. Так, например, щелчок по ссылке вида <a href="#foo">Go to Foo</a> прокрутит страницу до элемента <div id="foo">foo</div>. Теперь, если вы включили в CSS правило вида #foo:target { color: red; }, элемент <div> #foo будет окрашен в красный цвет. Выделение таких элементов может оказаться полезным для тех посетителей сайта, которые попали на страницу по внешней ссылке вроде www.example.com/#foo. При таком подходе браузер прокрутит страницу к нужному элементу и этот элемент окажется выделенным. В наши дни так поступают редко, но этот приём способен улучшить впечатления пользователей от работы с сайтом. → Пример Малоизвестные возможности content: ‘foo’; ▍Атрибуты данных Атрибуты данных можно использовать для динамического CSS-содержимого. Например: <div data-text="foo"></div> div:before { content: attr(data-text); } → Пример Этот приём может оказаться полезным, если, например, нужно перевести текст псевдо-класса (скажем, используя его для всплывающих подсказок). Сейчас с помощью attr() можно работать лишь с контентом. Хотя не исключено появление поддержки этой конструкцией других свойств. Более того, значения, получаемые из attr() — это строки, поэтому они предназначены, в первую очередь, для контента и не могут использоваться для свойств, задающих размеры (например — font-size), или для ссылок (например, content: url()). Кстати, поговорим об этом. ▍Content: url() Данную конструкцию можно использовать для многих видов данных (изображения, звуки, видео). Например: <div></div> div:before { content: url(image.jpg); } → Пример Однако если из DOM в CSS надо передавать произвольные данные, придётся обратиться к вышеописанным кастомным свойствам: <div style="--background-image: url('http://via.placeholder.com/150x150');"></div> div:after { content: ''; background-image: var(--background-image); } ▍Инкрементальный счётчик Конструкцию content: counter() можно использовать для инкрементной нумерации псевдо-элементов: p { counter-increment: myIndex; } p:before { content:counter(myIndex); } <p>foo</p> <p>bar</p> → Пример ▍Открывающие и закрывающие кавычки Свойство content псевдо классов вроде :before и :after может быть использовано для добавления к элементам открывающих и закрывающих кавычек: q:before { content: open-quote; } q:after { content: close-quote; } Если говорить о кавычках, то скомбинировав этот приём с ранее упомянутым выбором атрибутов данных, можно даже использовать CSS для задания специфического локализованного стиля кавычек, основанного на языке сайта, с применением одного лишь свойства quotes: html[lang="fr"] q { Quotes: "«" "»"; } Использование свойства font Свойство font позволяет, в сокращённом формате, задавать параметры шрифтов: h1 { font-weight: bold; font-style: italic; font-size: 1rem; //etc… } // комбинированный вариант h1 { font: italic lighter 1rem/150% Verdana, Helvetica, sans-serif; } // синтаксис // font: font-style font-variant font-weight font-size/line-height font-family; Директива supports Директиву @supports можно использовать для проверки того, поддерживает ли браузер возможности, интересующие разработчика. Скажем, если display:flex планируется использовать только в том случае, если есть уверенность в поддержке этой возможности браузером, можно применить следующую конструкцию: @supports (display: flex) { div { display: flex; } } Двоеточия в именах классов Использование двоеточий в именах классов может оказаться полезным для создания более понятных имён, которые, при чтении, легче делить на части. Так, например, некоторые CSS UI-фреймворки (вроде Tailwind) используют следующие соглашения по именованию: <div class="justify-start sm:justify-center md:justify-end lg:justify-between xl:justify-around"> <button class="bg-blue hover:bg-blue-dark text-white hover:text-blue-light">Button</button> Задавать специфические классы для стилей, применяемых к элементам, над которыми находится указатель мыши, возможно, в большинстве случаев не особенно полезно, но такой подход позволяет чётко отличать соответствующие состояния от других, что улучшает читаемость кода. Для использования двоеточий в CSS их нужно экранировать: .sm\:justify-center { } Трёхэлементный селектор Все, кто читают этот материал, должны знать о CSS-селекторе, состоящем из трёх элементов, который обычно называют «lobotomized owl selector». Вот как он выглядит: * + * { margin-top: 2rem; } Он придётся кстати в ситуациях, когда имеется множество элементов одного вида, между которыми должен быть отступ, причём, после последнего элемента такого списка отступ не нужен: li + li { margin-top: 1rem; } // вместо li { margin-bottom: 1rem; } li:last-of-type { margin-bottom: 0; } Вертикальное выравнивание методом «douchebag vertical align» Раз уж мы заговорили о необычных селекторах — вспомним и о методике вертикального выравнивания, называемой «douchebag vertical align»: .element { position: relative; top: 50%; transform: translateY(-50%); } Свойство font-feature-settings для шрифтов OpenType Шрифты OpenType поддерживают настройку свойств. Эту особенность можно использовать для подгонки шрифта под нужды конкретного проекта благодаря свойству font-feature-settings. Один из вариантов применения этой возможности открывается в ситуации, когда нужен красивый шрифт, не являющийся моноширинным, для таймера обратного отсчёта. Без специальной настройки ширина последовательности цифр будет постоянно меняться. Выглядит это непрофессионально. Вот решение этой проблемы: font-feature-settings: "tnum"; font-variant-numeric: tabular-nums; Обрезка текста с добавлением окончания в виде многоточия, "…" Тут всё предельно просто: p { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } → Пример Итоги Мы рассмотрели некоторые малоизвестные возможности CSS, которые, надеемся, пригодятся веб-разработчикам. Кстати, вот ещё одна интересная штука, не относящаяся, правда, к CSS. Это — HTML-элемент wbr, который позволяет отмечать места разрывов слов. Уважаемые читатели! Знаете ли вы о каких-нибудь возможностях CSS, полезных, но не получивших широкой известности? |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|