Tudo o que você precisa saber sobre a margem CSS

Uma das primeiras coisas que muitos de nós aprendemos quando aprendemos CSS foram os recursos dos vários elementos de um bloco em CSS, descritos como o "Modelo de Bloco CSS". Um dos elementos no modelo de bloco é a margem (margem externa), uma área transparente ao redor do bloco que repele outros elementos do conteúdo desse bloco. As propriedades margin-top , margin-right , margin-bottom e margin-left foram descritas desde CSS1, juntamente com a propriedade abreviada da margem para configuração simultânea nas quatro propriedades.

A margem parece bem direta, no entanto, neste artigo, examinaremos alguns pontos em que as pessoas se deparam ao usá-la. Em particular, como as margens interagem umas com as outras e como o colapso das margens externas realmente funciona.



Modelo de bloco CSS


Como em todos os artigos sobre os componentes do modelo de blocos CSS CSS, precisamos determinar o que queremos dizer com isso e como o modelo foi classificado em diferentes versões do CSS. O modelo de bloco refere-se a como os diferentes componentes do bloco - conteúdo (bloco), preenchimento (bloco), borda (quadro) e margem (bloco) - são localizados e interagem entre si. No CSS1, o modelo de bloco foi representado usando o diagrama ASCII mostrado na imagem abaixo.

Todas as quatro propriedades para cada lado do bloco e a propriedade abreviada da margem foram definidas no CSS1.

A especificação CSS2.1 tem uma ilustração para demonstrar o modelo de bloco e também define termos que continuamos a usar para descrever diferentes blocos. A especificação descreve caixa de conteúdo, caixa de preenchimento, caixa de borda e caixa de margem, cada uma das quais é definida pelas bordas de conteúdo, preenchimento, borda e margem, respectivamente.



Atualmente, há uma especificação para a versão do Modelo de Bloco 3 como um rascunho de trabalho. Ao definir o modelo e as margens do bloco, ele retorna ao CSS2, portanto, ao longo do artigo, usaremos a definição do CSS2.

Recolher margem


A especificação CSS1 definiu não apenas margens, mas também o colapso. Esse comportamento se tornou uma fonte de muitas decepções. O recolhimento de margem faz sentido quando você considera que, naqueles dias, o CSS era usado como uma linguagem de marcação para documentos de texto. Margem recolhida significa que, quando um cabeçalho com uma margem mais baixa é seguido por um parágrafo com uma margem superior, esses dois recuos não se somam, criando uma lacuna enorme entre os elementos.

Quando duas margens entram em colapso, o espaço entre os elementos se torna igual ao maior dos dois recuos. O recuo menor realmente termina dentro do maior

Margem em colapso nas seguintes situações:

  • Irmãos adjacentes (mãe solteira)
  • Blocos vazios
  • Pai e primeiro / último filho

Elementos de Enfermagem Adjacentes


Iniciarei a descrição com uma demonstração de como as margens colapsam entre irmãos adjacentes. Exceto como observado abaixo, se você tiver dois elementos exibidos um após o outro no fluxo normal, a margem inferior do primeiro elemento entrará em colapso com a margem superior do elemento subsequente.

No exemplo do CodePen abaixo, existem três elementos div . Para o primeiro elemento, as margens superior e inferior são 50px, para o segundo - 20px, para o terceiro - 3em. A margem entre os dois primeiros elementos é de 50px, uma vez que a margem inferior do elemento inferior é absorvida pela margem superior do elemento superior. A margem entre os dois segundos elementos é 3em, pois 3em é maior que 20 pixels na margem inferior do segundo elemento.


Blocos vazios


Se o bloco estiver vazio, sua margem superior e inferior poderão entrar em colapso. No exemplo a seguir do CodePen, o segundo elemento com a classe empty (não visível, porque está vazio) possui uma margem superior e inferior de 50px, no entanto, o espaço entre o primeiro e o terceiro elementos não é de 100 pixels, mas de 50. Isso é resultado do colapso de duas margens.

A adição de algo ao bloco (preenchimento uniforme) fará com que as margens superior e inferior sejam usadas, não recolhidas.


Pai e primeiro / último filho


Esse cenário de colapso da margem confunde as pessoas com mais frequência do que outras, pois não é intuitivo. No próximo CodePen, temos uma div com o wrapper classe (wrapper) e defino essa div propriedade outline de red, para que suas bordas possam ser vistas. Todos os três filhos têm uma margem de 50 pixels. No entanto, o primeiro e o último elementos são adjacentes às bordas do elemento wrapper; não há recuo de 50 pixels entre o elemento e o wrapper.


