问题
Intuitively, the space or wrap will be ignored between two block tag though we code it with the space. As follow figure:
foo
foo
As we know, spaces will be collapsed as one space between two inline element. So what's the rule in block element? Is it really ignored by browser?
解决方法In a block formatting context, boxes are laid out one after the other, vertically, beginning at the top of a containing block. The vertical distance between two sibling boxes is determined by the 'margin' properties. Vertical margins between adjacent block-level boxes in a block formatting context collapse.
So only margin can adjust distance between two block elements but let's don't forget Anonymous block boxes which is very important here and probably the anwser to your question.
Let's take this example:
.b {
border:1px solid;
height:50px;
}
some text
Between the two block level we have an Anonymous block formed by the text like explained in the specification. We will end with 3 block: the two divs + the anonymous one created that contain the text.
This will not happen when having only collapsible whitespace (i.e. U+0020)1. So there is no Anonymous block created in your example between the two blocks.
Below an example where I used a non collapsible whitespace (zero width character U+200B) where you will see a space between block elements because an anonymous block is created containing that invisible charater. Again a third block is in play here. Technically the space we see is that invisible block and between the invisible block and the two others there is no space.
.b {
border:1px solid;
height:50px;
}
body {
animation:change 2s linear infinite;
}
@keyframes change {
from {
font-size:16px;
}
to {
font-size:36px;
}
}
You can clearly notice how increasing the font-size will increase the distance because we are increasing the font of the invisible character inside our anonymous block which become bigger pushing the bottom one.
Below another way to illustrate where the red div is replacing our anonymous block where I placed the invisible character:
.b {
border:1px solid;
height:50px;
}
.anonymous {
background:red;
}
body {
animation:change 2s linear infinite;
}
@keyframes change {
from {
font-size:16px;
}
to {
font-size:36px;
}
}
Compared to collpasible white spaces no Anonymous block is created and nothing will separate our block elements. No third block will be created and only margin can change the spacing:
.b {
border:1px solid;
height:50px;
}
body {
animation:change 2s linear infinite;
}
@keyframes change {
from {
font-size:16px;
}
to {
font-size:36px;
}
}
The default behavior may also be changed if we adjust white-space property that control how spaces should or shouldn't collapse.
.b {
border:1px solid;
height:50px;
}
div {
white-space:pre;
}
1You can find more details about the white-space algorithm following this link: https://www.w3.org/TR/CSS2/text.html#white-space-prop
Below the relevant part related to the initial example where all the spaced get removed:
As each line is laid out,
If a space (U+0020) at the beginning of a line has 'white-space' set to 'normal', 'nowrap', or 'pre-line', it is removed.
All tabs (U+0009) are rendered as a horizontal shift that lines up the start edge of the next glyph with the next tab stop. Tab stops occur at points that are multiples of 8 times the width of a space (U+0020) rendered in the block's font from the block's starting content edge.
If a space (U+0020) at the end of a line has 'white-space' set to 'normal', 'nowrap', or 'pre-line', it is also removed.
If spaces (U+0020) or tabs (U+0009) at the end of a line have 'white-space' set to 'pre-wrap', UAs may visually collapse them.