The Horror Of Margins In CSS
Вставка
- Опубліковано 23 лип 2024
- Slightly controversial but man is life better after margins
Sources:
Margins Considered Harmful - mxstbr.com/thoughts/margin/
The Rules Of Margin Collapse - www.joshwcomeau.com/css/rules...
ALL MY VIDEOS ARE POSTED EARLY ON PATREON / t3dotgg
Everything else (Twitch, Twitter, Discord & my blog): t3.gg/links
S/O Ph4seOne for the awesome edit 🙏 - Наука та технологія
Margins are great for typography. Actually, they were designed for it, i. e. back when the web was basically only text, links and images. And this also explains most of their design choices like collapsing. I don't like to use extra markup just to be able to use padding, but when composing components, it's much better to have the container define some padding or gap. Components shouldn't have outer margins.
Ya these behaviors actually can come in handy when you understand them and are styling e.g. rich text. For components, though, it is cursed.
You can use a combination of grid for layout and `line-height` for text spacing instead, though, and that reflects graphic design typography more. I personally do still use margin, but I do hipster artisanal global CSS for my projects, and I can't recommend that for sensible, practical devs.
@@UliTroyo You would use line-height for spacing BETWEEN text elements rather than typographical tracking WITHIN a text element? Interesting approach! Not my cup of tea but whatever gets the page looking great! :)
Yes, let's take document layout tools and shoehorn them into UI layout mechanisms. Who could've thought it would turn into an unholy mess?
@@UliTroyo margins are perfect for typography because of margin collapse. If you define your h1 to be 16px margin, while p’s are 8px, when a h1 is followed by a p you get what you probably want, a 16px margin, because the 8px margin has been collapsed.
If there's one thing I'm confident about, it's my CSS skills. So, all these behaviors with margins that you're not fond of have their place in my toolbelt. When making a simple grid editor, you would not use grid if you want to animate the changes. What I like to use is flexbox and a mix of auto-margins with solid values.
Margins are useful but can be easily misused.
Margin is margin, it has its place, and the behaviour is exactly what you would expect, in the context of laying out typography and text on a screen, which is what html was initially created for.
"Margin is margin and behaves the way that you would expect". True but only if you have the same mental model of how margins should work, if you just think "add more px until looks good" you will have some problems
I don't want to spam all such comments, but there are better ways of handling typography on the web, with things like grid and flexbox, as well as more esoteric text properties like `line-height`, `word-spacing` and `letter-spacing`, to say nothing of `white-space`, `text-indent`, `font-stretch` and `font-kerning` which MUCH more clearly denote intent.
I was just being dramatic :) I agree that margin is not the best solution to every case, and not everything behaves 100% as expected (in fact it does not). For UI components (or anything that is a rectangle that has to fit inside another rectangle), padding and flexbox make more sense, and I agree with the reasons Theo mentions in the video.
What I meant, is that some behaviors of margin you cannot achieve with anything else, like negative margins, or overlapping margins of different sizes, which in my mind make sense, and are are pretty neat to have.
Also all the examples in the shown post are consequences of two things: Content Seperation and Block Formatting Context. If you know how these 2 concepts work then everything just makes sense. Its like not understanding how gravity works and complaining about how it doesnt make sense since a ball bahaves differently based on how you throw it. CSS might look simple syntax-wise which gives the false impression that it also is simple website-wise. The most intuitive behaviour is not always the best. So people please understand the why before the what. Understand how a calculator works instead of remembering all possible inputs and outputs.
>the behaviour is exactly what you would expect
i thought so as well, but i was surprised to see that margins collapse only vertically and not horizontally, and if you introduce padding they sometimes don't collapse at all.
Margin has some great uses, but most people don't use it how I believe it should be used. Margin should exclusively be used for text inside components or during page implementation of the component. (To be precise, something like this ). The bad use case would be to hardcode a margin inside the component
IMO margins should never be used for component layout, only for text layout (i.e. where multiple paragraphs and/or headers are siblings) where you want the margin collapse,. But that is the only use-case where I find it useful.
In my opinion margin should only be used when you need to shift something somewhere because of a layout reason
@@Coconut_Fred Depends on what you're shifting. If you use top/bottom margins to shift layouts, you run into the issues explained in Jon Comeu's blog post. This is causes inconsitencies between different contexts and is not ideal for reusable components.
Actually, if you're using margin-top, that only affects the component you apply it to. Margin-bottom will affect the component below it by pushing it around. I've found it's better to just avoid margin-bottom completely.
exactly. I worked at a company where they had a component (React) for integrating stuff on the pages.
Common practice for inconsistent vertical spacing is to use margin-bottom on elements. This way you won't have the issues with margin.
I see Theo trying to prove that he’s a CSS teacher now. 😂😂😂
Oof
It was painful to watch xP
@@RodrigoDAgostino I thought it was excellent, but still had to give him some shit for it. Lol.
@@Michael-Martell to be completely honest, it was an ignorant take on his part. CSS doesn’t seem to be one his strong suits :S
i dont get it, whats the bad take@@RodrigoDAgostino
Margin collapse is useful in cases where you conditionally render a component. If you need 12px bottom and top space between components but sometimes a component doesn't render, you'll be jumping through unnecessary hoops to achieve the correct spacing using spacer components or padding.
Gap is great for when you are using flex or css grid. But this isn't always the case.
margin-bottom: n; last-child margin-bottom: 0
gap is. GOATED
@@bohdanvinter6929 Or you could use the adjacent-selector, so you don't need to unset the margin on the last element i.e .item + .item {margin-top: n}
@@bohdanvinter6929 Or let margin collapse do what it's supposed to do? The overhead of having to think about a different margin for the last child is unnecessary.
@@infidusandrew The overhead of having to think about margin collapse is unnecessary.
Setting 100% on a block element is causing it to be 100% width of its parent and then you added 30px margin around it so it overflows. To fix that, just remove the 100% from the child width. Your solution of adding another child element is not always an option and you get into div-itis if you plan on doing this everywhere you need spacing. I’ll agree with one thing, margin collapse has been unintuitive for the longest time (it made sense when the web was mainly just paragraphs and one dimensional top to bottom). I use gap and padding first, but there’s a time and place for everything and you shouldn’t completely discount margins. I feel web influencers these days get a little too preachy and hyperbolic with their titles. Also, using a combination of negative margin and padding can be useful.
3:29
Keep watching just a few more seconds...
i just do `width: calc(100% - 60px)`
Use width: stretch with postcss enabled for 100% width elements.
@@k-yo the default width is auto, it will just work if you dont add 100%
I think UA-cam might be using css margins in the push notifications system because even though I've rang the bell I haven't gotten a notification for your channel in a while
The Horror Of Springs In A Toolbox
Springs are used widely. They can pull and push elements they are connected to. But I think they are not up to today's tasks.
Recently I had to build a frame for a painting. When I used springs to connect the wooden elements the frame lacked stability, it wasn't firm enough to hold the painting.
Then I decided to use screws and nails instead. The difference was enormous, everything stayed in place.
From all that I conclude, that there is no place for springs in a modern day toolbox. You should use screws and nails instead, or even glue.
"I suck at CSS so now margins are bad."
What a coincidence, just finished Module 1 in Josh's CSS course, and his margin collapse section has the exact quiz you are referring to where you have multiple elements all touching or wrapped around each other with different block and inline negative and positive margins, and have to determine what it will do. 2 days ago I would have been with you on a lot of this stuff not making sense, but Josh broke it down extremely well, and why all this stuff exists. However all of the headaches surrounding margin collapse only apply in flow layouts, and who isn't plastering flex and grid everywhere anymore.
99,9% of the time, I just use a padding lmao
Everything is flex/grid with gap for me now.
@@josephchagan9015 that too
Same😂
Same
Same!
Box sizing border box and padding all the way.
Margin collapse is for display block, & the rules make sense for typography as highlighted by veitlehmann. If you really, really want to avoid margin collapse, display flex is an easy opt out (which I am sure most people are abusing lol). Or as ddomingo highlighted, prioritize the use of let's say margin bottom over margin top (I am in the camp of margin bottoms, think paragraphs).
As for the container example, so for basic layout formats, margin 0 auto, padding whatever (give the container a nice background), & then just go up down with whatever components (with width 100%). & as someone proficient in SCSS & tailwind, tbh it is very easy to write mb-4 mr-4 instead of div padding whatever, the div wrappers would be more aggravating to me.
Flex gap is neat & happy to see it become more adopted, but I keep thinking about paragraph & heading margins (& margin between text & an icon or whatever) lol.
"Why couldnt you self close a div?!" its a layout element, it makes no sense to self close a div should always contain something
Furthermore you can't self close anything in html. That trailing slash has literally no effect. It's in the spec.
@@recursiv Exactly. The only purpose for the trailing slash on self closing elements is to make your HTML syntax compatible with XML.
Well, you gotta take into account that UI frameworks will often allow you to optionally add content to a slot, and when omitted - give you the option to write the component short-hand as . So, it's not crazy to think that you could do this with any element - *if* you were "A React/JSX dev." What's just weird - is that instead of thinking "Oh. I guess I assumed divs would be like this because of how my framework works - TIL..." - - that the go-to reaction is "HTML is insane and wrong and CSS is too because I don't know how it works."
@@sheriffderek except that your component isn't a div, it contains your components html so it being a self contained tag makes sense, unlike a div on its own that is ALWAYS a container
@@TurtleKwitty I feel like you're just paraphrasing what I said. I agree. It doesn't make sense to have a self-closing div. But I'm showing how someone like Theo might close their eyes and leap to the conclusion that it might.
Your content is so good man, keep up the great work, it's really appreciated!
does anyone know a replacement for negative margins in layouts where one element has to overlap another by a fixed amount in pixels? like one section overlaps the section above it
How else do you center an element within a container, without margin auto?
This is hilarious. Every time the thumbnail pops in my sidebar I crack up. Moving something away from something else... truly one of science's most perplexing concepts... probably just the internet got made wrong.
what about for different sections of the page how do you space those
Throughout the years, I've also kind of unintentionally moved away from using margins too, these days I barely use them for anything since gap is supported everywhere and if you use IE then barely any website would work for you, so why would mine have to? One significant difference between padding and margin is padding creates a bigger "hitbox", which in rare cases might not be what you desire. Also, a little tip, margin collapse is not an issue with flexbox.
By the way, the CSS Working Group even admitted it themselves, that margin collapse is terrible - "The top and bottom margins of a single box should never have been allowed to collapse together automatically as this is the root of all margin-collapsing evil."
Margin collapse makes sense for paragraphs, but it should only have affected typographic elements. A lot of inconsistencies and weird behaviors were born out of the fact that early websites were just text on screen.
I have this principle I made up that I call the ELI principle - "enforced layout isolation". In other words, design your UI such that your elements have as few "opinions" (or as you put it, side effects) about the outside world. This results in UI that is sane and predictable, and also helps to prevent things like layout shift.
I’m guessing flex box + gap > margin
Let’s see how this pans out
Don't forgot grid + gap, if going beyond a single direction with flex vertical/horizontal
I really love these technical talks. And CSS especially - because it's so obtuse. Thank you for showing alternatives and talking about flex box
06:36 is margin ok if it's on html element that is part of component?
I had a problem with a flew row tailwind problem where I was using margin. I had given up because I couldn’t solve it, low and behold it was the unpredictability of margin that did me in the entire time. I wish I knew about gap, but now I know! Thanks for the video
I love these kinds of videos, even if I don't agree with everything, It gives me another perspective on how I develop my apps
The vertical margin not combining but taking only the larger value is useful for typography. Granted more so back when a page was just a wall of and tags.
It overlapping means that a text element's margin is always consistent. For example if a h2 tag has a margin-top: 24px and a p tag has a margin-bottom of 16px you can always expect a margin above a h2 to be 24px unless the element before it has greater that 24px.
Granted that's not as useful of behaviour today as it was and honestly I wish we had the option to disable in with something like margin-stack: stack | collapse;
So what about mx-auto in tailwind for centering?
I tend to use margins a lot and generally like it but I have to admit I've had issues with the oversizing of elements. Especially when trying to get rid of double scroll bars. I'll think form now on I'll try to avoid margins.
Hey theo, im someone who heavily overuses margin, primarily auto margins in combination with a defined margin so i can position an element. your solutions made some sense but can you expand on it and maybe show cases where margin is needed (such that you would use it) and changing more margin elements around that are positioned into padded elements?
Having written a browser-compatible dom parser from scratch, I can say that self closing elements aren't a thing in the HTML spec. The DOM parser ignores `/>` completely. Whether the element is self closing or not is entirely dependent on it's tag and is predefined. Every oddity in the HTML5 spec, including this one, exists for the sake of backwards compatibility. They are pain in the ass to emulate right, but they are necessary to keep the old websites working.
I found myself using margins only for negative margins, a common use case I see across the web, is when a site on a phone has an image that takes like 3/5 of the height, and a bottom sheet that supposed to go *on top* of it a bit. for this use case negative margins are goated.
The gap is the best thing happened to me once I got back to frontend from backend. Awesome.
Does gap overlap as margin too?
What about margin auto and margin between child elements? Like the space-y-4 in tailwind.
Nice video. I learned a lot from it, thank you :)
most of the time either I use padding or gap with grid or flex
Collapsible margins make sense when you consider design. If we have a series of content divs inside a parent, we can set the top and bottom margins of all to be equal and collapse between them, but the extra space will remain at both the top and bottom of the parent, which, when added to the padding, creates a larger distance between the edge of the parent and the inner content than between then inner content divs, with just a single margin rule and a single padding rule. If we assume 1em for vertical padding and margin above that’s a 2 em gap at the start to the content, a 1 em gap between the content divs, and a 2 em gap to edge of the parent, which works well both visually and semantically
I didn't know about this, the video makes some good points. But I think for typography I'd still use margins.
So never use tailwind space-y-2 for like forms? 😅
Interesting point, what do you think about Tailwind Ui then? It uses a lot of margins and `overflow:hidden;` to deal with the margin issues. Generally the css in that ui library feels terrible!
9/10 my first issue with laying a prebuilt component onto a page is with width 100% and not having things behave as expected. Thanks for sharing!
YES to all the solutions! Finally i get some confirmation that my thoughts on this subject was "correct" to think.
I'm totally on board with using elements just for padding. I first discovered this in you "Chirp" modern web app tutorial and haven't looked back since - it's a great little trick to bring out in certain scenarios!
It's a bit confusing that in the code example for the first solution you initially use flex gaps without any apparent reason, even though you actually want to explain padding elements and only introduce flex gaps in the third solution."
Cool video! I guess I have some refactoring to do today
Flex gap is a blessing, I can't believe the jank I had to do before it
You could avoid problems with margins if you set a team rule to only use them in a certain direction (top or bottom).
`margin-left: auto` is a beautiful way to push an element to the side. I will stand by this before watching the vid
Wow I didn't know this was a take, but in hindsight, I have noticed myself using padding and gap with increasing frequency, and I typically only use margin if it's the only way to accomplish something.
Lol. I'm glad it's not just me that feels this way about margins. Thought I was odd guy out and have virtually no margins in my apps except for simplest of simple use cases. Thank you for this.
flex gap not supported on old Safari, and older mac computers are not allowed to update Safari. Many schools are still using those.
In TailwindCSS you have `space-y-8` on the parent to space list of children vertically without even using flex. flex col and flex-gaps are the second best way.
Hey, shut up! Don't share our secret!!!
idk if theo hates space-y-n in tailwind, i just love that feature.
The gap solution is basically thr thought model for css grid... which is an even better solution
Padding sucks when you want containers to disappear when there is no content, and you’d like them to have height zero but now it’s zero PLUS padding.
In the end having a dedicated class to add margin is still a handy solution, while keeping the objects style declarations margin-free.
If you know why margin exist this all make sense, and if you use it that way. Margin shell only be used to seperate text elements, , . Padding exist to make space distance between elements. To have overlapping margin when you work with text is a must.
So, no mx-auto? This is the only margin property I use on regular basis.
Thanks! Great vid
I am in the middle of changing some list items spaced by margin-bottom nonsense over to flex with gap as this comes on, amusing coincidence.
I'll be honest, all my stupid ui problems recently have been due to margins making things wider than intended
Incredibly useful video! Thank you.
I always use margin bottom only. where the component is used not in the component, don't use negative margin use transform
I was going to recommand you to check josh css course
Funny, i accidentally discovered gap a month ago, and its increasingly become my goto solution for solving spacing. Don't know why i never heard of it before.
I sometimes use margin auto to push elements to the center or the edge of its parents. Also great inside flexbox when flex-grow is not the solution.
Use margin-top in your pages to space elements vertically, almost never use margin-bottom, ever - that's just about all I used them for. Occasionally I'll use `ml-auto` or `mr-auto` (Tailwind syntax) for flex elements that need to be floated to one side or another, without having to fight with `justify-between` rules.
Isn't border box used to account for such behaviours ?
Gap, padding and margin are 3 spacing tools, but each one has their designated function - even if the end result is always space-related.
Glue, nails, and screws also have the same shared purpose (put two things together) but you don't see builders complaining about said tools, rather they learn the right context to use each one.
6:02 If you take his CSS-for-JS course, there actually _are_ quizzes for these! Maybe you can get some sponsored access from Josh and do some of them for a video, could be fun 😛
That course taught me almost everything I know about css! So good
Why make another component just for styling, when you could style the original element properly?
in tailwind CSS margin is not working the same as you mentioned in normal CSS.
I've had to fix countless issues related to styling being broken due to margin. I am not at a fan of padding either.
ohh... I remember when I tried to debug collapsed margins.. the pain was real.
i dont remember using margin, all the time ive been using padding in most of the cases
6:29, had the same reaction to display:flow-root
theo dying during this video is so funny
Personally i use small margin and padding on all elements and then i use childs in a rows and colls pattern to position elements
I don‘t mind margins as part of my page layout to position my components or within a comonent that is selfcontained. But I hate when components have margins on their border or try to position themselves in anyway within their context.
You get a lot of shit for that spacer solution for a good reason. It sucks! 😆
I was so ready to disagree, as I have previously had nightmares caused by colleagues misusing padding on components making reuse problematic when trying to get elements aligned consistently.
That said, this video has convinced me to avoid margins, if only to help others avoid these footguns.
I would prefer using 'gap' over the other options, to be honest.
FYI flex-gap and grid-gap were renamed simply 'gap' years ago, for simplicity.
It's so funny how there are some css features that have been there for ages and people have no clue and do them in a older way
@@brunopanizzi There's good reasons why things like clearfix is obsolete now. It's buggy, has browser-specific behaviour (looking at you IE) and breaks your intuition about layout since it also affects its surrounding elements. Flex and Grid solved a lot of these issues. Don't do it "the older way", adopt the new features as they become stable across browsers.
padding can also be quite a bit nightmarish when you take into account the overflow and have fixed element sizes. That being said, I'd still say this is mostly because I'm more of a backend-oriented dev and I don't "practice" all the "edge" cases with paddings & such all that much and it can be tough to not mess up.
That being said, I feel like using it with something like a spacer div does indeed solve most of these problems for someone that isn't used to all the possible CSS issues.
I use gap as well, but keep in mind the support is at 92% of global users, so its not fully bulletproof
@@lukasmolcic5143 IE users have had more than enough time to switch. Thankfully almost every company I've worked at has agreed is not worth supporting outdated browsers anymore.
This is a hard stance I've taken a good while ago (since flex gap was available). The reality is the the parent should lay out the children via grid/flex and gap. I only use margins for typography (spacing around headers and paragraphs etc)
I would add the parent should always take care of positioning the children. And each child can only take care of their own children, never go up their own box model.
Rule of thumb: if a CSS property affects outside the box model, then it's the parent responsibility, anything inside the box model then it's the child's responsibility.
This way, you get reusable components in any context.
Yessss I rarely use margin, padding + space-x/y in tailwind usually works much better.
The kind of things we had to deal with before flex and grid
In the first example it's better to use max-width to avoid overflow instead of adding another div. The collapsing margins theory is not that hard, you just have to be consistent on where you put the margins, for example use only margin-bottom between sections.
Great talk. I'm convinced.
I don't understand box model, positioning and display, and for my specific case margins break something, thus they are evil. Now lets all jump in and whine and cry how bad they are and now we all must avoid it, because I had a problem with it.
This is basically how I see this video.
EDIT: a classic way to create some sort of a hype out of nothing, for attention and views.
Margins, especially collapsing margins are great for text rendering. Less so for components
At Max I use only top and bottom margin, never a left and right.
Div around the element, with padding. Acts like margin should act.
6:03 and that's how interview questions are born for positions that aren't worth it or mentally stimulating
I've always pushed for having each component only affects what's *inside* of it. Using margin, in most cases, violates this guideline 🙈
Hot take but I think the solution is to learn the ins and outs of margin and use them appropriately. Spacer elements pollutes my html imho.
Cool.
Thanks theo 🙏
Hot take, using width 100% is almost never the right option. In flex box, isn't it nicer to use the "flex" or "flex-grow" properties?
new video from my favorite CSS youtuber
Correct. Margin is best for centering something horizontally on the page, like `margin: 0 auto.` Other than that, it's padding all day. Think of it this way. A delivery truck is packed with boxes. There is NO margin between boxes. However, each box IS padded on the inside wiht pacing peanuts. So, omitting margin in your css allows your elements to fit tightly and naturally together. Think of padding as packing peanuts. Just add what you need to pad your content appropriately and move on. Keep it simple. Furthermore, text elements really only need padding on the top, or just the bottom. You don't need to pad both. There are so many settings that you can hang yourself with CSS. Keep it as minimal as you can, and it stays easy to manage. MUCH RESPECT!
after watching this I instantly hopped into my last project and realized I just used some auto margins to space the nav main and footer elements. I quickly changed that to a flex + space-between and got rid 100% of margins. funny thing, I had some utility classes for margins that I've used starting the project only to get rid of all of them. margins sucks.
Why not margin with width: calc(width - margin) 😅😅