Isso ocorre porque a margem do filho entra em colapso com qualquer margem do pai, de forma que ela termine fora do pai. Você pode ver isso se testar a criança usando o painel do navegador do desenvolvedor. A área destacada em amarelo é a margem.



Recolher apenas margem


O exemplo final também destaca algo sobre o colapso da margem. No CSS2, apenas as margens verticais (superior e inferior) foram projetadas para colapsar. Portanto, no exemplo acima, as margens à esquerda e à direita não diminuem e terminam dentro do invólucro.

Nota: Vale lembrar que a margem diminui apenas na direção do bloco, por exemplo, entre parágrafos.

Prevenção de colapso


A margem não diminui se o elemento estiver definido como posicionamento absoluto ou a propriedade float . No entanto, se você estiver em uma situação em que a margem diminui, como isso pode ser evitado?

Margem em colapso não ocorre em uma situação em que algo está no meio.

Por exemplo, as margens superior e inferior de um bloco vazio não diminuem se o bloco estiver definido como uma borda ou preenchimento. No exemplo abaixo, adicionei um bloco de preenchimento de 1px. Agora, na parte superior e inferior do bloco, existe uma margem de 50px.


Essa é a lógica: se um bloco vazio não possui borda ou preenchimento, torna-se praticamente invisível. Por exemplo, pode ser um parágrafo vazio colocado na marcação do seu CMS. Se o seu CMS adicionou elementos de parágrafo redundantes, você provavelmente não gostaria que causassem um grande recuo entre outros parágrafos porque suas margens são levadas em consideração. Adicione algo ao bloco e obtenha esses recuos.

Comportamento semelhante pode ser visto com a margem do primeiro ou do último filho, cuja margem se estende além do pai. Se adicionarmos uma borda ao pai, a margem do filho permanecerá dentro.


E, novamente, há lógica nesse comportamento. Se você possui elementos de wrapper para fins semânticos que não são exibidos visualmente, provavelmente não deseja que eles criem recuo grande quando exibidos. Isso foi mais útil quando a web era principalmente texto. E esse comportamento é menos útil quando usamos elementos de layout.

Criando um "contexto de formatação de bloco"


O novo "Contexto de formatação de bloco" (BFC) impedirá que as margens caiam do elemento pai. Se olharmos novamente para o exemplo com o primeiro e o último filho cujas margens ficam fora dos limites do elemento wrapper e configuramos o wrapper para display: flow-root , criando assim BFC, a margem dos filhos permanecerá dentro.


Para saber mais sobre a display: flow-root , leia meu artigo " Entendendo o layout CSS e o contexto de formatação do bloco ". Alterar o valor da propriedade overflow para auto terá o mesmo efeito, pois também cria um novo BFC, embora possa levar a barras de rolagem que não são necessárias em certos casos

Contentores Flex e Grid


Os contêineres Flex e Grid definem o contexto de formatação Flex e Grid para filhos, para que eles tenham um comportamento de layout de bloco diferente. Uma dessas diferenças é que as margens não entram em colapso:
Um contêiner flexível define um novo contexto de formatação flexível para o conteúdo. É o mesmo que definir um contexto de formatação de bloco, exceto que a marcação flexível é usada em vez da marcação de bloco. Por exemplo, os carros alegóricos não funcionam dentro de um contêiner flexível e a margem de um contêiner flexível não entra em colapso com a margem dos elementos filho.
- Flexbox Nível 1
Se pegarmos o exemplo acima e empacotá-lo com um contêiner Flex, indicando a direção do eixo principal da coluna flex-direction:, fica claro que agora a margem dos filhos não vai além do empacotamento. Além disso, as margens entre os itens flexíveis adjacentes não diminuem; portanto, temos uma distância de 100 pixels entre os itens flexíveis, que é a soma das margens superior e inferior, com 50 px cada.


Estratégias de margem para o seu site


Devido ao colapso, uma boa solução seria oferecer uma maneira consistente de trabalhar com margem no seu site. A coisa mais simples que você pode fazer é estabelecer uma regra para definir margem apenas na parte superior ou inferior dos elementos. Nesse caso, você não deve encontrar problemas de recolhimento com muita frequência, pois o lado em que a margem está definida sempre será adjacente ao lado do outro elemento sem a margem.

