About CSS margin, some points that make you fuzzy

Time:2020-4-9

Original: https://www.smashingmagazine
Translator: front-end wit

In order to ensure readability, this paper adopts free translation instead of literal translation.

In order to give back to the readers, Daqian world is held irregularly (once or three times a month), with a cash lottery, a minimum of 200, and users’ appreciation. I hope you can become the little Koi of Daqian world. Come and have a try

When we learn CSS, the first thing most of us learn is the details of each part of the box in CSS, which is called CSS box and model. One of the elements in the box model ismargin, the transparent area around the box that pushes other elements away from the contents of the box.

CSS1 describesmargin-topmargin-rightmargin-bottomandmargin-leftProperties, and shorthand all four properties at oncemargin

marginIt may seem like a fairly simple thing, but in this article, we’ll look at some of the examples in usemarginSome are confusing and interesting. Especially,marginHow they interact, andmarginOverlapping effect.

If you want to read more high-quality articles, please jab GitHub blog, more than 100 high-quality articles a year are waiting for you!

CSS box model

CSS box model refers to all parts of a box——contentpaddingborderandmargin, how they were laid out and interacted before, as follows:

About CSS margin, some points that make you fuzzy

Four of the boxesmarginAttribute andmaringAbbreviations are defined in CSS1.

The css2.1 specification has an illustration of a demo box model and defines terms to describe various boxes, includingcontent boxFill inpadding boxborder boxandmargin box

About CSS margin, some points that make you fuzzy

There is now a draft of the level 3 box model specification. This specification refers to CSS2 as the box model andmarginSo we’ll use CSS2 definitions for most of this article.

Margin overlap

The CSS1 specification definesmargin, also defines the verticalmarginOverlap. If you consider that in the early days, CSS was used as a document format language, thenmarginOverlap makes sense. Margin overlap means that when one has a bottommarginThe title is followed by a topmarginThere will be no large gaps between them.

When twomarginWhen overlaps occur, they will be combined and the space between the two elements will be the larger one. SmallermarginIn the larger one.

Margin overlaps when:

  • Next door siblings
  • Completely empty box
  • Parent and first or last child

Take a look at these scenes in turn.

Next door siblings

YesmarginThe initial description of the overlap is to demonstrate the relationship between siblingsmarginHow it overlaps. In addition to the cases mentioned below, if there are two elements in the normal flow, then the bottom of the first elementmarginWill be associated with the top of the following elementsmarginOverlap together.

In the following example, there are threedivElement. FirstdivTop and bottommarginAll are50px。 The seconddivTop and bottom ofmarginAll are20px。 ThirddivTop and bottom ofmarginAll are3em。 Between the first two elementsmarginyes50pxBecause of the smaller topmarginAnd the larger bottommarginCombine. The margin between the second and third elements is3emBecause3emGreater than the bottom of the second elementmargin 20px。

html

<div class="wrapper">

<div class="box example1">
  margin-top: 50px; margin-bottom: 50px;
</div>

<div class="box example2">
  margin-top: 20px; margin-bottom: 20px;
</div>

<div class="box example3">
  margin-top: 3em; margin-bottom: 3em;
</div>
  
</div>

css

.wrapper {
  border: 5px dotted black;
}

.example1 {
  margin: 50px 0 50px 0;
}

.example2 {
  margin: 20px 0 20px 0;
}

.example3 {
  margin: 3em 0 3em 0;
}

body {
  font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
  margin: 2em 3em;
}

.box {
  background-color: rgb(55,55,110);
  color: white;
  padding: 20px;
  border-radius: .5em;
}

Operation effect:

About CSS margin, some points that make you fuzzy

Completely empty box

If a box is empty, its top and bottommarginMay overlap. In the following example,classbyemptyTop and bottom ofmarginEach is50px, but between the first and the thirdmarginNo100pxInstead,50px。 This is due to twomarginOverlap. If you put content in an empty box, it will stopmarginAmalgamation.

html

div class="wrapper">

<div class="box">
  A box
</div>

<div class="box empty"></div>

<div class="box">
  Another box
</div>
  
