Este artigo tem como objetivo desmistificar unidades de comprimento relativo . Em contraste com unidades de comprimento absoluto (com px como o representante mais conhecido), as unidades de comprimento relativo especificam um comprimento relativo a outra coisa. Esse"algo mais"pode ser de vários tipos, por exemplo, o tamanho da fonte de um elemento pai, a largura de um contêiner pai ou a altura da janela de visualização.
Ambos os tipos de unidades têm o termo comprimento
em comum, mas o que exatamente é uma unidade de comprimento neste contexto? Existem unidades de comprimento relativo à fonte (por exemplo, em
, rem
), que são relativos aos caracteres ou propriedades relacionadas à fonte de um elemento. Além disso, existem unidades de comprimento que são relativas à janela de visualização (por exemplo , vw
, vh
).
Outro tipo de dados CSS comum no contexto de unidades relativas é a porcentagem (%
). Existem também propriedades CSS que aceitam valores inteiros . O caso de uso mais comum para esse valor sem unidade é usá-lo com a altura da linha propriedade .
As unidades relativas são especialmente importantes do ponto de vista de layouts fluidos e acessibilidade da web para oferece suporte a usuários que dependem de zoom . Esses layouts de fluido são baseados em um design proporcional, onde os comprimentos são definidos em termos de porcentagens em relação a um contêiner.
Portanto, os componentes baseados em unidades relativas podem mudar de tamanho no tempo de execução porque são (re) calculados em relação a um contêiner contextual, por exemplo, girando um dispositivo ou diminuindo o tamanho de uma janela do navegador.
Unidades CSS relacionadas à fonte
Primeiro, veremos como funcionam as unidades CSS relacionadas às fontes mais comuns: em
e rem
.
Unidade CSS em
O navegador converte um valor em
em um valor px
em relação ao contexto de tamanho da fonte atual. Vamos dar uma olhada em um exemplo.
Ver a Caneta
CSS Unit em-Headings de Sebastian Weber ( @doppelmutzi )
em CodePen .
Qual é o valor real margin-top
do elemento h2
? Abra o DevTools do Chrome, selecione h2
e navegue até o Guia Computado na seção CSS. O valor é 40px
.
Como surgiu esse valor? A fórmula de cálculo para a propriedade CSS considerada ( margin-top
) do elemento HTML ( h2
) é:
Multiplique o valor em
(2) pelo valor real de font-size
em px do elemento HTML a ser estilizado (20). Para nosso exemplo, isso significa: 2 * 20px=40px.
E sobre margin-top
para o elemento h3
no exemplo? O valor final é 46,8px
.
Por que isso? Não declaramos um valor font-size
, como fizemos com o elemento h2
. No entanto, cada elemento tem um valor derivado-isso é da natureza das coisas em CSS.
Como podemos ver, nosso elemento h3
tem um valor font-size
padrão de 1,17em
. OK, também não é um valor px
. Temos que subir na hierarquia dos elementos pais até encontrar um valor px
.
Com a ajuda do DevTools, descobrimos que o elemento body
tem um valor font-size
absoluto derivado dos valores padrão do navegador, pois não especificamos um valor personalizado valor.
Com essas informações, nosso valor concreto pode ser calculado: 2,5 * 1,17 * 16=46,8px
.
O próximo exemplo demonstra que em
não é exclusivo para estilizar o conteúdo do texto; pelo contrário, pode ser usado onde quer que você use unidades de comprimento. Pode parecer um pouco estranho no início, mas você pode estilizar elementos não textuais sem problemas.
Veja a Caneta
CSS Unit em (margin) de Sebastian Weber ( @doppelmutzi )
em CodePen .
Unidade CSS rem
A unidade relativa relacionada à fonte rem
significa “root em”. Ele se correlaciona com o font-size
do elemento raiz do navegador (normalmente o elemento html
). É fácil determinar: Multiplique o valor rem
pelo valor real de font-size
em px
do html
elemento.
Aqui está um exemplo.
Ver a Caneta
CSS Unit rem de Sebastian Weber ( @doppelmutzi )
em CodePen .
O valor calculado margin-top
do elemento h2
é 32px
porque o valor rem
definido (2 ) é multiplicado pelo valor absoluto font-size
do elemento html
( 16px
). Como não fornecemos um seletor para definir o font-size
do elemento html
, ele é o padrão do navegador.
Para a maioria dos navegadores (desktop), o padrão é 16px
. Mas para descobrir com certeza, você pode aproveitar as DevTools novamente.
O suporte do navegador é bom . Ele pode ser usado sem problemas, exceto se você tiver que desenvolver para navegadores legados.
Trabalhando com em
É uma boa ideia verificar a documentação padrão CSS do W3C de tempos em tempos. Aqui, você pode ver que a propriedade font-size
obtém herdado da hierarquia HTML pai.
Portanto, trabalhar com em
pode ser complicado:
- Cada elemento HTML herda seu valor
font-size
de seu elemento HTML pai - Se um
em
baseado emfont-size
for definido para o elemento raiz (html
), opx
o valor resulta da multiplicação com o valor padrão do navegador. Alguns navegadores permitem definir os valores do usuário nas configurações que são então usadas
A conseqüência é que as configurações de fonte do navegador podem influenciar potencialmente todos os valores em
por meio de herança. Do ponto de vista da acessibilidade, isso é crucial para oferecer suporte aos usuários que dependem do zoom.
No entanto, isso pode levar a um comportamento indesejado em elementos aninhados estilizados com valores em
.
Veja a caneta
em-problema de herança por Sebastian Weber ( @doppelmutzi )
em CodePen .
Em nosso exemplo, o font-size
de elementos aninhados mais profundos é maior do que o esperado. Por que isso?
- O
font-size
para o nível 1li
é14px
:-
1.4 (seletor li) * 10px (tamanho da fonte herdado
do corpo)
-
- O
font-size
para o nível 2li
é19.6px
:-
1.4 (seletor li) * 14px (herdado do nível 1 li)
-
- O
font-size
para o nível 3li
é ainda maior em27.44px
-
1.4 (seletor li) * 19.6px (herdado do nível 2 li)
-
Para resolver esse problema de forma a garantir que todos os elementos li
tenham o mesmo tamanho de fonte, você pode adicionar outro seletor.
li li {tamanho da fonte: 1em; };
Tenha isso em mente para o seu design CSS. Provavelmente você não deseja usar em
em tal cenário; em vez disso, use rem
.
Trabalhando com rem
Determinar o valor calculado de px
para uma propriedade CSS usando um valor rem
é fácil: você deve multiplicar o valor rem
pelo html
. Use o DevTools (guia Computado ) para descobrir se você definiu o valor.
A lista abaixo fornece mais detalhes sobre como o valor px
do elemento html
é determinado:
- Se você não definiu um valor
px
personalizado para o elementohtml
, o valorpx
é herdado das configurações do navegador ou os valores padrão do navegador - Se você definir o
font-size
do elementohtml
com um valorpx
, então isso é o que é usado para o cálculo - Se você definir o
tamanho da fonte
do elementohtml
com um valorem
ou%
, o o valor real depx
é calculado com a ajuda das configurações de fonte ou valores padrão do navegador - Se você definir o
tamanho da fonte
do elementohtml
com um valorrem
, o valorpx
do elementohtml
é o resultado da multiplicação com as configurações de tamanho de fonte do navegador ou valores padrão
A consequência é que as configurações de fonte do navegador podem influenciar todos os valores de rem
no design CSS. Usar rem
não causa um “problema de herança” de font-size
, como você pode ver no próximo exemplo.
Veja a Caneta
CSS Unit rem-sem efeitos de herança por Sebastian Weber ( @doppelmutzi )
em CodePen .
As definições de
tamanho da fonte
na hierarquia pai são irrelevantes porque os valores de rem
são sempre correlacionados com o valor (calculado) de px
do único Elemento html
.
Quando usar rem
e em
Usar rem
e em
anda de mãos dadas com os tópicos de design responsivo, usabilidade e acessibilidade.
A vantagem de rem
é o tamanho unificado sem herança de font-size
. Como designer de aplicativos, você pode reagir às configurações de fonte do usuário para apresentar o conteúdo de maneira adequada. Isso é importante para não excluir usuários que contam com um design acessível. Quando um usuário aumenta o tamanho da fonte, você tem a oportunidade de manter a integridade do layout, por exemplo, o texto não fica comprimido em um pequeno recipiente de largura fixa.
em
é uma ferramenta poderosa na cintura de todo desenvolvedor CSS. O princípio básico para definir o estilo de um elemento é determinar “valores de tamanho” (por exemplo, margem
, largura
) dependendo dos valores de tamanho da fonte
do pai elementos Portanto, não está limitado ao elemento raiz ( html
).
Um dos principais benefícios do em
é sua capacidade de estabelecer relações proporcionais entre os elementos de design dentro de um contexto (por exemplo, um botão ou módulo de teaser). O uso de em
anda de mãos dadas com as questões de escalabilidade contextual e design responsivo. O próximo exemplo demonstra como em
pode ser usado para design de componente responsivo.
Ver a Caneta
Botões responsivos com unidade em de Sebastian Weber ( @doppelmutzi )
em CodePen .
A estrutura responsiva do componente do botão é definida com o seletor botão
. border
, padding
e border-radius
utilizam unidades relativas que se relacionam ao valor de font-size
definido. Os diferentes tamanhos de botão são definidos com os seletores de classe concretos (por exemplo, size-l
).
Uma vez que os valores font-size
também são unidades em
, o valor contextual concreto é derivado dos valores px
concretos definidos com o footer
.
A vantagem dessa abordagem é que você pode reutilizar facilmente esses componentes em diferentes contextos. Você só precisa definir diferentes valores de font-size
para os diferentes contêineres de contexto, e então a herança faz o resto.
Unidade CSS relativa %
Em CSS, a porcentagem (%
) não é uma unidade de comprimento per se, mas um tipo de dados . Usá-lo parece uma unidade de comprimento porque você pode aplicá-lo em qualquer lugar onde você pode usar px
, em
, etc. Portanto, é justo mencioná-lo neste contexto.
Este tipo de dados sempre se refere a uma fração do componente pai. Um comprimento definido em porcentagem é baseado no comprimento (valor calculado em px
) da mesma propriedade do elemento pai. O exemplo a seguir ilustra isso:
main { largura: 400px; altura: 50%; } h1 { largura: 50%; }olá, mundo
A largura
calculada do elemento h1
é a metade de seu elemento pai main
, ou seja, 200px
. Se o container pai for o elemento body
, então a porcentagem sempre se refere ao tamanho da janela de visualização do navegador. Em nosso caso, o valor calculado da propriedade height
do elemento main
é a metade da altura do valor calculado do contêiner da janela de visualização.
Vamos dar uma olhada em alguns detalhes essenciais. No CodePen a seguir, os contêineres de fundo cinza são os elementos pais para os elementos h2
(o fundo azul).
Veja a caneta
Demonstração de porcentagem de CSS de Sebastian Weber ( @doppelmutzi )
em CodePen .
O comportamento padrão para um elemento de nível de bloco sem uma largura definida pelo usuário é ocupar o espaço horizontal disponível do contêiner pai , como você pode ver com a demonstração 1 . O preenchimento horizontal (o fundo azul escuro) de nosso h2
não é adicionado à largura total.
Porém, como você pode ver na demonstração 2 , definir uma largura: 100%
explícita faz com que uma barra de rolagem horizontal seja exibida. Por que isso?
Em contraste com o demo 1 , em que o padrão largura
tem o valor auto
, definir um valor percentual inclui preenchimento
, margin
e border
em seu cálculo e permite que os filhos ultrapassem a largura de seu contêiner pai. Você pode ler sobre isso na especificação CSS .
No demo 3 , especificamos width: 100%
também, mas não temos uma barra de rolagem horizontal. Isso ocorre porque as border
e padding
das crianças não estão adicionando ao espaçamento horizontal devido ao fato de que alteramos o padrão de box-sizing: content-box
para box-sizing: border-box
. Não é incomum definir um seletor global para usar border-box
em todo o design CSS.
Com a demonstração 4 e a demonstração 5 , você pode ver que a porcentagem não está necessariamente relacionada ao elemento pai direto, mas a um elemento mais acima na árvore pai.
Unidades da janela de visualização
Os valores percentuais (%
) sempre se referem ao elemento pai. No entanto, os valores da unidade da janela de visualização representam uma porcentagem da janela de visualização atual do navegador.
Os valores das unidades da janela de visualização são determinados com base na largura do contêiner da janela de visualização ( vw
) e na altura ( vh
). O intervalo de valores está entre 1 e 100:
-
1vw
é 1 por cento da largura da janela de visualização; da mesma forma,1vh
é 1 por cento da altura da janela de visualização -
100vw
é 100 por cento da largura da janela de visualização; da mesma forma,100vh
é 100 por cento da altura da janela de visualização
O caso de uso mais óbvio para unidades de janela de visualização é usá-las para contêineres de nível superior que ocupam espaço em relação ao tamanho da janela de visualização; não há cascata ou influência dos elementos pais envolvidos. Em contraste com %
, para unidades de janela de visualização, não importa onde na marcação o elemento a ser estilizado reside.
Portanto, 100vw
pode ser usado para seções de largura total, certo? Sim-mas com uma ressalva.
A border
e margin
do elemento não são consideradas, então como você pode ver no próximo exemplo, o recipiente do cabeçalho excede o janela de visualização do navegador e uma barra de rolagem horizontal é mostrada. O contêiner article resolve esse problema configurando a propriedade box-sizing
de seu valor padrão de content-box
para border-box
.
See the Pen
Viewport units demo by Sebastian Weber (@doppelmutzi)
on CodePen.
For the main container, we prevent this issue with another approach by using calc()
to subtract the border widths and margins on both sides.
If your use case is to get a full-width section, it’s easier to use the good old width: 100%
(the default with display: block
), as you can see in the footer container. Using width: 100%
is superior because older browsers can experience issues when scrollbars are shown.
A more beneficial use case is to use the vh
unit in relation to the height of the viewport. If you want to stretch a container to the height of the viewport, vh
is superior to %
because the latter relates to the parent. Thus, with the %
unit, you have to use fixed layout techniques to ensure the parent container fills the height of the viewport.
The following sticky footer example leverages vh
to have a component at the bottom of the viewport.
See the Pen
sticky footer with flexbox by Sebastian Weber (@doppelmutzi)
on CodePen.
Associated units are vmin
and vmax
:
20vmin
relates to20vw
or20vh
, whichever is smaller10vmax
relates to10vw
or10vh
, whichever is larger
Let’s rephrase the explanation: as an example, 10vmin
will resolve to 10 percent of the current viewport width in portrait orientations, and 10 percent of the viewport height on landscape orientations.
The following picture gives an example on how the final pixel value is calculated for both units.
What is it good for? Not many use cases come to mind — but it’s another tool in your bag as a web developer.
In some circumstances, it serves you better than media queries. With media queries, you have to think in “gates.” Due to the almost infinite number of devices and form factors, however, this approach does not always scale. You can think of vmin
and vmax
more as fluid length units.
When you search for use cases, you often come across responsive hero text components. The next CodePen demonstrates that vmin
improves the responsive behavior in contrast to vw
. In this case, the ratio of the text to the screen width in landscape mode is more coherent.
See the Pen
Hero text with vmin by Sebastian Weber (@doppelmutzi)
on CodePen.
Browser support is very good, even for Internet Explorer 9, except you want to use vmax
.
However, the devil’s in the details when it comes to mobile devices. The calculation especially of vh
is not consistent in all mobile browsers because the spec is vaguely formulated. There are some tricks to cope with it, however.
Common use cases
In this section, I want to show some responsive patterns that are possible by combining the different relative units.
Combining em
and rem
for local and global scaling
This CodePen by Chris Coyier impressively demonstrates, with the help of sliders, how rem
and em
can be leveraged for global (i.e., the whole website) and local (i.e., inside a module) scaling. This shows how you can build your layout with inclusive design in mind by reacting to the font size settings of the user.
See the Pen
Em AND Rem by Chris Coyier (@chriscoyier)
on CodePen.
There’s a subtle difference between this approach and the button example we discussed above. Using rem
values instead of px
values — and, in addition, not defining a fixed font-size
value for the root element — respects user font size settings to improve accessibility.
Full-width containers in limited-width parents
Consider a scenario in which the structure of the markup is not fully under your control. If you work with some kind of CMS, you may find yourself in a situation where you have a limited-width container, but you want to make children elements break out.
The next CodePen shows how to break out of a bounded container and span the entire horizontal space with the help of vw
.
See the Pen
Full-width containers in limited-width parents by Sebastian Weber (@doppelmutzi)
on CodePen.
The important code is part of the .break-out
selector. If you’re curious about the code, take a look at the following derivation of margin-left
:
.break-out { margin-left: calc(-100vw/2 + 500px/2);//500px because of the max width of the container margin-left: calc(-50vw + 50%);//replace 500px with 100% }
You can read detailed explanations with different scenarios and techniques at CSS-Tricks and Cloud Four.
Fluid typography
Let’s put it in a nutshell — most of the time, text content plays a very important part on the page. Due to the variety of screen sizes, fluid typography has grown more and more important.
Fluid typography that uses viewport units (vw
, vh
) dynamically adjusts the font size to the viewport. This leads to a more harmonic and suitable presentation in contrast to responsive typography based on breakpoints.
Here is a naive example:
h1 { font-size: 4vw; } p { font-size: 2vw; }
But wait — a better approach is to do the following:
html { font-size: 3vw; }
Why? Because we leverage the Browser’s default values with accessibility in mind. The HTML tags for h1
and p
are defined with relative font-size
values (em
), so you don’t have to think about relativity between paragraph text, headlines, etc. Of course, you can define your own font sizes if you wish to optimize your design.
But our approach has a problem: the font size is too tiny for small viewport widths.
So we need some lower and upper bounds so that the text neither shrinks nor grows too much for small or large screen widths, respectively. We can use media queries to define such boundaries, but then we wind up with these inharmonious jumps between the breakpoints.
A better approach is to omit media queries in the first place.
See the Pen
Fluid typography by Sebastian Weber (@doppelmutzi)
on CodePen.
The algorithm used in the CodePen above is based on the approach described by CSS-Tricks. Christine Vallaure does a nice job of explaining the rationale behind this algorithm.
html { font-size: calc([minimum size] + ([maximum size]-[minimum size]) * ((100vw-[minimum viewport width])/([maximum viewport width]-[minimum viewport width]))); }
Tim Brown also transfers the concept to fluid line-height
.
See the Pen
CSS calc lock for line-height by Tim Brown (@timbrown)
on CodePen.
Custom scroll indicator with vh
The following example shows a clever trick to combine %
with vh
units to create a pure CSS scroll indicator.
See the Pen
CSS only scroll indicator by Mike (@MadeByMike)
on CodePen.
Conclusão
Understanding relative units is key for fluid layouts or responsive designs (call it whatever you want) that enable CSS to cope with the virtually unlimited variety of viewport sizes and dpi.
Font-based units might feel odd at first, but after gaining some experience, you’ll recognize their benefit over absolute units. Viewport units, especially vh
, are useful, but it’s important to understand when to use them and when to use the good old %
data type.
An all-too-often overlooked aspect of developing websites is to make them accessible. By their very nature, these relative units respect user-specific font sizes and zoom settings.
There are more relative units on the horizon, but no browser currently supports them. Thankfully, we can already work very well with the current representatives.
The post Understanding relative CSS units appeared first on LogRocket Blog.