Единицы измерения
Помимо стандартных px
и %
существует 1001 способ задать размер элементам.
Зависящие от размера шрифта
em
- зависит от font-size
дочернего элемента
rem
- зависит от font-size
элемента html
Относительно экрана (viewport-а)
Появились в первую очередь для мобилок
vw
- viewport width, % от ширины окна браузера.vh
- viewport height, % от высоты окна браузераvmin
,vmax
- для мобилок, % от меньшей/большей размерности вьюпорта вне зависимости от ориентации
Проблемы - не учитываются размеры элементов браузера, например адресная строка в safari или клавиатура
Чтобы решить эти проблемы - придумали новый костыль модификаторы:
svh
- small viewport height, представляет высоту области просмотра, когда пользовательский интерфейс адресной строки еще не уменьшил свой размер. svh отвечает за то содержимое страницы, которое вы будете видеть, когда интерфейс адресной строки растянут до максимума.lvh
- large viewport height, представляет высоту области просмотра после того, как пользовательский интерфейс адресной строки уменьшил свой размер. lvh отвечает за то содержимое страницы, когда пользовательский интерфейс сжат до минимума.dvh
- dynamic viewport height - использует любое из значений svh или lvh в зависимости от того, уменьшен ли интерфейс адресной строки. dvh просчитывает переходные состояния между максимальным и минимальным размером UI в браузере.svw, lvw, dvw
- такая же история для ширины области просмотраsvmin, lvmin, dvmin
- аналогvmin
,vmax
Однако классическую проблему со скроллбаром новые единицы так и не решили -
100svw
= 100dvw
= 100lvw
= 100vw
Решение проблемы со скроллбаром
html,body {scrollbar-gutter: stable;}/* 100vw не вызовет появление горизонтального скролла */.full-width {width: 100vw;}
либо
body {margin: 0;container-type: inline-size;}.full-width {width: 100vw; /* fallback for older browsers */width: 100cqw; /* 100cqw учитывет сколлбар */}
Зависящие от размера блока
Можно использовать единицы измерения, которые будут зависить от размера блока
cqw
: 1% of a query container's widthcqh
: 1% of a query container's heightcqi
: 1% of a query container's inline sizecqb
: 1% of a query container's block sizecqmin
: The smaller value of either cqi or cqbcqmax
: The larger value of either cqi or cqb
Чтобы использовать эти единицы измерения, нужно задать container-type
у родительского контейнера:
Объяснение container-type
.container {container-type: inline-size;container-name: card;}.container-child {width: 100cqw; /* всегда будет того же размера, что и my-container */}
cqw
всегда зависит от ширины контейнера, даже если есть вложенность.
<div className="container"><div className="container-inner"><div className="container-child">Hi</div></div></div>
.container {width: 400px;height: 400px;background: blueviolet;container-type: inline-size;container-name: card;}.container-inner {width: 300px;}.container-child {width: 100cqw; /* 400px, а не 300px */height: 40px;background: red;}
Можно использовать в медиазапросах:
@container (min-width: 400px) { /* Если ширина ближайшего контейнера больше 400px */.card h2 {font-size: 2em;}}@container card (min-width: 400px) { /* Если ширина контейнера с именем card больше 400px */.card h2 {font-size: 2em;}}
Зависящие от соотношения сторон
aspect-ratio
- соотношение ширины к высоте, например 1 / 1 - квадрат, а 16 / 9 - прямоугольник
Можно использовать в медиазапросах, для этого есть min-aspect-ratio
, max-aspect-ratio
@media screen and (min-aspect-ratio: 16/10) {/* something for wide screens */}
Селекторы
/* По id */#foo {}/* По классу */.bar {}/* По наличию аттрибута */.input[type]/* По значению аттрибута */.input[type="submit"]/* Потомок с классом .bar внетри элемента с классом .foo */.foo .bar {}/* Элемент с классом .foo И классом .bar */.foo.bar {}/* Непосредственная вложенность - .bar может быть только на первом уровне вложенности */.foo > .bar {}/* Стили для .bar, если он расположен сразу после .foo (сосед) */.foo + .bar {}/* Стили для любого .bar, если он расположен после .foo (но не обязательно сосед)*/.foo ~ .bar {}
Псевдоклассы
Псевдокласс - ключевое слово, добавленное к селектору для уточнения его состояния.
selector:pseudo-class {property: value;}
Самые полезные:
-
:hover
- при наведении -
:focus
- при фокусе (tab) -
:focus-within
- при фокусе этого элемента или его детей -
:active
- при активации, например при зажатии ЛКМ -
:checked
- для выбранных<input type="radio">
,<input type="checkbox">
или<option>
внутри<select>
-
:disabled
- для кнопок -
:empty
- когда у элемент пуст (нет children), можно применить.element:empty { display: none }
вместо условного рендеринга -
:first-child
- первый ребенок своего родителя -
:first-of-type
- первый ребенок такого типа, например первыйdiv
-
:last-child
- последний ребенок своего родителя -
:last-of-type
- последний ребенок такого типа, например последнийdiv
-
:nth-child()
- какой-то конкетный ребенок (1-й, второй, третий, четный, нечетный) -
:nth-of-type()
- какой-то конкетный элемент такого типа -
:only-child
- единственный ребенок -
:only-of-type
- единственный элемент такого типа -
:valid
,:optional
,:required
- для валидации форм -
:visited
- для посещенных ссылок, рудимент если честно -
:is()
- позволяет проще писать сложный CSS
.card h1,.card h2,.card h3 {color: black;}.card :is(h1, h2, h3) {color: black;}a:hover,a:focus {color: purple;}a:is(:hover, :focus) {color: purple;}
-
:where()
похож на :is, но позволяет убить специфичность, идеально для reset -
:has()
- позволяет проверить наличие у родителя наличие какого-то селектора внутри и выбрать именно родителя
/* Если в форме есть невалидный инпут - покрась submit кнопку в красный */.my-form:has(input:invalid) button[type="submit"]{background: red;}
/* */html:has(.modal.open) {background: red;}
Псевдоэлементы
Псевдоэлементы не существуют в HTML разметке, они создаются только с помощью CSS, их нельзя создать, выбрать(querySelector-ом) и менять при помощи JS.
::after
- добавить какой-то контент после элемента (создать псевдоэлемент, который является последним потомком)::before
- до (создать псевдоэлемент, который будет первым потомком)::first-letter
- стилизовать первую букву::first-line
- стилизовать первую линию