- commit
- 4fb09ca7203f0e03ab6ed40f7f798257f68e8890
- parent
- 63b317a6f02ca42712995a97c840bd128c42f2b9
- Author
- Tobias Bengfort <tobias.bengfort@posteo.de>
- Date
- 2024-04-24 12:02
add post on margin collapsing
Diffstat
A | _content/posts/2024-04-24-margin-collapsing/01-defaults-combined.png | 0 | |
A | _content/posts/2024-04-24-margin-collapsing/02-bottom-combined.png | 0 | |
A | _content/posts/2024-04-24-margin-collapsing/03-top-combined.png | 0 | |
A | _content/posts/2024-04-24-margin-collapsing/05-flex-combined.png | 0 | |
A | _content/posts/2024-04-24-margin-collapsing/index.md | 154 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
5 files changed, 154 insertions, 0 deletions
diff --git a/_content/posts/2024-04-24-margin-collapsing/01-defaults-combined.png b/_content/posts/2024-04-24-margin-collapsing/01-defaults-combined.png
Binary files differ.diff --git a/_content/posts/2024-04-24-margin-collapsing/02-bottom-combined.png b/_content/posts/2024-04-24-margin-collapsing/02-bottom-combined.png
Binary files differ.diff --git a/_content/posts/2024-04-24-margin-collapsing/03-top-combined.png b/_content/posts/2024-04-24-margin-collapsing/03-top-combined.png
Binary files differ.diff --git a/_content/posts/2024-04-24-margin-collapsing/05-flex-combined.png b/_content/posts/2024-04-24-margin-collapsing/05-flex-combined.png
Binary files differ.diff --git a/_content/posts/2024-04-24-margin-collapsing/index.md b/_content/posts/2024-04-24-margin-collapsing/index.md
@@ -0,0 +1,154 @@ -1 1 --- -1 2 title: What is the best approach for margins in body text? -1 3 date: 2024-04-24 -1 4 tags: [css] -1 5 description: By default, browsers add margins both at the top and bottom of elements, which results in excessive whitespace in padded boxes. Is there a better way? -1 6 --- -1 7 -1 8 By default, browsers add margins both at the top and bottom of elements. That -1 9 is not a problem because [adjacent borders -1 10 collapse](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_box_model/Mastering_margin_collapsing). -1 11 -1 12 However, as we can see in the screenshot below, margins do not collapse when -1 13 there is a border or padding, which results in excessive whitespace in padded -1 14 boxes. -1 15 -1 16 ```css -1 17 h2 { -1 18 margin-block: 1.5em 1rem; -1 19 } -1 20 p, ul { -1 21 margin-block: 1em; -1 22 } -1 23 ``` -1 24 -1 25 ![Screenshot: browser defaults](01-defaults-combined.png) -1 26 -1 27 ## Margins on the bottom -1 28 -1 29 In 2012, [Harry -1 30 Roberts](https://csswizardry.com/2012/06/single-direction-margin-declarations/) -1 31 proposed that you should only apply margins in one direction, preferably the -1 32 bottom. The argument was that margin collapsing is a bit of complexity we just -1 33 don't need. -1 34 -1 35 This is the general rule I currently use and that is also employed in popular -1 36 frameworks such as bootstrap. Of course there are exceptions: Headings need a -1 37 top margin. -1 38 -1 39 For the problem with the padding, Harry recommends to use the `:first-child` -1 40 and `:last-child` selectors. [Chris -1 41 Coyier](https://css-tricks.com/spacing-the-bottom-of-modules/) added that there -1 42 might also be a margin on the last child of the last child (and so on), so you -1 43 have to do a little more work then that. -1 44 -1 45 All put together, you end up with code like this: -1 46 -1 47 ```css -1 48 h2 { -1 49 margin-block: 1.5em 1rem; -1 50 } -1 51 p, ul { -1 52 margin-block: 0 1em; -1 53 } -1 54 > :first-child { -1 55 margin-block-start: 0; -1 56 } -1 57 > :last-child { -1 58 margin-block-end: 0; -1 59 } -1 60 ``` -1 61 -1 62 ![Screenshot: Margin on the bottom](02-bottom-combined.png) -1 63 -1 64 ## Margins between elements -1 65 -1 66 In 2014, [Heydon -1 67 Pickering](https://alistapart.com/article/axiomatic-css-and-lobotomized-owls/) -1 68 proposed that margins should not be defined on elements, but between elements. -1 69 This can be done by using the adjacent sibling combinator and top margins. The -1 70 code could look something like this: -1 71 -1 72 ```css -1 73 h2, p, ul { -1 74 margin-block: 0; -1 75 } -1 76 * + h2 { -1 77 margin-block-start: 1.5em; -1 78 } -1 79 * + p, -1 80 * + ul { -1 81 margin-block-start: 1em; -1 82 } -1 83 ``` -1 84 -1 85 ![Screenshot: Margins between elements](03-top-combined.png) -1 86 -1 87 One benefit of this approach is that it keeps very low specificity, which is an important property for base styles. -1 88 -1 89 On the other hand, I am not convinced that the basic premise is even correct. -1 90 Note how there is no margin between the list items in the second list (the one -1 91 that contains paragraphs). The visual hierarchy is off here because the margin -1 92 inside of the list items creates a bigger separation than the list items -1 93 themselves. -1 94 -1 95 You could argue that the list should be in charge of adding margins here. But -1 96 the list doesn't know whether it contains paragraphs or not. So maybe just -1 97 looking at siblings isn't enough. -1 98 -1 99 I really like this approach. But because of its limitations I currently only -1 100 use it in some special cases, e.g. top borders on headings. -1 101 -1 102 ## flex gap -1 103 -1 104 The previous approaches are both 10 years old. A lot has happened in the -1 105 meantime, so more options have become available. Specifically, I sometimes hear -1 106 people say that we should use the `gap` property instead of margins. That could -1 107 look something like this: -1 108 -1 109 ```css -1 110 .container { -1 111 display: flex; -1 112 flex-direction: column; -1 113 gap: 1em; -1 114 } -1 115 -1 116 h2 { -1 117 margin-block: calc(1.5em - 1rem) 0; -1 118 } -1 119 p, ul { -1 120 margin-block: 0; -1 121 } -1 122 ``` -1 123 -1 124 ![Screenshot: flex gap](05-flex-combined.png) -1 125 -1 126 While I love `gap`, I am not 100% convinced it is the right approach in this -1 127 case. Since it only adds space between elements, it has some of the same issues -1 128 as the previous approach. Also note how the paragraphs inside list elements do -1 129 not have any margins because the flex styling is only applied to the box -1 130 itself. -1 131 -1 132 ## margin-trim -1 133 -1 134 In 2023, -1 135 [Apple](https://developer.apple.com/videos/play/wwdc2023/10121/?time=240) -1 136 proposed a new CSS attribute called `margin-trim` that is supposed to finally -1 137 fix the problem for good. This would indeed be nice, but so far there seems to -1 138 be little interest from other vendors. -1 139 -1 140 ## Conclusion -1 141 -1 142 I had already done all the screenshots when I realized I should have included a -1 143 nested list. That is another case that frequently produces unexpected results. -1 144 At least I was able to include it in the -1 145 [codepen](https://codepen.io/xi-the-bashful/pen/qBwgrjB) I used for all the -1 146 examples. -1 147 -1 148 It is still hard (impossible?) to produce base styles that just work out of the -1 149 box for every kind of content and at the same time don't make it extremely -1 150 complicated to overwrite them for custom components. -1 151 -1 152 If we have to live with some edge cases, I feel like excessive margins at the -1 153 bottom are more acceptable than excessive margins at the top or missing -1 154 margins. So I will stick with the bottom margin approach for now.