Comprehensive guide: when to use em vs. rem

The most widely used size units

px

px (pix element) is a main and base absolute size unit. The browser converts all other units in px by default.
The main advantage of px is its accuracy. It is not hard to guess that 1px is equal to 1px of the screen. If you zoom any raster image you will see little squares. There are pixels.

But the disadvantage is that pixel is an absolute unit. It means that pixel doesn’t set the ratio.

Let’s look at the simple example.

HTML of this example:

CSS:

Element with class=’element2′ is nested in parent with class=’element1′. For the both elements font-size is equal to 20px. On the image above you can see that sizes of the words ‘Hello’ and ‘Habr Reader’ are the same.

What can this example say about a pixel? Pixel sets a specific text size and does not depend on the parent element.

em

em is a more powerful unit size than px because it is relative. It means that we can set a ration for it.

Let’s look at our previous example to fully understand the sense of em. We will change font-size of .element1 and .element2 to 2em.

The result:

What do we see? The size of the text ‘Habr Reader!’ is 2 times more than ‘Hello’.It means that em sets the size by looking at the size of the parent element.

For example, we set to .element1 font-size: 20px and to .element2 — 2em. If we convert 2em to px, how many pixels will be the value of the .element2?

Let’s give a conclusion for the em unit. em asks the question: How many times I bigger or less than the value of my parent element?

rem

It is easier to understand the sense of rem by comparing it with em.

rem asks the question: How many times I bigger or less than the value of <html>?

For example, if we set:

And for two elements:

The Result:

Let’s convert the size of .element1 and .element2 to pixels.

percent

% is a another relative unit. But this is more unpredictable than em and rem. Why? Because it has a lot of side cases.

In the majority of cases, % takes ratio from the parent element like em. It works for the width, height or font-size properties. If we look at our example it will work like an example with em.

The result:

Let’s conve… No, no. I’m just kidding. I’m sure you can calculate the simple ratio with percent.

Let’s look at some other cases with %. For the property margin, it takes the width of the parent element; for the line-height — from the current font-size. In such cases, it is better and more rational to use em instead.

vw and vh

  • 1vw means 1% of the screen width.
  • 1vh means 1% of the screen height.

These units are usually used for mobile platform support.
The simple example is the block below.

Even if you resize the screen the block always will contain 50% of the screen width and height.

Rarely used units

  • 1mm = 3.8px
  • 1cm = 38px
  • 1in (inch) = 96px
  • 1pt (Typographic point) = 4/3px ~ 1.33px
  • 1pc (typographic peak) = 16px
  • 1vmin = the lowest value from vh and vm
  • 1vmax = the highest value from vh and vm
  • 1ex = exactly the height of a lowercase letter “x”
  • 1ch = the advance measure of the character ‘0’ in a font
Unit Unit Type The Parent for which the Ratio is set Example
absolute
relative the First Parent element
relative <html>
relative the First Parent element *()
relative the screen width and height

Абсолютные длины

Абсолютные единицы длины фиксированы, а длина, выраженная в любом из них, будет выглядеть точно так же, как и размер.

Абсолютные единицы длины не рекомендуются для использования на экране, так как размеры экрана меняются так сильно.
Однако их можно использовать, если известен выходной носитель, например, для макета печати.

Единицы Описание
cm

centimeters

mm

millimeters

in

inches (1in = 96px = 2.54cm)

px *

pixels (1px = 1/96th of 1in)

pt

points (1pt = 1/72 of 1in)

pc

picas (1pc = 12 pt)

* Pixels (px) are relative to the viewing device. For low-dpi devices, 1px is one device pixel (dot) of the display. For printers and high resolution
screens 1px implies multiple device pixels.

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:

  1. Size in if the property scales according to its
  2. 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.

Relative Lengths

Relative length units specify a length relative to another length property.
Relative length units scales better between different rendering mediums.