</div>

css

.wrapper {
  border: 5px dotted black;
}

body {
  font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
  margin: 2em 3em;
}

.box {
  background-color: rgb(55,55,110);
  color: white;
  border-radius: .5em;
}

.empty {
  margin: 50px 0 50px 0;
}

Operation effect:

About CSS margin, some points that make you fuzzy

Parent and first or last child

Margin overlap is a surprise because it’s sometimes not intuitive. In the following example, there is a class namedwrapperOfdiv, give this div a red oneoutline, so you can see where it is.

thisdivOf the three sub elementsmarginAll are50px。 But you’ll find that the actual effect is the first and last with the parent elementmarginFlush, as if there is no50pxOfmarginSame.

html

<div class="wrapper">

<div class="box">
  Item 1
</div>

<div class="box">
  Item 2
</div>

<div class="box">
  Item 3
</div>
  
</div>

css

.wrapper {
  outline: 1px solid red;
}

.box {
  margin: 50px;
}

body {
  font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
  margin: 2em 3em;
}

.box {
  background-color: rgb(55,55,110);
  color: white;
  padding: 20px;
  border-radius: .5em;
}

Operation effect:

About CSS margin, some points that make you fuzzy

This is because of themarginWill follow any side of the parent nodemarginThey overlap each other so that they end up outside the parent node. If you use devtools to check the first child element, you can see that the yellow area ismargin

About CSS margin, some points that make you fuzzy

Only block element margin overlaps

In CSS2, only themarginOverlap, that is, the top and bottom margin of the element. As a result, the top left and right margins do not overlap.

It’s worth noting that margin only overlaps in the direction of the block, such as between paragraphs.

Prevent margin overlap

If an element is absolutely positioned, or floating, itsmarginNever overlap. However, assuming you’ve encountered several situations in the above example, how can you prevent margin overlap?

For example, a completely empty box, if it hasborderorpadding, it’s up and downmarginThere will be no overlap. In the following example, 1px is added to the empty boxpadding。 Now there is one above and one below the empty box50pxOfmargin

html

<div class="wrapper">

<div class="box">
  A box
</div>

<div class="box empty"></div>

<div class="box">
  Another box
</div>
  
</div>

css

.wrapper {
  border: 5px dotted black;
}

body {
  font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
  margin: 2em 3em;
}

.box {
  background-color: rgb(55,55,110);
  color: white;
  border-radius: .5em;
}

.empty {
  margin: 50px 0 50px 0;
  padding: 1px;
}

Operation effect:

About CSS margin, some points that make you fuzzy

There is logic behind this. If the box is completely empty, there is noborderorpadding, which is basically invisible. It may be a paragraph element marked empty in CMS. If you add extra paragraph elements to your CMS, you may not want them to create large gaps between other paragraphs. In this case, margin overlap has a certain significance.

If the parent element overlaps the first or last child element margin, if we addborder, then themarginIt will remain inside.

...
.wrapper {
  border: 5px dotted black;
}
...


About CSS margin, some points that make you fuzzy

Similarly, this kind of behavior has certain logic. If you wrap elements for semantic purposes, but they don’t appear on the screen, you may not want them to introduce largemargin。 This makes sense when the web is primarily text. When we use elements to lay out a design, its overlapping behavior doesn’t make much sense.

Create format context (BFC)

BFC (block formatting context) formatting context, is the CSS rendering mode of the box model layout in the web page, which refers to an independent rendering area or an isolated independent container.

BFC can prevent the overlap of margins. If we look at the example of the parent element and the first or last child element, we can adddisplay: flow-rootA new BFC will be created to preventmarginmerge

...
.wrapper {
  outline: 1px solid red;
  display: flow-root;
}
...


About CSS margin, some points that make you fuzzy

display: flow-rootIt is a new property of CSS3, which is used to create a BFC without side effects. takeoverflowProperty is set toautoThe same effect can be achieved because this also creates a new BFC, although it may also create scrollbars that are not needed in some scenes.

Flex and grid containers

flexandgridContainer for its child elementsflexandgridFormat the context so they can also preventmarginOverlap.

