Единицы измерения vh, vw, vmin, vmax
Содержание:
- Какие бывают единицы измерения CSS
- Единица rem: смесь px и em
- Используйте em или px для шрифтов
- Циклы делают переменные CSS недействительными во время вычисления значения
- Что такое CSS-шлюз?
- CSS Свойства
- The Base Experiment
- What About rems and Sass?
- Case 1: Properties of all Elements Scale With The Component’s Font-Size
- Примеры использования viewport единиц
- Using Only REMs to Make a Header Element
- REMs or EMs?
- CSS-переменные упрощают инкапсуляцию стилей
- Components on a Grid
Какие бывают единицы измерения CSS
После рассмотрения способов задания цветов CSS автор видеоурока перейдет к подробному рассказу о единицах измерения CSS — размеров шрифтов, отступов и прочих элементов веб-страничек, где необходимо задание размеров.
Пиксели — самые распространенные единицы измерения CSS
Самым распространенным и известным определением размеров является задание их в пикселях. Базовым размером шрифта, который по умолчанию применяется большинством браузеров, является 16px.
Ключевые слова как вариант единиц измерения шрифтов в CSS
Для определения размера шрифта CSS также предлагает 7 ключевых слов, которые задают этот размер относительно базового: xx-small, x-small, small, medium, large, x-large и xx-large. Базовым является medium (16px), остальные уменьшают или увеличивают базовый размер. Эти единицы измерения CSS используют крайне редко.
Единицы измерения CSS — проценты
Задание единиц измерения CSS в процентах означает определение размеров относительно величин, заданных браузером либо размеров, прописанных в родительском блоке. Базовый размер шрифта (16px) равнозначен 100%. Относительные размеры могут изменяться, если наследуются значения тега-предка. Все вложенные теги наследуют его и используют для вычисления своих размеров.
Исключения!
- При установке свойства margin-left в % процент берется от ширины родительского блока, а не от его margin-left.
- При установке свойства line-height в % процент берется от текущего размера шрифта, а вовсе не от line-height родителя.
- Для width/height процент берется обычно от ширины/высоты родителя, но при position: fixed процент задается от ширины/высоты окна (а не родителя или документа).
Единицы измерения CSS — em
Следующие единицы измерения размеров в CSS — em. 1 em равен, как и при задании размеров в процентах, базовому размеру. Принцип работы механизма наследования с em точно такой же как и с процентами.
Современные единицы измерения CSS — rem
С появлением CSS3 появилась новая единица измерения размеров CSS — rem, что означает root element. Его значение основано на значении шрифта корневого root-элемента. В подавляющем большинстве случаев это относится к базовому размеру шрифта, а корневым элементом считается HTML. Для использования единиц измерения CSS rem можно установить базовый размер шрифта для элемента HTML, а затем применять rem для определения значений шрифтов относительно этого базового размера.
.main-menu {
font-size: .5rem; /*.5rem = 10px*/
}
.heading {
font-size: 1.5rem; /*1.5rem = 30px*/
}
Единицы измерения CSS относительно viewport — vw и vh
В CSS3 также появились такие новые единицы измерения, как vw и vh, они определяются относительно размеров области просмотра, т.е. размера viewport.
- 1vw = 1% ширины окна;
- 1vh = 1% высоты окна.
К этому типу единиц измерения относятся и следующие:
- vmin — наименьшее значение из vw и vh;
- vmax — наибольшее значение из vw и vh.
Эти единицы созданы для поддержки мобильных устройств, поскольку любые размеры, которые заданы в них, автоматически масштабируются в соответствии с размерами экрана, что очень удобно при создании адаптивных сайтов.
Этим видеоуроком завершится наш курс по основам CSS. Надеемся, полученные вами знания очень пригодятся вам в дальнейшем вашем развитии как веб-разработчика.
Приятного всем просмотра! Учитесь с удовольствием! Всегда ваш Loftblog.
Единица rem: смесь px и em
Итак, мы рассмотрели:
- – абсолютные, чёткие, понятные, не зависящие ни от чего.
- – относительно размера шрифта.
- – относительно такого же свойства родителя (а может и не родителя, а может и не такого же – см. примеры выше).
Может быть, пора уже остановиться, может этого достаточно?
Э-э, нет! Не все вещи делаются удобно.
Вернёмся к теме шрифтов. Бывают задачи, когда мы хотим сделать на странице большие кнопки «Шрифт больше» и «Шрифт меньше». При нажатии на них будет срабатывать JavaScript, который будет увеличивать или уменьшать шрифт.
Вообще-то это можно сделать без JavaScript, в браузере обычно есть горячие клавиши для масштабирования вроде Ctrl++, но они работают слишком тупо – берут и увеличивают всю страницу, вместе с изображениями и другими элементами, которые масштабировать как раз не надо. А если надо увеличить только шрифт, потому что посетитель хочет комфортнее читать?
Какую единицу использовать для задания шрифтов? Наверно не , ведь значения в абсолютны, если менять, то во всех стилевых правилах. Вполне возможна ситуация, когда мы в одном правиле размер поменяли, а другое забыли.
Следующие кандидаты – и .
Разницы между ними здесь нет, так как при задании в процентах, эти проценты берутся от родителя, то есть ведут себя так же, как и .
Вроде бы, использовать можно, однако есть проблема.
Попробуем использовать этот подход для .
Протестируем на таком списке:
Пока это обычный вложенный список.
Теперь уменьшим размер шрифта до , вот что получится:
Проблема очевидна. Хотели, как лучше, а получилось… Мелковато. Каждый вложенный получил размер шрифта от родителя, в итоге уменьшившись до нечитаемого состояния. Это не совсем то, чего мы бы здесь хотели.
Можно уменьшить размер шрифта только на одном «корневом элементе»… Или воспользоваться единицей , которая, можно сказать, специально придумана для таких случаев!
Единица задаёт размер относительно размера шрифта элемента .
Как правило, браузеры ставят этому элементу некоторый «разумный» (reasonable) размер по умолчанию, который мы, конечно, можем переопределить и использовать для задания шрифтов внутри относительно него:
Получилось удобное масштабирование для шрифтов, не влияющее на другие элементы.
Элементы, размер которых задан в , не зависят друг от друга и от контекста – и этим похожи на , а с другой стороны они все заданы относительно размера шрифта .
Единица не поддерживается в IE8-.
Используйте em или px для шрифтов
Единицы (пункт) and (пика)
CSS получил в наследство от печатного дела. Там традиционно
применялись эти и подобные единицы, а не сантиметры или дюймы.
В CSS незачем использовать , пользуйтесь любой
единицей на свой выбор. Но есть хорошая причина
не использовать ни , ни других абсолютных
единиц, а использовать только и .
Вот несколько линий разной толщины. Некоторые из них могут
казаться четкими, но как минимум линии в 1px и 2px должны быть
четкими и видимыми:
0.5pt,
1px,
1pt,
1.5px, 2px
Если первые четыре линии выглядят одинаковыми (либо линия
в 0.5pt пропала), скорее всего вы видите это на мониторе,
не способном отображать точки мельче 1px. Если линии выглядят
возрастающими по толщине, скорее всего вы видите эту страницу
на качественном экране или на бумаге. А если 1pt выглядит толще,
чем 1.5px, то это скорее всего экран мобильного устройства (похоже, последняя фраза описывает ситуацию до правки 2011 года —
прим. перев.).
Волшебная единица CSS, , часто бывает удачным
выбором, особенно если нужно выровнять текст с картинками, либо
просто потому, что что-либо толщиной 1px (или кратной 1px) заведомо
будет выглядеть четко.
Но размеры шрифтов еще лучше задавать в . Идея
в том, чтобы 1) не задавать размер шрифта для элемента BODY
(в HTML), а использовать размер шрифта по умолчанию для устройства,
поскольку это наиболее удобный для читателя размер; и 2) указывать
размеры шрифта других элементов в : , чтобы H1 был в 2½ раза крупнее
основного шрифта страницы.
Едиственное место, где можно использовать
(либо или ) для размера
шрифтов — стили для печати, если нужно, чтобы напечатанный шрифт
был строго определенного размера. Но даже там чаще всего лучше
использовать размер шрифта по умолчанию.
Циклы делают переменные CSS недействительными во время вычисления значения
Рассмотрим следующий фрагмент Sass:
Результат будет примерно таким:
CSS-переменные — это совсем другая история, естественное следствие их реактивности. Посмотрим на тот же фрагмент, но с CSS-переменными:
Переменная, зависящая от самой себя, создала бы бесконечный цикл, которого не должно быть в декларативном языке, таком как CSS. Чтобы избежать этого, циклы делают все задействованные переменные недействительными во время вычисления значения. Сюда входят циклы длины 1 (в примере выше) и более длинные циклические цепочки, где переменная A зависит от B, которая зависит от C, и так далее до Z, которая зависит от A. Все 26 (A..Z) были бы недействительными во время вычисления значения, что сделало бы их значение равным начальному, и это по существу дало бы такой же результат, как если бы они никогда не были установлены.
Что такое CSS-шлюз?
Размеры относительно окна браузера
В последнем проекте у меня был баннер во всю ширину с заголовком сверху, причем макет был только для настольных ПК, с крупным шрифтом. Я решил, что мне нужен шрифт помельче для маленьких экранов и что-то промежуточное для средних. Почему бы не сделать шрифт зависимым от ширины окна?
Ранние подходы для этого выглядели примерно так:
h1 { font-size: 4vw; /* Бац! Готово. */ }
У этого было два недостатка:
- Текст становится совсем мелким на маленьких экранах (12.8 пикселей при 320px) и очень крупным на больших (64px при 1600px);
- Он не реагирует на пользовательские настройки для размера шрифта.
Техники CSS-шлюзов призваны исправить первый пункт. Отличные техники CSS-шлюзов стараются исправить и второй: учет пользовательских предпочтений.
Понятие CSS-шлюза
CSS-шлюз — такой способ вычисления CSS-значения, при котором:
- есть минимальное и максимальное значения,
- есть две контрольные точки (обычно отталкивающиеся от ширины окна)
- и между этими контрольными точками фактическое значение линейно меняется от минимума до максимума.
«Пусть у нас font-size будет 20px при 320px и меньше, 40px при 960px и выше, а в промежутке его значение меняется от 20px до 40px».
В CSS это может выглядеть так:
h1 { font-size: 1.25rem; } @media (min-width: 320px) { h1 { font-size: /* магическое значение от 1.25rem до 2.5rem */; } } @media (min-width: 960px) { h1 { font-size: 2.5rem; } }
Первой трудностью для нас будет реализовать само это магическое значение. Не стану вас интриговать и сразу покажу отгадку, что оно будет выглядеть примерно так:
h1 { font-size: calc(1.25rem + значение_относительно_окна); }
Где может быть отдельным значением (напр., 3vw) или более сложным выражением (тоже на основе единицы vw или другой единицы области просмотра).
Ограничения
Раз CSS-шлюзы строятся на базе единиц области просмотра, у них есть важные ограничения. Они работают только для числовых значений, могут использовать и принимают значения в пикселях.
Почему в пикселях? Потому что единицы области просмотра (, , и ) всегда в конечном итоге переводятся в пиксели. Например, при ширине окна 768px переводится в 7.68px.
(У Тима в статье есть ошибка, где он пишет, что выражение типа переводится в em. Это не так: браузер воспримет как значение в пикселях, и вычтет из него столько пикселей, сколько их окажется в для этого элемента и этого свойства.)
Несколько примеров того, что работать не будет:
- CSS-шлюз для свойства opacity, потому что — это ошибка;
- CSS-шлюз для большинства функций (напр., нельзя повернуть что-либо на столько-то пикселей)
Что ж, на первый взгляд с одними лишь пикселями особо не разгуляешься, но, может быть, кто-то возьмет на себя смелость отыскать все свойства и приемы, где от CSS-шлюзов может быть польза.
Для разминки, возьмем свойства и и посмотрим, как построить для них CSS-шлюзы с контрольными точками как в пикселях, так и в em-ах.
CSS Свойства
align-contentalign-itemsalign-selfallanimationanimation-delayanimation-directionanimation-durationanimation-fill-modeanimation-iteration-countanimation-nameanimation-play-stateanimation-timing-functionbackface-visibilitybackgroundbackground-attachmentbackground-blend-modebackground-clipbackground-colorbackground-imagebackground-originbackground-positionbackground-repeatbackground-sizeborderborder-bottomborder-bottom-colorborder-bottom-left-radiusborder-bottom-right-radiusborder-bottom-styleborder-bottom-widthborder-collapseborder-colorborder-imageborder-image-outsetborder-image-repeatborder-image-sliceborder-image-sourceborder-image-widthborder-leftborder-left-colorborder-left-styleborder-left-widthborder-radiusborder-rightborder-right-colorborder-right-styleborder-right-widthborder-spacingborder-styleborder-topborder-top-colorborder-top-left-radiusborder-top-right-radiusborder-top-styleborder-top-widthborder-widthbottombox-decoration-breakbox-shadowbox-sizingcaption-sidecaret-color@charsetclearclipclip-pathcolorcolumn-countcolumn-fillcolumn-gapcolumn-rulecolumn-rule-colorcolumn-rule-stylecolumn-rule-widthcolumn-spancolumn-widthcolumnscontentcounter-incrementcounter-resetcursordirectiondisplayempty-cellsfilterflexflex-basisflex-directionflex-flowflex-growflex-shrinkflex-wrapfloatfont@font-facefont-familyfont-kerningfont-sizefont-size-adjustfont-stretchfont-stylefont-variantfont-weightgridgrid-areagrid-auto-columnsgrid-auto-flowgrid-auto-rowsgrid-columngrid-column-endgrid-column-gapgrid-column-startgrid-gapgrid-rowgrid-row-endgrid-row-gapgrid-row-startgrid-templategrid-template-areasgrid-template-columnsgrid-template-rowshanging-punctuationheighthyphens@importisolationjustify-content@keyframesleftletter-spacingline-heightlist-stylelist-style-imagelist-style-positionlist-style-typemarginmargin-bottommargin-leftmargin-rightmargin-topmax-heightmax-width@mediamin-heightmin-widthmix-blend-modeobject-fitobject-positionopacityorderoutlineoutline-coloroutline-offsetoutline-styleoutline-widthoverflowoverflow-xoverflow-ypaddingpadding-bottompadding-leftpadding-rightpadding-toppage-break-afterpage-break-beforepage-break-insideperspectiveperspective-originpointer-eventspositionquotesresizerightscroll-behaviortab-sizetable-layouttext-aligntext-align-lasttext-decorationtext-decoration-colortext-decoration-linetext-decoration-styletext-indenttext-justifytext-overflowtext-shadowtext-transformtoptransformtransform-origintransform-styletransitiontransition-delaytransition-durationtransition-propertytransition-timing-functionunicode-bidiuser-selectvertical-alignvisibilitywhite-spacewidthword-breakword-spacingword-wrapwriting-modez-index
The Base Experiment
I thought of creating three separate elements, one for , one for and one for . I gave each a background color so it becomes easy to tell them apart.
Next, I created a query on all three selectors since we’re comparing the media query units.
When the query kicks in, I decided to decrease the opacity of the element so I can see the difference immediately. Here’s the CSS for the pixel-based media query:
The next step is to figure out how to create the and units.
In this first experiment, I wanted to test if there were differences between the three units if all conditions were ideal. In other words, none of the following scenarios has happened:
- changed in
- user zoomed in.
- user changed their browser’s font setting.
Since the conditions are ideal at this point, I can safely assume that , and are equal. , then, is equivalent to or .
If all three media queries behave in the same manner, we should see all of them trigger at 400px exactly.
And they did (on every browser I tested).
The base experiment
Since all three media queries kicked in at the same breakpoint, we know that there’s no difference between , or queries at this stage.
After establishing the base experiment, the next step is to test for less ideal conditions where any of the scenarios above occurred. Once again, the scenarios are:
- changed in
- user zoomed in.
- user changed their browser’s font setting.
Let’s go through them one by one.
What About rems and Sass?
The in CSS always inherits its value from the base font size setting on the root element of the document, irrespective of the computed font size. In HTML, the root element is always the element. So you could use rems, but this would mean you’ll have to control all components on the page using the font size on that element. It could work on certain projects, but I think this technique works best when focusing the resizability on an isolated component, rather than the whole document.
As for using a preprocessor like Sass, I think that’s a side point. Ultimately, your compiled stylesheet will use whatever units you’re using in your Sass code, and the inheritance will work the same way.
Case 1: Properties of all Elements Scale With The Component’s Font-Size
Let’s begin with an example of what such a component looks like:
How component resizes (Case 1)
Notice how the , and of all elements within the component change at the same time?
If your component behaves in this manner when resized, you need to size everything in s. The code then becomes:
Then, to activate the change in sizes, all you have to do is to change the component’s property.
So far so good.
Now, let’s bring the complexity up a bit.
Imagine if you had a grid like this. The vertical and horizontal spaces between each grid item needs to remain the same across all devices (for good aesthetics).
Equal margins on a 1 + 2 grid!
The markup for this grid is:
I’ve set the gutter width between each grid item to be at a root of . In order words, the computed width of the gutter is .
The challenge in this grid is to separate small component A and small component B with a margin of . We can try setting a of component B to be for start.
Unfortunately, this doesn’t turn out well. The between small component A and small component B is larger than the gutter width at a viewport above 800px.
Space between the two smaller components isn’t equal to the gutters when the screen is wider than 800px
Boo 🙁
This happens because the of the component is (or ) when the viewport is larger than . Since the is , the computed value of becomes , which is different from the we were looking for.
Grrrrr! (╯°□°)╯︵ ┻━┻
Thankfully, we can solve this issue simply by sizing in since we know where the gutter width needs to be sized according to the root .
Vertical space is now equal! 🙂
Tada! Problem solved 🙂 Here’s a Codepen for you to play with.
See the Pen REM vs EM – Case 1 by Zell Liew (@zellwk) on CodePen.
Note: You need to use Flexbox to build this grid. I won’t explain how I built it since it’s way out of scope. Check out this article if you’re interested in finding out more about Flexbox
Oh by the way, I didn’t come up with this technique. Chris Coyier wrote about it a year ago. (He’s a genius).
Anyway, are we good so far? If yes, let’s move on to case 2. If not, feel free to leave a comment and I’ll figure a way to explain this further.
Примеры использования viewport единиц
В следующих секциях мы посмотрим на некоторые примеры использования единиц viewport и на то, как их применять в ваших рабочих проектах.
Размер шрифта
Единицы вьюпорта идеальны для адаптивной типографики. Для примера, мы можем использовать следующий код для заголовка статьи:
Размер заголовка будет увеличиваться или уменьшаться в зависимости от ширины вьюпорта. Это как будто бы мы выдали размеру шрифта 5% ширины страницы. Однако, как бы не хотелось, а надо протестировать и смотрим, что получается.
Обратите внимание, что шрифт стал очень мелким при мобильных размерах, это очень плохо в плане доступности и UX. Насколько я знаю, минимальный размер шрифта на мобильных устройствах не должен быть ниже
А там у нас выходит уже ниже .
Чтобы решить эту проблему, нам надо дать заголовку минимальный размер шрифта, который не может быть меньше положенной нормы. И тут CSS спешит на помощь!
У функции будет основное значение и оно добавит к нему . Учитывая это, размер шрифта точно не будет слишком маленьким.
Ещё стоит рассмотреть то, как себя будет вести размер шрифта на больших экранах, к примеру на 27” аймаках. Что будет? Ну вы уже наверное предположили. Размер шрифта бахнет аж в , что само по себе уже кошмар. Чтобы предохраниться от этой ситуации мы можем использовать медиа запросы на определённых брейкпоинтах и менять размеры шрифтов.
Сбрасывая мы можем быть уверены в том, что размер шрифта не будет слишком большим. Тут возможно вам понадобится несколько медиа запросов, но это сугубо ваше личное дело когда и как их использовать в контексте проекта.
Полноэкранные секции
Иногда нам надо, чтобы секция забирала 100% высоты виюпорта. Это так называемые полноэкранные секции. Для их создания мы можем использовать вьюпорт единицу высоты.
Добавив , мы можем точно убедиться в том, высота секции будет в 100% высоту вьюпорта. Также, тут я добавил немного флексбокса, чтобы отцентровать контент вертикально и горизонтально.
Прилипающий футер
На больших экранах вы могли уже обратить внимание на то, что футер не прилипает к концу страницы. Ну и это нормально
Это даже не рассматривается как плохая практика. Однако, тут у нас есть пространство для улучшений. Давайте рассмотрим следующий кейс, в котором и происходит эта ошибка.
Чтобы её решить, нам нужно отдать основному контенту высоту, равную разнице между высотой вьюпорта и суммой хедера и футера. Динамически это довольно хитрая операция, но с помощью единиц вьюпорта всё становится довольно быстро и понятно.
Первое решение: calc и единицы вьюпорта
Если высота хедера и футера фиксированны, то их можно совместить с помощью функции :
Это решение не гарантирует того, что оно будет всегда работать, особенно для футера. За всю свою карьеру я никогда не использовал футер с фиксированной высотой, потому что это просто непрактично, особенно на разных размерах экранов.
Второе решение: Flexbox и вьюпорт единицы (рекомендуемое)
Добавляя как высоту для элемента, мы можем использовать флексы для того, чтобы основной контент занимал всё оставшееся место.
С учетом этого, наша проблема решена и у нас есть прилипающий футер вне зависимости от длины контента.
Адаптивные элементы
Занимаясь подготовкой материала я наткнулся на эту статью и она мне реально понравилась. Так что я возьму пример использования оттуда и объясню его своим способом.
Предположим, что у нас есть портфолио для того, чтобы показать свои адаптивные работы и у нас имеется три типа устройства (мобильные, планшеты и ноутбук). В каждом устройстве есть по изображению. Суть в том, чтобы сделать этот контент 100% отзывчивым на CSS.
Используя гриды и единицы вьюпорта, мы можем сделать это адаптивным и динамическим.
Обратите внимание, что вьюпорт единицы используются в grid-* свойствах. Они также используются для , и других свойств
Всё это приведет к флюидному дизайну.
Выходим за пределы контейнера
Я обратил внимание на случай, который больше всего подходит для редакторских шаблонов. А именно когда дочерний элемент забирает 100% ширины вьюпорта, хотя его родитель ограничен в ней
Давайте рассмотрим пример ниже:
Чтобы достигнуть такого же эффекта, мы можем использовать вьюпорт единицы и свойства позиционирования. Вот наш CSS:
Давайте разберем всё по полочкам и поймём как это работает.
Добавляем
Самый важный шаг, который даст изображению ширину равную 100% вьюпорта.
Добавляем
Чтобы отцентровать изображение, нам понадобится выдать отрицательный маргин с половиной ширины вьюпорта.
Добавляем
И наконец, мы отодвинем изображение в правую сторону со значением 50% от ширины его родителя.
Using Only REMs to Make a Header Element
Say you have a header element () that looks like this:
I’m a header!
The header’s styles should be similar to the following if you sized everything in :
So far so good.
Next, let’s create a slightly bigger header element since it’s common to have differently-sized elements on the same website. While doing so, let’s try to inherit as many styles as possible.
The markup of the bigger header element might be something like this:
The CSS would be:
Unfortunately, the code doesn’t turn out well. You can see that there’s too little breathing space between the edge and text of .
Not enough breathing space between edge and text on this large header
If you insist on using only s, the only way to fix this problem is to redeclare the on the large header:
More padding the large header now!
Notice the pattern here? ’s is twice as large as ’s. Consequently, on is twice as large as on .
What would happen if we have more headers of different sizes, or if the headers have to change in size? You can already see how coding the entire site in can cause duplication and super complex code.
We can simplify the code such that there’s no need to redeclare on if we don’t mind using both and :
As you can see, can be incredibly helpful when you have a property that needs to scale with it’s font size. This is where the first rule was born.
Next, let’s take a look at what happens if you use an only approach for the same header.
REMs or EMs?
It’s highly debatable.
Some developers avoid entirely, claiming that using makes their components less modular. Others use for everything, preferring the simplicity that provides.
Oddly, I fell into the trap of strictly only or at different points in my development career. I loved how helped me make modular components, but I loathed the complexity it brought to my code. I also loved how made calculations simple, but I hated the hacks I used to make my components modular.
Turns out, and have their strengths and weaknesses. They should be used differently, depending on the circumstances.
How? I have two simple rules:
- Size in if the property scales according to its
- Size everything else in .
A tad too simple? Well, let’s consider writing a simple component (a header element) either using or , and you’ll see how these two rules play out nicely.
CSS-переменные упрощают инкапсуляцию стилей
CSS-переменные позволяют повторно использовать и настраивать CSS-код, поскольку они делают возможной инкапсуляцию. Предположим, есть стиль плоской кнопки, примененный к классу . Его упрощенный CSS-код выглядит так:
Допустим, ещё нужны кнопки разного цвета для разных действий, например красная кнопка для опасного действия. Можно добавить поддержку класса-модификатора и переопределять соответствующие объявления:
Заменим цвет переменной, чтобы избежать дублирования:
Теперь всё упростилось до переопределения одного свойства: :
Можно даже создавать темы «на лету», переопределяя свойство во встроенном (inline) стиле кнопки.
Это триумф краткости, но гораздо больший триумф инкапсуляции — роскошь, которую CSS не всегда позволял своим разработчикам. Фактически, натягивание тем на сторонний CSS-код раньше означало близкое знакомство с его внутренней структурой, а изменение стороннего кода требовало аналогичных обширных изменений и в коде тем. Теперь настраиваемые CSS-свойства могут служить своего рода API: кардинально меняя базовый стиль только с помощью настраиваемых свойств.
Возвращаясь к примеру с кнопкой, предположим, что надо добавить переход для более плавного эффекта наведения. Ещё надо, чтобы новый цвет фона увеличивался внутрь от границы вместо затухания по умолчанию, которое получается при переходе между двумя цветами фона. Для этого нужно имитировать фон с помощью :
Несмотря на то, что сама реализация довольно существенно изменилась, работают все цветовые темы кнопок. Если бы было нужно переопределять CSS для создания тем, код этих тем был бы сломан.
Эта возможность — не экономия нескольких символов или времени на обслуживание, она является истинной ценностью настраиваемых свойств. Они позволяют делиться кодом, который может быть повторно использован и настроен другими разработчиками, при этом допускает полностью изменять его внутреннюю структуру. Пользовательские свойства также являются единственным способом создания компонентов shadow DOM, потому что, в отличие от любых других CSS-свойств, они выходят за пределы shadow DOM.
Components on a Grid
Before we move on, let’s combine the header and paragraph elements together into a component:
The basic styles for this component are:
So far so good. This was everything we covered in the earlier sections.
Moving on, this component can be found in differents of a website. Potential areas include:
- The main content area
- The sidebar
- In a 1/3 grid layout
- …
Possible locations of the component
The header element might be rendered with a smaller when the component is placed in a narrow location, like the sidebar.
Header components on a grid.
We can create a variant for this by modifying the component’s class. The markup would look like this:
And the style for this variant is:
Now, on to the component’s styles. The same two rules still apply:
- Size in if property should scale according to it’s
- Size everything else in .
As with the header element, you can identify which properties to size in by seeing if they interact with the rest of the page. There are two different ways to think about building this component:
- Properties of all inner elements scale with the component’s .
- Properties of some inner elements scale with the component’s .
Let’s build the component in both ways and you’ll see what I mean.