Unit Описание
em Relative to the font-size of the element (2em means 2 times the size of the current font)
ex Relative to the x-height of the current font (rarely used)
ch Relative to width of the «0» (zero)
rem Relative to font-size of the root element
vw Relative to 1% of the width of the viewport*
vh Relative to 1% of the height of the viewport*
vmin Relative to 1% of viewport’s* smaller dimension
vmax Relative to 1% of viewport’s* larger dimension
% Relative to the parent element

Совет: Модули EM и REM практичны в создании идеально масштабируемой компоновки! * Видовой экран = размер окна браузера. Если видовой экран шириной 50 см, 1ВВ = 0.5 cm.

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 2: Properties of Some Elements Scale With The Component’s Font-Size

Case 1 is easy to understand. The downsides though, are that it’s tough for you to stay true to your modular scale, maintain good vertical rhythms and ensure that every component is sized well AT the same time (especially when building responsive websites).

Sometimes you just need to tune a small section of your component instead of resizing everything at once. For example, you might want to change only the header at a larger viewport.

Only the headers change in size when the viewport changes

Let’s start styling this case by taking a look at the basic styles we wrote above:

Since we’re only changing the header’s s at , we can safely size every property in (with the exception of the header’s and properties)

You can then change the header’s at different viewports by simply adding a media query on them:

Tada! Notice how only the header changes as we resize the browser now? That’s how you build for case 2 🙂

One more thing.

Since it’s a best practice to use only a handful of typography sizes, I often abstract the property away from the component. This way, it becomes easy to ensure that your typography remains consistent across all components.

That’s it for case 2! Here’s a Codepen for you to play with:

See the Pen REM vs EM – Case 2 by Zell Liew (@zellwk) on CodePen.

Here’s a question you’ll probably ask, so I thought I’ll answer it first: Which method should you use?

I’ll say it depends on your design.

Personally, I find myself working with Case 2 more often than Case 1 since I prefer abstracting away typography into a file of it’s own.

What are ems?

In CSS, an em unit is equal to the computed for the element to which the em is applied. When em units are declared on child elements that don’t have a defined, they will inherit their from their parent, or from another ancestor element, possibly going all the way back to the root element on the document.

Look at the following CSS:

In this case, 1em on this element, or on its child elements (assuming no other definitions), would be equal to 20px. So if we added a line:

This value of computes to 10px (i.e. 20*.5). Similarly:

The padding value of is equal to 40px (20*2). As mentioned, this type of calculation would apply to any child elements as well — unless any of those child elements had an explicitly defined value, in which case the em value would be calculated based on that. If no font size is defined anywhere in the CSS, the em unit will be equal to the browser’s default font size for the document, which is usually 16px.

I think that should make it clear how ems work. Now let’s look at how this technique can be used to make easily resizable web components, as discussed by Simurai in the original Medium article. I’ll take his idea a step further by providing a demo to see this in action.

Conclusion

There doesn’t seem to be an industry standard way of handling responsive typography yet, with some preferring to use , some , and others a combination of the two. There’s even a growing group that say to never use for font-sizes because it doesn’t allow the user to increase or decrease font-size in their browser settings. To be honest, there’s valid arguments from all sides, so it’s best to use the method that makes sense for the project you’re working on and the audience that it’s for.

One thing is for sure, setting a root font-size, and then using to scale your type up or down from there—as I’ve done above— is super easy to grasp, scale, and maintain. Hopefully it will be of help to you too.

Why Use rem Units:

The greatest power that units offer is not just that they give consistent sizing regardless of element inheritance. Rather, it’s that they give us a way to have user font size settings influence every single aspect of a site’s layout by using units where we used to use units.

For this reason the primary purpose of using units should be to ensure that whatever default font size a user has their browser set to, the layout will adjust to accommodate the size of text within it.

A site can be designed initially focusing on the most common default browser font size of 16px.

Browser font size 16px

But by using units, if a user increases their font size, the integrity of the layout will be preserved, and the text won’t get squashed up in a rigid space meant for smaller text.

Browser font size 34px

And if the user decreases their font size, the entire layout scales down, and they won’t be left with a tiny smattering of text in a wasteland of white space.

