aguarde...

20 de maio de 2020

Como domar a altura da linha em CSS

Como domar a altura da linha em CSS

No CSS, line-heighté provavelmente um dos atributos mais incompreendidos, porém mais usados. Como designers e desenvolvedores, quando pensamos line-height, podemos pensar no conceito de liderar a partir do design de impressão – um termo, curiosamente, que vem literalmente da colocação de peças de chumbo entre linhas de tipo. 

Liderar e line-height, por mais semelhante que seja, tem algumas diferenças importantes. Para entender essas diferenças, primeiro precisamos entender um pouco mais sobre tipografia. 

#Uma visão geral dos termos de tipografia

No design tradicional do tipo ocidental, uma linha de texto é composta por várias partes: 

  • Linha de base: esta é a linha imaginária na qual o tipo fica. Quando você escreve em um caderno de anotações, a linha de base é a linha na qual você escreve.
  • Descender: Esta linha fica logo abaixo da linha de base. É a linha que alguns personagens – como minúsculas gjqyp  – toque abaixo da linha de base. 
  • Altura X: é (sem surpresa) a altura de uma letra minúscula normal xem uma linha de texto. Geralmente, essa é a altura de outras letras minúsculas, embora algumas possam ter partes de seus caracteres que excederão a altura x. Para todos os efeitos, ele serve como a altura percebida das letras minúsculas.
  • Altura máxima : é a altura da maioria das letras maiúsculas em uma determinada linha de texto.
  • Ascendente: uma linha que muitas vezes aparece logo acima da altura da tampa, onde alguns caracteres, como letras minúsculas hou bpodem exceder a altura normal da tampa.
Como domar a altura da linha em CSS

Cada uma das partes do texto descritas acima é intrínseca à própria fonte. Uma fonte é projetada com cada uma dessas partes em mente; no entanto, existem algumas partes da tipografia que são deixadas para o criador de tipos (como você e eu!), e não para o designer. Um deles é líder.

Leading é definido como a distância entre duas linhas de base em um conjunto de tipos.

Como domar a altura da linha em CSS

Um desenvolvedor de CSS pode pensar: “OK, liderar é a altura da linha, vamos seguir em frente”. Embora os dois estejam relacionados, eles também são diferentes em alguns aspectos muito importantes.

Vamos pegar um documento em branco e adicionar um “CSS reset” clássico :

* {
  margin: 0;
  padding: 0;
}

Isso remove a margem e o preenchimento de cada elemento.

Também usaremos o Lato do Google Fonts como nosso font-family.

Vamos precisar de algum conteúdo, então vamos criar uma <h1>tag com algum texto e definir o valor line-heightcomo algo irritante, como 300px. O resultado é uma única linha de texto com uma quantidade surpreendente de espaço acima e abaixo da única linha de texto.

Quando um navegador encontra a line-heightpropriedade, o que realmente faz é pegar a linha de texto e colocá-la no meio de uma “caixa de linha” que possui uma altura correspondente à altura da linha do elemento. Em vez de definir o líder em uma fonte, temos algo parecido com o preenchimento de um dos lados da caixa de linha.

Como domar a altura da linha em CSS

Como ilustrado acima, a caixa de linha envolve uma linha de texto onde a liderança é criada usando espaço abaixo de uma linha de texto e acima da próxima. Isso significa que, para cada elemento de texto em uma página, haverá metade dos líderes acima da primeira linha de texto e após a última linha de texto em um bloco de texto específico.

O que pode ser mais surpreendente é que ajustar explicitamente a line-heightfont-sizeem um elemento com o mesmo valor vai deixar espaço extra acima e abaixo do texto. Podemos ver isso adicionando uma cor de fundo aos nossos elementos.

Isso ocorre porque, embora font-sizeesteja definido como 32px, o tamanho real do texto é algo menor que esse valor, devido ao espaçamento gerado.

#Conseguir que o CSS trate a altura da linha como líder

Se quisermos que o CSS use um estilo de configuração de tipo mais tradicional em vez da caixa de linha, queremos que uma única linha de texto não tenha espaço acima ou abaixo dele – mas permita que elementos de várias linhas mantenham todo o seu line-heightvalor. 

É possível ensinar CSS sobre liderança com um pouco de esforço. Michael Taranto lançou uma ferramenta chamada Basekick que resolve esse problema. Isso é feito aplicando uma margem superior negativa ao ::beforepseudoelemento e translateYa ao próprio elemento. O resultado final é uma linha de texto sem espaço extra ao seu redor.

A versão mais atualizada da fórmula do Basekick pode ser encontrada no código-fonte do Braid Design System da SEEK . No exemplo abaixo, estamos escrevendo um mix Sass para fazer o trabalho pesado para nós, mas a mesma fórmula pode ser usada com JavaScript, Less, mix PostCSS ou qualquer outra coisa que forneça esses tipos de recursos matemáticos.

@function calculateTypeOffset($lh, $fontSize, $descenderHeightScale) {
  $lineHeightScale: $lh / $fontSize;
  @return ($lineHeightScale - 1) / 2 + $descenderHeightScale;
}


