- 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 
-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 
-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 
-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 
-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.