Browser font size 9px

Users change font size settings for all kinds of reasons, from strained eyesight to choosing optimum settings for devices that can be vastly different in size and viewing distance. Accommodating these settings allows for much better user experiences.

Important to Know:

Some designers use based layouts in conjunction with a fixed unit setting on the element. This is typically done so that a change of font size on the element can scale overall the design up or down.

I strongly advise against this as it overrides the font size the element inherits from the user’s browser settings. Hence this prevents the settings from having any effect, and removes the user’s ability to optimize for best viewing.

If you do want to change the font size on the element, do so with an or value as the root font size will then still be a multiple of the user’s browser font size setting.

This will still allow you to scale your design up or down by changing your element’s font size, but you’ll preserve the effect of user browser settings.

ex и ch

Единицы и , по аналогии с и , соотносятся с текущим шрифтом и размером шрифта. Но, в отличие от и , они также соотносятся  c .

или character является продвинутой единицей измерения ширины от нуля, . Наиболее интересные обсуждения того, что это может значить, можно найти в блоге Эрика Мейерса. Вкратце, если мы возьмем моноширинный шрифт, контейнер с шириной из букв, тогда, например, всегда будет содержать выражение из 40 единиц этого конкретного шрифта. Когда стандартным использованием этого правила является пример шрифта Брайля, возможности творческого подхода существенно расширяют его функционал.

обозначается как «x-высота текущего шрифта ИЛИ половина «. выбранного шрифта называется высота буквы x нижнего регистра этого шрифта. Часто эта высота оказывается срединной точки всей высоты шрифта.

X-высота; высота буквы x нижнего регистра (читайте больше про структуру веб типографики)

Для этой единицы измерения существует множество вариантов использования, большинство из них являются небольшими дополнениями к основной типографике. Например, элемент , который обозначает надстрочные символы, может быть приподнят относительно своей позиции, если ему задать position: relative и значение свойства bottom 1ex. Таким же образом вы можете опустить подстрочные буквы еще ниже. Стандартные настройки браузера использует свои правила надстрочных и подстрочных символов. Но если вам нужна более тонкая настройка, вы можете сделать ее следующим образом:

Могу ли я это использовать?

Единица существует примерно , а вот для такой поддержки вы не найдете. Для ознакомления со спецификацией по поддержке свойств, ознакомьтесь со значениями и единицами CSS в блоге Эрика Мейерса.

Процент

С процентом все более понятно, он устанавливается относительно родительского блока. Если ширина родительского блока 800px, тогда 50% будет 400px. За последние годы адаптивный дизайн становится стандартом в веб-дизайне, так что единица измерения процент используется все чаще.

Давайте рассмотрим следующий пример, в отрывке кода ниже задается значение ширины, равное 60%, блокам классов .container и .main, но у блоков этих классов разные родительские блоки, так что они будут разной длины. Блок класса .container займет 60% ширины видимой области браузера, а блок класса .main займет 60% ширины своего родительского блока класса .container.

.container {
    width: 60%;
    margin: 100px auto;
    background-color: #eaeaea;
    padding: 1%;
    height: 250px;
    font-family: Arial;
    text-align: center;
}
.main, .aside {
    line-height: 253px;
}
.main {
    width: 60%;
    height: 100%;
    float: left;
    background-color: #ccc;
}
.aside {
    width: 40%;
    height: 100%;
    background-color: #aaa;
    float: left;
}

Таким образом, мы получим следующий результат:

Так как процент тоже относительная единица измерения, с ним есть такая же проблема, как и с единицами измерения EM. Может быть сложно быстро сосчитать в уме, сколько процентов от 500px составит 15px. Это обычно происходит, когда мы переводим единицы измерения пиксели из фазы дизайна в веб-страницу. Есть два пути, которыми можно решить эту проблему: Вы можете традиционно считать с помощью калькулятора, или, если Вам удобно использовать предобработчик CSS, Вы можете использовать функцию percentage()из Sass.