@mixin basekick($typeSizeModifier, $baseFontSize, $descenderHeightScale, $typeRowSpan, $gridRowHeight, $capHeight) {
  $fontSize: $typeSizeModifier * $baseFontSize;
  $lineHeight: $typeRowSpan * $gridRowHeight;
  $typeOffset: calculateTypeOffset($lineHeight, $fontSize, $descenderHeightScale);
  $topSpace: $lineHeight - $capHeight * $fontSize;
  $heightCorrection: 0;
  
  @if $topSpace > $gridRowHeight {
    $heightCorrection: $topSpace - ($topSpace % $gridRowHeight);
  }
  
  $preventCollapse: 1;
  
  font-size: #{$fontSize}px;
  line-height: #{$lineHeight}px;
  transform: translateY(#{$typeOffset}em);
  padding-top: $preventCollapse;


  &::before {
    content: "";
    margin-top: #{-($heightCorrection + $preventCollapse)}px;
    display: block;
    height: 0;
  }
}

À primeira vista, esse código definitivamente se parece com muitos números mágicos. Mas pode ser decomposto consideravelmente ao pensar no contexto de um sistema específico. Vamos dar uma olhada no que precisamos saber:

  • $baseFontSize: É o normal font-sizepara o nosso sistema em torno do qual tudo o mais será gerenciado. Usaremos 16px como valor padrão.
  • $typeSizeModifier: Este é um multiplicador usado em conjunto com o tamanho da fonte base para determinar a font-sizeregra. Por exemplo, um valor 2 associado ao tamanho da fonte base de 16px nos fornecerá font-size: 32px.
  • $descenderHeightScale: Esta é a altura do descendente da fonte expressa como uma proporção. Para Lato, isso parece estar em torno de 0,11.
  • $capHeight: Esta é a altura do limite específico da fonte, expressa como uma proporção. Para Lato, isso é cerca de 0,75.
  • $gridRowHeight: Os layouts geralmente baseiam-se em um ritmo vertical padrão para proporcionar uma experiência de leitura agradável e consistentemente espaçada. Por exemplo, todos os elementos em uma página podem ser espaçados em múltiplos de quatro ou cinco pixels. Usaremos 4 como valor, pois ele se divide facilmente em nosso $ baseFontSize de 16px.
  • $typeRowSpan: Como $typeSizeModifieressa variável serve como um multiplicador a ser usado com a altura da linha da grade para determinar o line-heightvalor da regra . Se a altura da linha da grade padrão for 4 e o intervalo de linhas do tipo for 8, isso nos deixará com a altura da linha: 32px.

Agora podemos conectar esses números à fórmula do Basekick acima (com a ajuda das funções e mixins do SCSS) e isso nos dará o resultado abaixo.

É exatamente isso que estamos procurando. Para qualquer conjunto de elementos do bloco de texto sem margens, os dois elementos devem colidir um com o outro. Dessa forma, todas as margens definidas entre os dois elementos serão perfeitas em pixels, porque não estarão lutando com o espaçamento da caixa de linha.

#Refinando nosso código

Em vez de despejar todo o nosso código em uma única combinação SCSS, vamos organizá-lo um pouco melhor. Se estamos pensando em termos de sistemas, notamos que existem três tipos de variáveis ​​com as quais estamos trabalhando:

Tipo de variávelDescriçãoVariáveis ​​Mixin
Nível do sistemaEsses valores são propriedades do sistema de design com o qual estamos trabalhando.$baseFontSize
$gridRowHeight
Nível da fonteEsses valores são intrínsecos à fonte que estamos usando. Pode haver algumas suposições e ajustes envolvidos para obter os números perfeitos.$descenderHeightScale
$capHeight
Nível da regraEsses valores serão específicos da regra CSS que estamos criando$typeSizeMultiplier
$typeRowSpan

Pensar nesses termos nos ajudará a dimensionar nosso sistema muito mais facilmente. Vamos levar cada grupo por sua vez.

Primeiro, as variáveis ​​no nível do sistema podem ser definidas globalmente, pois é improvável que sejam alteradas durante o curso do nosso projeto. Isso reduz o número de variáveis ​​em nosso mixin principal para quatro:

$baseFontSize: 16;
$gridRowHeight: 4;

@mixin basekick($typeSizeModifier, $typeRowSpan, $descenderHeightScale, $capHeight) {
  /* Same as above */
}

Também sabemos que as variáveis ​​no nível da fonte são específicas para sua família de fontes. Isso significa que seria fácil criar uma combinação de ordem superior que as defina como constantes:

@mixin Lato($typeSizeModifier, $typeRowSpan) {
  $latoDescenderHeightScale: 0.11;
  $latoCapHeight: 0.75;
  
  @include basekick($typeSizeModifier, $typeRowSpan, $latoDescenderHeightScale, $latoCapHeight);
  font-family: Lato;
}

Agora, como regra, podemos chamar o Latomixin com pouco barulho:

.heading--medium {
  @include Lato(2, 10);
}

Essa saída nos fornece uma regra que usa a fonte Lato com font-size32px e line-height 40px com todas as conversões e margens relevantes. Isso nos permite escrever regras de estilo simples e utilizar a consistência da grade que os designers estão acostumados ao usar ferramentas como Sketch e Figma.

Como resultado, podemos criar facilmente designs perfeitos para pixels com pouco esforço. Veja como o exemplo se alinha à nossa grade básica de 4px abaixo. Você provavelmente precisará aumentar o zoom para ver a grade.

Fazer isso nos dá uma superpotência única quando se trata de criar layouts em nossos sites: pela primeira vez na história, podemos criar páginas perfeitas em pixels. Associe essa técnica a alguns componentes básicos de layout e podemos começar a criar páginas da mesma maneira que em uma ferramenta de design.

#Movendo-se para um padrão

Embora ensinar CSS a se comportar mais como nossas ferramentas de design exige um pouco de esforço, há potencialmente boas notícias no horizonte. Uma adição à especificação CSS foi proposta para alternar esse comportamento nativamente. A proposta, como está agora, adicionaria uma propriedade adicional aos elementos de texto semelhantes a line-height-trimou leading-trim

Uma das coisas surpreendentes sobre as linguagens da web é que todos temos a capacidade de participar. Se isso parece um recurso que você gostaria de ver como parte do CSS, você pode entrar e adicionar um comentário a esse tópico para permitir que sua voz seja ouvida.

Posted in Blog
Write a comment