Nota : Harry Roberts tem uma excelente publicação detalhando os motivos pelos quais definir margem em uma única direção é uma boa ideia, e não apenas por resolver problemas de colapso.

Essa abordagem não resolve o problema da margem cair dos elementos filhos além dos limites dos pais, que você pode encontrar. Esse problema em particular geralmente é menos comum e entender por que isso está acontecendo pode ajudar a encontrar uma solução. A solução ideal é definir os componentes que exigem a display: flow-root e com um fallback (fallback) para navegadores mais antigos, você pode usar o overflow para criar um BFC (contexto de formatação de bloco); transforme o pai em um recipiente flexível; ou mesmo defina o preenchimento para 1px. Lembre-se de que você pode usar a solicitação de suporte do navegador para propriedades para determinar se a propriedade display: flow-root é suportada, para que apenas navegadores mais antigos obtenham uma solução menos otimizada.

Acredito que, na maioria dos casos, entender por que as margens colapsam (ou não) é a chave. Isso permitirá que você determine como lidar com isso em cada caso. Seja qual for o método escolhido, compartilhe essas informações com sua equipe. Muitas vezes, o colapso da margem é um pouco misterioso; portanto, as maneiras de lidar com isso nem sempre são óbvias. Um comentário no seu código pode ser apropriado - você pode até incluir um link para este artigo e ajudar a compartilhar conhecimentos sobre o colapso da margem.

Decidi complementar este artigo com alguns dados adicionais relacionados à margem.

Margem de juros


Quando você usa porcentagens no CSS, deve ser porcentagens de alguma coisa. A margem (assim como o preenchimento) definida como uma porcentagem sempre será calculada em relação à largura do elemento pai. Isso significa que, ao usar porcentagens, você sempre terá margem igual de todos os lados ao redor do elemento.

No exemplo do CodePen abaixo, eu tenho um wrapper com uma largura de 200px, dentro do qual existe um bloco com margem = 10%. De todos os lados, a margem é de 20 px, ou seja, 10% de 200 px.


Margem em um mundo dependente de fluxo


Ao longo deste artigo, falamos sobre margens verticais; no entanto, o CSS moderno, via de regra, pensa na localização dos elementos em relação ao fluxo mais do que em relação aos lados físicos. Portanto, quando falamos em margens verticais, estamos falando de margens na dimensão do bloco. Essas margens podem ser superiores ou inferiores no modo de gravação horizontal ou direita ou esquerda no modo vertical.

Depois de trabalhar com direções lógicas relativas ao fluxo, fica mais fácil falar sobre o início e o fim do bloco do que sobre o topo e o fundo. Para facilitar isso, uma especificação de Propriedades e Valores Booleanos foi introduzida no CSS. Ele substitui propriedades físicas por propriedades relacionadas ao fluxo.

Se falarmos de margem, isso nos dará as seguintes alternativas (se trabalharmos com inglês ou qualquer outro modo gravado horizontalmente com a direção do texto da esquerda para a direita).

  • margin-top = margin-block-start
  • margin-right = margin-inline-end
  • margin-bottom = margin-block-end
  • margin-left = margin-inline-start

Também temos duas novas propriedades abreviadas:

  • bloqueio de margem
  • margem em linha

No exemplo a seguir do CodePen, usei palavras-chave relacionadas ao fluxo e alterei o modo de ortografia do bloco. Você pode ver como as margens seguem o fluxo de texto, em vez de serem vinculadas aos lados físicos.


Você pode ler mais sobre propriedades e valores lógicos no MDN ou no meu artigo, Noções básicas sobre propriedades e valores lógicos , na Smashing Magazine.

Em conclusão


Agora você já sabe o que deve saber sobre margem. Resumidamente:

  • A margem pode entrar em colapso. A compreensão de quando isso acontece e quando não o ajudará a resolver quaisquer problemas que eles possam criar.
  • Instalar a margem em apenas uma direção resolve muitos problemas associados a elas.
  • Como em qualquer situação de CSS, compartilhe as decisões que você toma com sua equipe e comente seu código
  • Levar em consideração as medições de blocos e linhas, em vez dos lados físicos, superior, direito, inferior e esquerdo, ajudará você, pois a web está se movendo para se tornar independente do modo de escrita

Source: https://habr.com/ru/post/pt465839/


All Articles