Font-family — задаем имя шрифта в CSS

Начнем с атрибута стиля font-family с помощью которого можно задать гарнитуру и тип шрифта, которым будет выведен текст html-элемента (например текст заголовка или абзаца p). Синтаксис применения атрибута выглядит так:

font-family: <список имен шрифтов разделенных запятыми>

Список имен шрифтов задается в виде их названий (например Arial, Verdana или Times New Roman). Если имя шрифта содержит пробелы, то его необходимо взять в кавычки. Можно указать несколько наименований шрифтов, разделив их запятыми. В этом случае браузер сначала будет искать первый из указанных шрифтов, в случае неудачного поиска — второй, третий и так далее:

p { font-family: Arial, Verdana, ‘Times New Roman’, san-serif; }

В данном примере браузер сначала будет искать на компьютере пользователя шрифт Arial и если найдет, то отобразит все элементы p этим же шрифтом. Если же Arial на компьютере пользователя не найдется, тогда браузер будет искать Verdana, затем, в случае неудачи — Times New Roman, и так далее. Последним в списке имен шрифтов в данном примере идет не имя конкретного шрифта, а имя целого семейства шрифтов, представляющего целые наборы аналогичных шрифтов.

Таким образом можно задавать целые семейства шрифтов. Таких семейств всего пять:

  • serif — шрифты с засечками;
  • sans-serif -шрифты без засечек;
  • cursive — шрифты, имитирующие рукописный текст;
  • fantasy — декоративные шрифты;
  • monospace — моноширинные шрифты.

Кроме имен шрифтов, свойству font-family можно задать особое значение inherit, которое говорит браузеру, что текст данного элемента нужно отображать таким же шрифтом, как и текст родительского элемента.

Some Notes, Flaws, etc.

As you can see from using the range slider in the demo, this type of flexible resizing isn’t always something you’ll want to use. It can be somewhat restricting.

You may have to tweak some of the em values to get them how you like, and, as in the case of the parent border in the demo, you may not want the resize-ability to apply to all elements. You can overcome this easily by simply avoiding ems on the elements you want to leave out.

As described in the discussion on Simurai’s original article, you don’t have to use px units to set the root . You can use ems for that too, but just remember that this will be inherited in the same way from its parent, possibly coming from the document’s default value for .

Using rem Units for Scaling Documents

A third use we can find for rem units is to build scalable components. By expressing widths, margins, and padding in rem units, it becomes possible to create an interface that grows or shrinks in tune with the root font size. Let’s see how this thing works using a couple of examples.

In this first example, we change the root font size using media queries. Just like in the previous section, the purpose is to customize the reading experience for the device used. As element padding values and margins are expressed using rem, the entire component scales with the device size.

Let’s see another:

See the Pen Dynamic Sizing of Modules with Rem Units by SitePoint (@SitePoint) on CodePen.

In the second example we do the same alteration using JavaScript. This time the user has control over the size of the interface, adjusting it to fit his needs. Add a way to store these custom values (using either a database, cookies or local storage) and you have the base of a personalization system based on user preferences.

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.

Процентные единицы измерения длины, зависящие от размеров области просмотра

Область просмотра основывается на ширине и высоте окна просмотра и включает в себя:

  • 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.

Относительно шрифта: em

– текущий размер шрифта.

Можно брать любые пропорции от текущего шрифта: , и т.п.

Размеры в – относительные, они определяются по текущему контексту.

Например, давайте сравним с на таком примере:

пикселей – и в Африке пикселей, поэтому размер шрифта в одинаков.

А вот аналогичный пример с вместо :

Так как значение в высчитывается относительно текущего шрифта, то вложенная строка в раза больше, чем первая.

Выходит, размеры, заданные в , будут уменьшаться или увеличиваться вместе со шрифтом. С учётом того, что размер шрифта обычно определяется в родителе, и может быть изменён ровно в одном месте, это бывает очень удобно.

Что такое размер шрифта?