Take the example above to use flex layout instead of wrapper:


...
.wrapper {
  outline: 1px solid red;
  display: flex;
  flex-direction: column;
}
...


About CSS margin, some points that make you fuzzy

Website Margin Policy

BecausemarginIt will overlap. It is better to find a consistent way to deal with the websitemargin。 The easiest way is to define only at the top or bottom of an elementmargin。 In this way, we seldom encounter the problem of overlapping margin, because there aremarginThe edge of is always with nomarginThe edges of are adjacent.

This solution does not solve the problem you may encounter because of themarginWill overlap with the parent element. This particular problem is often less common, but knowing why it happens can help you come up with a solution.

An ideal solution for this is to set the elementdisplay: flow-root, but some browsers do not support it. You can useoverflowEstablishBFC, or set the parent element toflexContainer, of course, can also be setpaddingTo solve this problem.

Percentage margin

When you use percentage in CSS, it must be a percentage of an element. Margin (or padding) set with percentage is always a percentage of the inline size (width in horizontal write mode) of the parent element. This means that when using percentages, thepaddingThey are all the same size.

In the following example, there is a 200px wide d when, which is a class namedboxOfdivItsmarginThe value is10%That is to say20px (200*10%)。

html

 <div class="wrapper">
  <div class="box">
    I have a margin of 10%.
  </div>
</div>

css

 * {
  box-sizing: border-box;
}

.wrapper {
  border: 5px dotted black;
  width: 200px;
}

.box {
  background-color: rgb(55,55,110);
  color: white;
  padding: 20px;
  border-radius: .5em;
  margin: 10%;
}

body {
  font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
  margin: 2em 3em;
}


About CSS margin, some points that make you fuzzy

We’ve been talking about vertical margin in this article, but modern CSS tends to think about things in terms of flow rather than physics. So when we talk about vertical margins, we’re actually talking about the margins of the block dimension. If we are in the level writing mode, thesemarginWill be top and bottom, but in vertical writing mode, thesemarginIt will be right and left.

Once logical, flow related directions are used, it is easier to discuss the beginning and end of a block, rather than the top and bottom of the block. To simplify this process, CSS introduces logical properties and value specifications. This maps the relevant properties of the flow to physical properties.

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

There are also two new shortcut keys that can set two blocks or two inner blocks at the same time.

  • margin-block
  • margin-inline

In the following example, you use these flow related keywords, and then change the writing mode of the box, as you can seemarginHow to follow the text direction:

html

<div class="wrapper horizontal-tb">
  <div class="box">
    A box with a horizontal-tb writing mode.
  </div>
</div>

<div class="wrapper vertical-rl">
  <div class="box">
    A box with a vertical-rl writing mode.
  </div>
</div>

css

* {
  box-sizing: border-box;
}

.wrapper {
  border: 5px dotted black;
  inline-size: 200px;
}

.horizontal-tb {
  writing-mode: horizontal-tb;
  margin-bottom: 1em;
}

.vertical-rl {
  writing-mode: vertical-rl;
}

.box {
  background-color: rgb(55,55,110);
  color: white;
  padding: 20px;
  border-radius: .5em;
  margin-block-start: 30px;
  margin-block-end: 10px;
  margin-inline-start: 2em;
  margin-inline-end: 5%;
}

body {
  font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif;
  margin: 2em 3em;
}

About CSS margin, some points that make you fuzzy

For more information, read more about logical properties and values on MDN.

The bugs that may exist after the code is deployed cannot be known in real time. In order to solve these bugs afterwards, a lot of time has been spent on log debugging. In this way, we recommend a good bug monitoring tool fundebug.

Communication

The articles of dry goods series are summarized as follows. I think it’s a good idea to order a star. Welcome to learn from each other.

https://github.com/qq44924588…

I am the little wisdom, the official account of “the great migration to the world”.Keep learning enthusiasts for front-end technology. I will often share what I have learned and seenOn the way to the advanced stage, encourage!

Pay attention to official account, background replywelfare, you can see the benefits, you know.

About CSS margin, some points that make you fuzzy