Единицы измерений в css
Содержание:
- Загрузка подмножества символовСкопировать ссылку
- Practical Application
- Как адаптировать размер текста под размер экрана
- min(), max()
- Rem Units vs. Em Units
- Rem vs Em
- Относительные единицы измеренияСкопировать ссылку
- EM
- Best of both worlds
- Относительно шрифта: em
- Процентные единицы измерения длины, зависящие от размеров области просмотра
- Rem
- CSS-переменные облегчают разделение поведения и стиля
- clamp()
- What About rems and Sass?
- Why Use em Units
- Что насчет rem и Sass?
Загрузка подмножества символовСкопировать ссылку
Быстрая загрузка веб-страниц всегда была важна — но сейчас, с появлением на рынке широкого спектра мобильных устройств (с каждым из которых понятие «скорость соединения» становится всё более изменчивым и неопределенным) это, пожалуй, особенно важно. Один из способов ускорить загрузку страницы — сократить размер внешних подгружаемых файлов, и поэтому новое свойство внутри , которое позволяет делать именно это — весьма полезное добавление
Свойство, о котором идет речь — , и в качестве значения оно принимает набор ссылок на юникод-символы. При загрузке внешних ресурсов из файла шрифта будут загружаться только эти символы, а не все символы, присутствующие в шрифте. Приведенный код показывает, как загрузить только три символа из файла foo.ttf:
Особенно это полезно в том случае, если вы используете иконки внутри шрифта и хотите показывать на конкретной странице не все из них, а только конкретные. В одном тесте, который я провел, использование сократило общее время загрузки файла шрифта в среднем на 0,85 секунды — а это вполне существенно. Конечно, у вас могут получиться и другие цифры.
Это свойство на данный момент поддерживается в IE9+ и браузерах на движке WebKit: Chrome и Safari.
Practical Application
There may be some debate among web designers and I’m sure different people have different preferred approaches, however my recommendation is as follows.
Use Units For:
Any sizing that should scale depending on the font-size of an element other than the root.
Generally speaking, the only reason you’ll need to use units is to scale an element which has non default font sizing.
As per our example above, design components like menu items, buttons, and headings may have their own explicitly stated font sizes. If you change these font sizes, you want the entire component to scale proportionately.
Common properties this guideline will apply to are , , , and settings, when used on elements with non default font sizing.
I recommend that when you do employ units, the font size of the element they’re used on should be set in units to preserve scalability but avoid inheritance confusion.
Typically Don’t Use Units for Font Sizes
It’s quite common to see units used for font sizing, particularly in headings, however I would suggest that designs are more manageable if units are typically used for font sizing.
The reason headings often use units is they’re a better choice than units, being relative to regular text size. However units can achieve this goal equally well. If any font size adjustment on the element is made, the heading sizes will still scale too.
Try changing the font size on the element in this CodePen to see for yourself:
More often than not, we don’t want our font sizes to scale based on any element other than the root, with only a few exceptions.
One example where we might want based font sizing could be a drop down menu, where we have second level menu item text sized depending on the font size of the first level. Another example might be a font icon used inside a button, where the icon’s size should relate to the button’s text size.
However most elements in a web design will tend not to have this type of requirement, so you’ll generally want to use units for font sizing, with units only where specifically needed.
Use units for:
Any sizing that doesn’t need units for the reasons described above, and that should scale depending on browser font size settings.
This accounts for almost everything in a standard design including most heights, most widths, most padding, most margins, border widths, most font sizes, shadows, basically almost every part of your layout.
In a nutshell, everything that can be made scalable with units, should be.
Tip
When creating layouts it’s often easier to think in pixels but output in units.
You can have pixel to calculations done automatically via a preprocessor like Stylus / Sass / Less, or a postprocessor like PostCSS with the PXtoRem plugin.
Alternatively, you can use PXtoEM to manually do your conversions.
Always Use Media Queries
Importantly, when using units to create a uniformly scalable design, your media queries should also be in units. This will ensure that whatever a user’s browser font size, your media queries will respond to it and adjust your layout.
For example, if a user scales up text very high, your layout may need to snap down from a two columns to a single column, just as it might on a smaller screened mobile device.
If your breakpoints are at fixed pixel widths, only a different viewport size can trigger them. However with based breakpoints they will respond to different font sizing too.
Don’t Use or For:
Multi Column Layout Widths
Column widths in a layout should typically be based so they can fluidly fit unpredictably sized viewports.
However single columns should still generally incorporate values via a setting.
For example:
This keeps the column flexible and scalable, but prevents it from becoming too wide for the text therein to be comfortably readable.
When an Element Should be Strictly Unscalable
In a typical web design there won’t be many parts of your layout that can’t be designed for scalability. However occasionally you will come across elements that really do need to use explicit fixed values for the purpose of preventing scaling.
The precondition for employing fixed sizing values should be that if the element in question were scaled it would break. This really doesn’t come up often, so before you’re tempted to whip out those units, ask yourself if using them is an absolute necessity.
Как адаптировать размер текста под размер экрана
Допустим, дизайнер поручил нам сделать так, чтобы заголовки на странице меняли размер в зависимости от ширины экрана. Если экран широкий, то и заголовок должен быть большим. Если экран узкий — пусть будет компактным.
Самый прямолинейный способ это сделать — задать размер в единицах vw. Например, 1vw — это 1% ширины экрана; 10vw — 10% ширины экрана. Если экран шириной 1000 пикселей, то 20vw — это 200 пикселей.
Звучит неплохо, но может плохо выглядеть: смартфоны обычно очень узкие, а экраны компьютеров очень широкие, и разница в размере шрифта будет в 5–6 раз. И если, например, основной текст фиксированного размера, а заголовки должны менять размер, то на широких экранах заголовки будут мельче, чем основной текст.
На телефоне с узким экраном всё выглядит нормально.
А на широком экране компьютера текст стал больше заголовка.
Второй вариант — использовать медиазапросы. Мы расскажем о них подробно в другой статье, а пока кратко: это когда мы можем накатывать разные стили на документ в зависимости от того, как этот документ отображается. Можно сказать: «Если экран шире 500 пикселей, используй вот такой размер шрифта; если шире 1000 пикселей — сякой; а если это не веб-страница, а версия для печати — вообще используй другой шрифт и размер».
Тогда мы можем просто задать размеры стандартных экранов смартфонов и прописать нужные размеры текста для каждого, и всё будет выглядеть идеально.
Теперь всё в порядке.
Текст:
Михаил Полянин
Редактор:
Максим Ильяхов
Художник:
Даня Берковский
Корректор:
Ирина Михеева
Вёрстка:
Кирилл Климентьев
Соцсети:
Олег Вешкурцев
min(), max()
Функция возвращает минимальное из переданных значений, — максимальное. При использовании процентов или выбираемое значение будет динамическим и будет зависеть от внешних условий. Например:
Если поресайзить окно с примером, можно увидеть как это работает.
Если вычисленное значение для меньше , ширина блока будет равна . Как только станет больше , функция выберет меньшее значение, то есть , и дальше блок тянуться не будет.
Функция будет выбирать подходящее значение учитывая ширину окна в данный момент.
Этот код не делает ничего особенного, что не умел бы CSS без математических функций: точно такое же поведение можно получить задав и :
Оба варианта для сравнения:
Порастягивайте демо, чтобы увидеть, что разницы в поведении блоков нет.
На первый взгляд, и не делают ничего интересного, но если подумать, как много мест в CSS, где можно управлять диапазоном значений?
Это доступно только для ширины и высоты:
- , ,
- , ,
и их аналогов, привязанных к направлению письма:
- , ,
- , ,
У нас нет, например, или , но благодаря математическим функциям, можно добавить умную динамику практически в любое значение. Например, в размер шрифта:
Поресайзите демо, и вы увидите, что при растягивании шрифт будет бесконечно расти, но при сужении, как только станет меньше или равным , размер шрифта застынет на этом значении.
Если попытаться реализовать подобное на JS, пришлось бы отслеживать ресайз окна, получать вычисленное значение, и при превышении заданного порога, фиксировать значение на определённом уровне. При использовании и браузер всё делает сам: отслеживает изменение значений и, при необходимости, фиксирует их — нам нужно просто выбрать функцию и задать диапазон значений.
Это будет работать во всех свойствах, которые используют размеры, в том числе в тенях, градиентах и прочем. Пример с :
Размер тени будет зависеть от размера окна браузера, минимальное значение — .
Экспериментируя с функциями и можно заметить, что они дают возможность управлять или минимальным значением, или максимальным, но нельзя контролировать и то, и другое одновременно. Хотя совершенно логичным выглядит желание, например, задать размер шрифта, который будет расти в диапазоне от минимального значения до максимального и не выходить за эти значения.
Для такого есть ещё одна функция:
Rem Units vs. Em Units
The main problem with em units is that they are relative to the font size of their own element. As such they can cascade and cause unexpected results. Let’s consider the following example, where we want lists to have a font size of , in the case where the root font size is the default :
If we have a list nested inside another list, the font size of the inner list will be 75% of the size of its parent (in this case ). We can still overcome this problem by using something along these lines:
This does the trick, however we still have to pay a lot of attention to situations where nesting gets even deeper.
With rem units, things are a simpler:
As all the sizes are referenced from the root font size, there is no more need to cover the nesting cases in separate declarations.
Rem vs Em
I’ll start this off by saying I honestly wasn’t completely sure what the difference between and was until recently, so if you aren’t either, don’t feel bad. Let’s clear this up once and for all…
For me, realizing that the “R” in REM stands for “root” was what helped me to finally differentiate the two. Let’s check out a quick example to help clarify vs .
Just some example CSS to show how will work, notice the root font-size is set using via tag
And the corresponding HTML:
Because the tag is set to it ignores the parent div’s font-size of 18px. However, if we instead set the font-size to , the paragraph would inherit the 18px font-size of its parent element. I know this example isn’t particularly useful, but hopefully it can help illustrate the difference between and .
Относительные единицы измеренияСкопировать ссылку
Скорее всего, вы, умный и предусмотрительный веб-разработчик, работаете с относительными единицами измерения — то есть с или процентами — так что эта проблема вам должна быть знакома: вам наверняка приходится сидеть за калькулятором, чтобы вычислить размеры — из-за наследования. Например, сейчас вполне обычный прием — установить базовый размер шрифта для документа, а потом использовать относительные единицы, чтобы установить размер шрифта для всех остальных элементов на странице. В CSS это выглядит примерно так:
Здесь всё отлично, и никакой проблемы нет, пока у вас не появляется дочерний элемент, которому вы хотите установить какой-нибудь другой размер шрифта. Например, в такой разметке:
Если вы хотите, чтобы этот было меньшего размера шрифта, например, , то что вам делать? Берите калькулятор и считайте, сколько будет 1,2 поделить на 1,4, и в итоге у вас получится:
И проблема не ограничивается использованием . Если вы разрабатываете тянущийся сайт с использованием ширин в процентах, то знаете, что эти проценты соотносятся с размерами контейнера элемента, так что если у вас есть элемент, которому вы хотите поставить ширину в 40% от его родительского элемента, ширина которого — 75%, тогда придется устанавливать ширину этого элемента в 53,33333%.
Мягко говоря, не идеально.
EM
EM — это относительная единица измерения. В CSS EM обозначает множитель размера шрифта по умолчанию у устройства или документа.
Например, допустим, в документе размер шрифта задан как 16px. 1em равен 16px, 2em – 32px и так далее. Хотя EM обычно используется для обозначения размера шрифта и фактически это стандартная единица измерения в стилях браузера для измерения размера шрифта, мы можем также использовать EM, чтобы задавать длину элемента.
Единственная проблема при использовании EM – это то, что он не очень интуитивно понятен, но есть два способа справиться с этим. Во-первых, мы можем использовать удобный калькулятор PX в EM.
Другой способ — установить размер пикселя по умолчанию равным 10px, чтобы было удобнее считать, например, задав 15px как 1.5em. Надеемся, вы получили общее представление с помощью этого примера.
Best of both worlds
The best parts about the unit is that it allows you to quickly scale an entire project, across resolutions, just by setting the root font-size once per media query, and then scaling from there. You can do this a number of ways, but the simplest method is to set a base px font size, say , and then use to inherit that base font size and scale it up or down for sizing of H1-H5, body copy, and even margins and padding. Let’s take a look:
This step is optional, but if you use Sass or Less it’s nice to set up reusable screen size breakpoints for your media queries.
Now we can use those screen size variables (or hard-coded values) to set staggered root font-sizes. Here we’re doing this mobile first, with a default font-size of 15px that applies to and below screen sizes (most phones), up to on extra large monitors or TVs.
And now we can use the root font-size to scale our headings, and any other reusable or common elements.
Относительно шрифта: em
– текущий размер шрифта.
Можно брать любые пропорции от текущего шрифта: , и т.п.
Размеры в – относительные, они определяются по текущему контексту.
Например, давайте сравним с на таком примере:
пикселей – и в Африке пикселей, поэтому размер шрифта в одинаков.
А вот аналогичный пример с вместо :
Так как значение в высчитывается относительно текущего шрифта, то вложенная строка в раза больше, чем первая.
Выходит, размеры, заданные в , будут уменьшаться или увеличиваться вместе со шрифтом. С учётом того, что размер шрифта обычно определяется в родителе, и может быть изменён ровно в одном месте, это бывает очень удобно.
Что такое размер шрифта?
Что такое «размер шрифта»? Это вовсе не «размер самой большой буквы в нём», как можно было бы подумать.
Размер шрифта – это некоторая «условная единица», которая встроена в шрифт.
Она обычно чуть больше, чем расстояние от верха самой большой буквы до низа самой маленькой. То есть, предполагается, что в эту высоту помещается любая буква или их сочетание. Но при этом «хвосты» букв, таких как , могут заходить за это значение, то есть вылезать снизу. Поэтому обычно высоту строки делают чуть больше, чем размер шрифта.
Единицы и
В спецификации указаны также единицы и , которые означают размер символа и размер символа .
Эти размеры присутствуют в шрифте всегда, даже если по коду этих символов в шрифте находятся другие значения, а не именно буква и ноль . В этом случае они носят более условный характер.
Эти единицы используются чрезвычайно редко, так как «размер шрифта» обычно вполне подходит.
Процентные единицы измерения длины, зависящие от размеров области просмотра
Область просмотра основывается на ширине и высоте окна просмотра и включает в себя:
- vh (высота окна просмотра);
- vw (ширина окна просмотра);
- vmin (наименьшее из (vw, vh));
- vmax (наибольшее из (vw, vh)).
vw
Это ширина области просмотра. 1vw равен 1/100 ширины окна просмотра. Немного похоже на проценты, за исключением того, что значение остается неизменным для всех элементов независимо от ширины их родительских элементов. Например, если ширина окна 1000px, то 1vw будет равен 10px.
vh
То же самое, что и vw (ширина окна просмотра), только данная единица измерения зависит от высоты области просмотра. 1vh равен 1/100 высоты просмотра. Например, если высота окна браузера 900px, то 1vh будет 9рх.
vmin
Vmin равно 1/100 от минимального значения между высотой и шириной области просмотра. Другими словами, 1/100 стороны с наименьшей длиной. Например, если размеры окна 1200 на 800 пикселей, то значение vmin будет равно 8px.
vmax
vmax равно 1/100 от максимального значения между высотой и шириной окна просмотра. Другими словами, 1/100 стороны с наибольшей длиной. Например, если размеры были 1200 на 800 пикселей, то vmax равно 12px.
Проценты %
Расстояние, заданное в процентах, зависит от длины родительского элемента. Например, если родительский элемент шириной 1000px, а его дочерний элемент — 50% от этого значения, то ширина дочернего элемента будет 500px.
Rem
Итак, как вы уже поняли, это значение не взаимодействует с body, оно взаимодействует с основным корневым тегом . У корневого узла есть особый селектор псевдокласса, который записывается как . В данном случае rem это и есть сокращение от слов «root em», то есть «корневой em». Если вы работаете с rem, то вы должны помнить, что его значения относительны не к текущему элементу, а к корневому
В данном случае совершенно не важно, где вы используете значение rem, оно никак не будет влиять на остальные значения
Если мы вернемся к предыдущему примеру с вложенностями, то в данном случае, если мы напишем rem, эта проблема отпадёт. Вы так же можете использовать значения больше единицы, и при этом остальные уровни никак не видоизменятся. Они используют те же значения, что и первый элемент.
Если вернуться к примеру где мы рассматривали em, то мы можем скопировать и написать , что сделать небольшое отличие в классах:
<div class="box-rem"> Lorem Ipsum <p class="post">Lorem Ipsum</p> </div>
Если в стилях запишем
.box-rem .post { font-size: 1.2rem; }
то увидим, что это значение никак не видоизменится, т.к. первый «Lorem Ipsum» записан вне тегов. Он меняется по отношению к body, но при этом, если мы запишем селектор
:root { font-size: 50px; }
то мы увидим, что значение меняется относительно этого сектора.
Давайте создадим еще один пример и поговорим о некоторых тонкостях с использованием rem. Давайте снова создадим , внутри которого будет содержаться тег и
<div class="box"> <h2>Home</h2> <p>Does your lorem ipsum text long for something a little fishier? Give our generator a try… it’s fishy!</p> </div>
То, что я сейчас покажу — это анти-пример и я не советую применять на своих проектах. И в конце я объясню почему.
Итак, запишем селектор .
Заодно давайте поговорим о том, как вычислить 10px с точки зрения em. Для этого открываем калькулятор. Что бы вычислить, сколько будет 10px, мы делим 10 на тот размер, который у нас установлен по умолчанию, то есть на 16px. Итого у нас получается значение 0.625. Давайте запишем:
:root { font-size: 0.625em; /*=10px */ }
Далее давайте будем стилизовать . Начнем вычислять с точки зрения rem для этого нам необходимо 14 разделить на 10 и выходит 1.4rem
h2 { font-size: 1.4rem; /* =14px */ }
Этот метод удобен тем, что нам не потребуется прибегать к вычислениям. Всё это возможно вычислить в уме. Но я предлагаю сделать заголовок сделать все-таки чуть больше, например, 24px. В rem значении это будет 2.4rem.
h2 { font-size: 2.4rem; /* =24px */ }
Как вы видите, по умолчанию, если я не буду стилизовать , либо какие-то другие элементы, которые будут появляться на странице, например:
<ul><li>Lorem</li><li>Lorem</li><li>Lorem</li></ul>
то все они автоматом будут иметь размер шрифта 10px. Это слишком маленький размер шрифта и на экранах он будет нечитабельным, а это значит, что вам придется для каждого элемента добавлять значение , из-за чего файл документа CSS значительно увеличится. В данном случае приходиться чем-то жертвовать и как мне кажется, использовать такой метод нецелесообразно.
Если вы не хотите использовать размер шрифта 10px по умолчанию, то вы можете использовать другое значение — 14px. Чтобы вычислить, сколько это будет в rem, для этого нужно 14px / 16px. Итог: 0.875rem
:root { font-size: 0.875em; /*=14px */ }
Теперь мы видим, что текст по умолчанию стал читабельным. Заголовок увеличился, потому что 2.4rem это уже не 24px. А сколько? Давайте посчитаем: 24px / 14px = 1.71rem. Давайте запишем:
h2 { font-size: 1.71rem; /* =24px */ }
В таком случае размер заголовка у нас стал таким же, как тогда когда у нас составлял 10px. Конечно же, такое значение не вычислить в уме, однако работы с кодом по итогу будет значительно меньше.
Давайте предположим, что мы работаем с media-запросами. Например, размер шрифта нам нужно сделать чуть большедля планшетов и ПК устройств. То есть если мы будем использовать media-запросы то внутри мы можем записать и внутри media мы запишем селектор :root с значением font-size: 1em, то есть 16px:
@media (min-width:768px) { :root { font-size: 1em; } }
Таким образом, при увеличении экрана у нас размер шрифта становится больше, заголовок тоже автоматически становится больше, при этом, если вам нужно его подкорректировать вы это тоже можете сделать в media запросе, но в целом много стилей вам менять не потребуется. И это на самом деле удобнее, чем, если бы вы работали с простыми пикселями. Потому что если бы вы работали с пикселями, то вам потребовалось бы менять каждое значение, чтобы сохранить соотношение.
CSS-переменные облегчают разделение поведения и стиля
Реактивность переменных CSS — это делает их мощными. При правильном использовании стили могут оставаться в CSS, а вычисления — в JavaScript, где им и положено находиться. Предположим, нужен радиальный градиентный фон, на котором центральная точка градиента следует за курсором мыши. Раньше приходилось генерировать весь градиент в JavaScript и устанавливать его во встроенном (inline) стиле HTML-элемента при каждом движении мыши. С CSS-переменными в JavaScript необходимо установить только две переменные: и . В обычном JavaScript это может выглядеть так:
Затем надо в CSS настроить эффект, например, так:
See this code CSS gradient that follows the mouse with CSS variables on x.xhtml.ru.
Совершенно другой эффект будет со слоистыми градиентами, в которых используется одна и та же центральная точка:
See this code CSS gradients that follow the mouse with CSS variables on x.xhtml.ru.
Предположим, надо сделать, чтобы оттенки и угол в коническом градиенте менялись в зависимости от времени суток. Тот же самый JavaScript будет работать и для мыши, поэтому следует добавить немного JavaScript, который устанавливает CSS-переменную с текущим часом (0–23):
Затем включить эту переменную в CSS и использовать её в вычислениях:
See this code CSS gradient «clock» that follows the mouse with CSS on x.xhtml.ru.
Поскольку все три переменные, установленные с помощью JavaScript, являются чистыми данными, а не значениями из CSS, их можно использовать в нескольких несвязанных CSS-правилах. (Они не относятся непосредственно к эффектам только для фона.)
clamp()
Она сочетает в себе и . Функция получает на вход параметры:
И вычисляет значение вот таким образом:
Проще всего её понимать представляя среднее значение () как желаемое, которое ограничено минимальным и максимальным значениями. Например, этот код
описывает следующее поведение: размер шрифта равен , но не меньше и не больше . Порастягивайте демо, чтобы увидеть как это работает:
Аналогичный подход часто используется при разработке адаптивных сайтов: мы задаём минимальное и максимальное значения ширины страницы, позволяя ей тянуться и сжиматься в заданных пределах, например, в диапазоне от до :
Используя это можно записать в одну строчку:
Для следующего демо я взяла значения поменьше, но смысл тот же: блоки тянутся в пределах от до . Ширина верхнего блока управляется с помощью и , нижнего — с помощью :
Оба блока ведут себя совершенно одинаково, разница только в возможностях этих подходов: позволяет добавить умную динамику значений в любое свойство, не только в размеры блоков. Мне нравится идея использовать для адаптивных шрифтов, почитать про это можно в статье Linearly Scale font-size with CSS clamp() Based on the Viewport.
Предыдущие функции достаточно просты по сравнению с , самой мощной и интересной.
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.
Why Use em Units
The key value units offer is they allow sizing values to be determined by a font size other than that of the element.
For this reason, the primary purpose of units should be to allow for scalability within the context of a specific design element.
For example, you might set the , and around a navigation menu item to use values.
Menu with 0.9rem font size
This way if you change the menu’s font size the spacing around the menu items will scale proportionately, independently of the rest of the layout.
Menu with 1.2rem font size
In the earlier section on inheritance you saw how quickly keeping track of units can get out of hand. For this reason, I recommend only using units if you identify a clear need for them.
Что насчет rem и Sass?
Единица rem в CSS всегда наследует значение размера шрифта корневого элемента независимо от вычисленного размера шрифта. В HTML корневым является элемент <html>. Таким образом можно использовать rem. Но это означает, что вы должны будете управлять всеми компонентами на странице, используя размер шрифта этого элемента. Это может сработать в некоторых проектах, но я думаю, что этот метод лучше всего работает при изменении размеров отдельного компонента, а не всего документа.
Что касается использования препроцессора Sass, то это уже второстепенный вопрос. В итоге CSS будет использовать любые единицы измерения, которые указаны в Sass коде, и наследование будет работать таким же образом.