Что такое «размер шрифта»? Это вовсе не «размер самой большой буквы в нём», как можно было бы подумать.

Размер шрифта – это некоторая «условная единица», которая встроена в шрифт.

Она обычно чуть больше, чем расстояние от верха самой большой буквы до низа самой маленькой. То есть, предполагается, что в эту высоту помещается любая буква или их сочетание. Но при этом «хвосты» букв, таких как , могут заходить за это значение, то есть вылезать снизу. Поэтому обычно высоту строки делают чуть больше, чем размер шрифта.

Единицы и

В спецификации указаны также единицы и , которые означают размер символа и размер символа .

Эти размеры присутствуют в шрифте всегда, даже если по коду этих символов в шрифте находятся другие значения, а не именно буква и ноль . В этом случае они носят более условный характер.

Эти единицы используются чрезвычайно редко, так как «размер шрифта» обычно вполне подходит.

Создание цветовых палитр

Как правило, руководства по стилю начинаются с одного или нескольких основных акцентных цветов, из которых создается остальная палитра. Использование переменных только для основных цветов будет более эффективно, чем необходимость вручную настраивать каждый вариант цвета. К сожалению, в CSS пока нет функций изменения цвета. Между тем, вместо того, чтобы определить базовый цвет как одну переменную, нужно использовать отдельные переменные для компонентов цвета.

Из цветовых синтаксисов, доступных для CSS в настоящее время, имеет тенденцию работать лучше для создания цветовых вариаций (до тех пор, пока не получим , который будет намного круче из-за своего более широкого диапазона и восприятия). Если понадобятся только варианты светлее/темнее и прозрачнее, можно использовать переменную как для оттенка, так и для насыщенности:

Эти переменные можно использовать в CSS или создавать на лету новые варианты. Да, есть ещё небольшое дублирование — яркость основного цвета — но если планируется создать много альфа-вариаций, можно добавить переменную со всеми тремя координатами или одну с яркостью.

Relative Lengths

Relative length units specify a length relative to another length property.
Relative length units scale better between different rendering medium.

Unit Description
em Relative to the font-size of the element (2em means 2 times the size of the current font) Try it
ex Relative to the x-height of the current font (rarely used) Try it
ch Relative to the width of the «0» (zero) Try it
rem Relative to font-size of the root element Try it
vw Relative to 1% of the width of the viewport* Try it
vh Relative to 1% of the height of the viewport* Try it
vmin Relative to 1% of viewport’s* smaller dimension Try it
vmax Relative to 1% of viewport’s* larger dimension Try it
% Relative to the parent element Try it

Tip: The em and rem units are practical in creating perfectly
scalable layout!* Viewport = the browser window size. If the viewport is 50cm
wide, 1vw = 0.5cm.

What is EM?

This statement doesn’t make sense on the web since we don’t use . It makes complete sense if we substituted with though.

What it means is: if a selector has a of .

The unit can be used to declare font-sizes. In fact, it’s a best practice to use relative units like for .

Consider the following:

What’s the actual size of the selector here?

We have to look at the parent element in order to compute the ‘s . Let’s say the parent element is , and its is set to .

When put this way, we can see that the computed value of is , or .

Although this is possible, it’s often a bad idea to set in the to a pixel value because it overrides the user’s browser settings.

Instead, you can either choose to use a value, or leave out the declaration entirely.

Note: will be set to if you left it out entirely.

For most users (and browsers), a of would default to unless they change the default through their browser settings. It’s rare that anyone would do that though.

Okay so far? Let’s come back to .

can also be used to specify values for other properties in addition to . and are two of such properties that are commonly sized in s.

This is where many people start to get confused with values.

Consider the following code. What should the value be for both the and elements? (Assume of is set to ).

Are you surprised that the computed value of on is different in these two scenarios`?

This phenomenon occurs because is equal to its current . Since the in is now set to . Other properties computed with in would see that .

What throws people off is that can take on different values in different parts of the code. It can be confusing if you’re just starting out with s.

Anyway, that’s . Let’s find out what is next.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector