Técnicas CSS para elementos de cobertura

Veja algumas técnicas possível para fazer elementos de cobertura (cobrir um elemento com outro) através de utilitários CSS.

Ir para o artigo

Em muitos projetos, é preciso usar o CSS para fazer elementos de cobertura (cobrir um elemento com outro). Veja algumas técnicas possível para alcançar este efeito através de utilitários CSS.

Quadrado listrado representando um elemento de cobertura CSS (seu código será mostrado mais à frente).

Aqui está algo que é bastante comum de se fazer repetidamente em CSS: “cobrir” completamente um elemento com outro — daí o nome elemento de cobertura. :)

É sempre o mesmo CSS: o primeiro elemento (aquele que precisa ser coberto) tem position: relative aplicada a ele; o segundo, position: absolute e é posicionado de forma que todos os quatro lados se alinhem às bordas do primeiro elemento.

O CSS completo se parece com:

Freqüentemente, é um título (title) ou legenda (caption) que precisa cobrir uma imagem; às vezes, com uma cor de fundo translúcida ou gradiente — isso também é chamado de sobreposição. Normalmente, é um filho direto do primeiro elemento que está sendo sobreposto, mas nem sempre.

Às vezes, é necessário sobrepor um pseudo-elemento, talvez até fazer a transição ou animá-lo para um estado de foco. De qualquer maneira, isso é feito com tanta frequência, que é totalmente legítimo criar uma classe de utilitário para ajudar, em vez de escrever as propriedades CSS à mão todas as vezes.

Classes de utilidade (ou utilitárias) para elementos de cobertura

Já citamos algumas vezes classes utilitário aqui no dpw — por exemplo, em nossa live sobre Namespaces CSS. Tratam-se classes que devem ter um e somente um propósito e que podem ser aplicadas em diversos elementos.

Por exemplo, é possível ter uma classe de alinhamento centralizado de texto:

Então, sempre que for necessário que um elemento tenha texto centralizado, ao invés de colocar a propriedade e o valor, utiliza-se essa classe — ou, caso a stack do projeto conte com pré-processador de CSS, ela é estendida.

É possível usar classes de utilitários de diversas maneiras, desde as mais insanas (como é feito no Tailwind), até as mais normais, com parcimônia e na medida em que o projeto as demanda.

E uma utilty class não precisa, necessariamente, se ater a somente uma propriedade CSS. Pensando em uma classe de utilitário para elemento sobreposto, esta incluiria várias propriedades.

Por exemplo, um utilitário desta natureza poderia ser algo como:

Embora seja muito flexível como um utilitário, usar position: absolute define a posição do elemento em relação ao ancestral de posição relativa mais próximo, então é preciso lembrar de definir position: relative ao elemento que se quer cobrir (e garantir que seja um ancestral do elemento de cobertura).

Na maioria dos casos, o elemento que se usa como uma sobreposição é um filho direto ou um pseudo-elemento, portanto, pode fazer sentido criar mais utilitários para aplicar nesses casos, o que significa que não é preciso definir position: relative.

Qualquer uma dessas 3 classes pode, ao invés disso, ser aplicada ao elemento-pai (ou seja, o elemento original que é preciso cobrir):

Agora existem 3 utilitários para se aplicar adicionalmente quando é necessário direcionar o elemento que está fazendo a cobertura:

  • overlay-child (para posicionar um elemento-filho direto)
  • overlay-before (para posicionar um pseudo-elemento ::before)
  • overlay-after (para posicionar um pseudo-elemento ::after)

Um exemplo de quando é possível usar a sobreposição em vez de uma das classes de segmentação de pais é se o elemento de cobertura não for um filho direto, mas um descendente mais abaixo na árvore DOM.

See the Pen Overlay utility classes by Michelle Barker (@michellebarker) on CodePen.

Dica bônus: pegar o elemento-pai mais próximo com JavaScript

Já que estamos no assunto de diferentes técnicas CSS para elementos de cobertura, quando é preciso lidar com componentes complexos e posicionamento absoluto, um position: relative maroto às vezes pode ser a causa de bugs de layout.

Para debugar, geralmente é necessário encontrar o ancestral em posição relativa mais próximo do elemento em posição absoluta que está causando problemas. Felizmente, é possível usar um pouquinho de JavaScript para ajudar.

Nas DevTools do Chrome e Firefox, digitar $0 no console retornará o elemento atualmente selecionado. Se usar $0.offsetParent, o ancestral posicionado mais próximo do elemento atualmente selecionado será retornado.

Então, é possível verificar se ele tem position: relative pelo painel Styles — ou através de JavaScript, com getComputedStyle($0.offsetParent).position.

CSS Logical Properties

Posicionar um elemento dessa maneira está prestes a se tornar mais conciso com a ajuda da nova propriedade CSS inset. Parte da especificação CSS Logical Properties, inset é efetivamente uma abreviação para as propriedades de posicionamento top, right, bottom, left.

Também há novas propriedades lógicas, que permitem alcançar algo parecido: inset-block-start, inset-block-end, inset-inline-start e inset-inline-end. Para o modo de escrita (writing mode) padrão da esquerda para a direita (left-to-right), isso será mapeado para top, bottom, left, right, nessa ordem.

Mas outros modos de escrita (bem como a propriedade direction) farão com que os valores sejam mapeados de forma diferente. No momento, porém, é preciso apenas da propriedade inset para o utilitário do elemento de cobertura.

Voltando ao código, ele poderia ser refatorado de:

Para:

Fazendo do código menor e igualmente eficiente:

Suporte cross-browser

No momento da publicação deste artigo, inset já tem um suporte cross-browser (moderno) bastante amplo, portanto, você já pode começar a pensar em usar a nova propriedade CSS em produção — dependendo do caso, forneça um fallback para navegadores sem suporte.

Método alternativo para elementos de cobertura: CSS Grid

Algo interessante é que não necessariamente é preciso usar posicionamento absoluto: o utilitário CSS para cobertura de elementos também pode ser feito ao usar CSS Grid para cobrir um elemento com outro!

O código (mais enxuto, inclusive) é parecido com:

Se a sobreposição for o único elemento filho, não é preciso nem definir a grid area, mas nada impede prevenir para o caso de ser preciso adicionar outros elementos-filho — caso contrário, seria arriscado acontecer algum efeito colateral quando os itens são colocados automaticamente na grid.

Eis um demo com a técnica usando CSS Grid:

See the Pen Overlay utility classes with Grid by Michelle Barker (@michellebarker) on CodePen.

Conclusão

Usar utilitário CSS é uma técnica já conhecida. Existem maneiras de otimizar seu entendimento e eficiência, mas sua intenção de uso fica bem clara.

Quando se deparar com casos de CSS em que seja necessário repetir muitas vezes as mesmas propriedades, é interessante ponderar a respeito do uso de utilitários CSS.

Um dos casos, abordados no artigo, é sobre criar utilitários que tratam elementos de cobertura usando diferentes técnicas. A depender do projeto, pode ser uma bela adição às folhas de estilo.

Usamos cookies para melhorar sua experiência e para ajudar a entender como nosso site é usado. Ao utilizar este site, você aceita o uso de cookies. Consulte nossa política de privacidade para obter mais informações.