I mostly agree with this, but I would add a secondary construct on top of it. Sometimes you want collections of things to appear identical.
You might want a component, that as part of its own public API, abstracts away the usage of the spacing component (author calls this "Stack").
Ex: suppose you have a list of images and you always want them to be 8px apart. So you package up the Stack and an <Image /> component, that takes an images[] array.
This prevents the issue where engineers use the raw Stack+Image "atom" components and define random spacing rules: say the spec is 8, some engineers use 6, others 10, etc-- then you have inconsistent spacing in your app.
So ban a huge part of the CSS box model. Got it... Margins are valid in many use-cases, specifically many people leverage them for typography. They can even still be valid with component-driven development as well.
While eliminating them is hard, the argument here makes perfect sense. We've all been fighting margins one way or another. One could even argue that negative margins are a symptom of the problem.
When you use negative margins you're pulling the element out of the box and essentially causing overflow. Does this fix the issue sometimes? Sure. Is it the best option? Maybe it should just be the exception.
> We've all been fighting margins one way or another.
Nope - not really.
There's always been a huge distaste for the box model and it comes from a place of not understanding it vs. anything else. Margins + features like flexbox are a huge feature of modern web development.
If I were interviewing a developer and they started to go off on "ban margins" it would cause the interview to go short.
---
Since you bring up an edgecase to defend the article: negative margins.
Negative margins are almost considered an edge-case use for my entire career which is as-old as the CSS spec. They would show up in situations where complex layouts were just not achievable (holy grail w/dynamic content width and static sidebars pre-flex/grid). The other place they would show up is simple "off-by-one" issues like placing a child div 1px over it's parent border in dropdowns etc.
I'd say for the last 5-10 years specifically they've not been needed and are an artifact of legacy development before flex showed up. If I came across code using negative margins in a PR I'd ask the submitter to refactor.
Idk - just saying that using an old edgecase as an argument against such a ubiquitous feature of the box model (which is core to FE development) seems off to me.
---
One last thought - margins are still perfectly valid with components. It's just that component developers don't want to think about how their component may lay out with something else on the page. It's microservices fiefdom on the front-end calling to give up core web development features because people don't want to think about components interacting with others.
I did read the article and frankly it’s little better than the HN title. It’s heavily biased, fails to offer a convincing argument to anyone other than those who already believed the title, and even explicitly says margins should be banned.
What does "heavily biased" mean in this context? It's a straightforward article that puts forward a position, a series of propositions supporting that position, and a potential solution.
It's biased in that the author has an opinion he's trying to convince people of by providing arguments in its favour, but that's what writing tends to do (including your comment).
The "banning" stuff is obvious hyperbole[0]. No reasonable reader could conclude the writer means CSS margins should be banned in law.
You’ve admitted yourself that the article is highly opinionated and full of hyperbole so I don’t really see why you’re confused by my statement. But I’ll answer your question nonetheless.
Any article stating something should be “banned” can’t really be described as a balanced discussion about the usage of that thing.
I’m all for discussions on why usage of something is bad but in the case of margins there’s clearly use cases that are suited to it, which other commenters have highlighted but which the article entirely glossed over.
So the article is more than just written as a persuasive piece; it misses any balance or contextual clarity and thus ends up dishing out bad advice as a result. Bad advice that is so strongly emphasised that lesser experienced developers would easily be intimidated by it.
Now if people want to discuss the strengths and weaknesses of margins and put forward alternative solutions in the process, that at least informs lesser experienced developers about ways to solve their real world problems rather than berating them for not following some misguided idealised view of perfection.
(Yes I know there was some details about alternative ways to implement a margin, but they were crap and lacked any detail, since the article was essentially a rant piece rather than technical document)
Yes, that title fits better with the content of the blog post and is a statement I would readily support. Leaving spacing to be the concern of the parent element makes eminent sense, and spacing components is a good way to do that which happens to be used by drag-and-drop editors like Squarespace.
Honestly I think this an amazingly effective title: It's very evident from the comments here who actually read the article (which is very short) and who are just replying to the title.
I think the main bugbear of margins that the article doesn't mention is margin collapse: I personally don't find the rules super intuitive and I would rather just be explicit with spacing than have the browser collapse things together!
Agree, collapsing margins are counterintuitive, and only applied to top and bottom margin. It’s really surprising how many people don’t know it’s a thing and fight the box model. If you think you’re constantly fighting layout, try to read the MDN docs [1] with a fresh eye. I was guilty to think I needn’t learn CSS, and reading the MDN really help me.
What's really surprising is how many people do know that margin collapse is a thing, but haven't fully understood all of the implications, so they still get mystified by some unintended consequence.
I don't think that "go read all the MDN docs" is a very useful suggestion. More useful is something like the following, which I don't think you will find anywhere in MDN:
When an element's top or bottom margin collapses with its parent,
this may affect the position of the parent, because the minimum of the child and parent's margin will be used to position the parent. (MDN says the child element's margin will fall "outside the parent", but it is not clear that it will be used during layout to place the parent.)
The bigger problem is that CSS is just so complicated and arbitrary. Consider the rule for collapsing margins with parents, from MDN:
> If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of one or more of its descendant blocks; or no border, padding, inline content, height, or min-height to separate the margin-bottom of a block from the margin-bottom of one or more of its descendant blocks, then those margins collapse.
They list five different factors that prevent collapse, one of which ("block formatting context created") is a link to a page that defines it in terms of 15 different constructs or situations in CSS.
On top of that, it appears that the MDN text is in error, because it lists intervening "height" as something that prevents bottom margin collapse, but not top margin collapse (when in fact it does).
This is according to me the real issue. Besides this unintuitive collapsability margins, there is only one difference between margin and padding: the edges/border of the background color.
It's the unintuitive collapsability that messes up margins.
I almost feel it should be written out of the spec, because a lot of people still don't understand it, designers and developers. And design tools like Sketch or Figma will never implement it in their tools.
The point about not having it in a component is valid. It happens all the time that a margin on a component is different based on context. But there is no need to make it any more complicated than a margin -- just add the margin externally and if your framework can't do that, add a wrapper and put the margin there.
Margin is generally more desirable than padding imo. Component/element knows the content it contains and uses margins to require a minimum amount of spacing. It avoids the need to make decisions on the spacing between every combination of components.
Padding only works if you know everywhere your component might be used or don't mind remaking spacing decisions every time you use it. In my experience minimizing code needed for each use of a component leads to more coherently styled interfaces, particularly on larger or faster moving teams.
The author is arguing exactly that: remake spacing decisions every time you use a component, because that’s what many designers (most?) do. This is also true in my experience.
I want CSS to make spacing decisions so that I don't have to, and a system where graphical elements look good by default because they come with appropriate margins and containers adapt to what I want them to contain (e.g. by shrinkwrapping the content or by switching between different numbers of columns or rows) is more useful than a non-system that looks bad unless I keep many tedious ad-hoc specifications consistent.
Moreover,
> Margin breaks component encapsulation. A well-built component should not affect anything outside itself.
Definitely not, margins are an essential part of a component, like a garden around a house, and they make components "usable in any context or layout" (unless the context or layout is stupidly overcomplicated).
Exactly. Slapping some components together for a simple feature shouldn't require a designers input at all. Whether the defaults are margins or paddings I don't really care, but if the component looks bad without styling, it's a bad component.
And then you have a container with A, B, margined apart by max(A.mr, B.ml) and want to insert a sizer knob in-between, which makes them (A.mr + B.ml) apart. Or you have to put ABCDE into a sortable wrapping flexbox, and the best practice* says you must -ml the flexbox, but now you don’t know how much because each of ABCDE has its own +ml. It’s all nice until it’s bullshit.
Margins make complete sense when you do want to fold them, which is common with textual content (eg. imagine an img tag with bottom margin, and a h2 tag right after it with top margin).
The fact that they can be misused does not make them useless.
Web styling is not useless, it’s just fucked up. The article has no hope to change that (neither do we) and tries to find a balance.
In a better world, margins would work in a block context (where paragraphs live) but not in flex/grid ones, which take layout in their hands. Another context could be called “constraints-based”, which would space its children relatively, like A.r + 10px <= B.l; B.r = this.r - 10px. Children would expose their preferred margins, which these layout contexts could take or not take into account.
The "block context" for which setting margins is a good layout abstraction is not the technical "block", "inline-block" etc. of CSS, but the general situation of measuring the empty space between homogeneous rectangular blocks.
If you want to place a slider between two text paragraphs, the slider isn't a good match for them (even if rectangular, it's far smaller) and you'll have to give it small or even negative margins under the assumption of the text paragraphs having normal, big enough margins.
And this highlights the issue with the idea that "children would expose their preferred margins, which these layout contexts could take or not take into account": a reusable and modular layout should be bottom-up, with components knowing what CSS rules make them look good and containers respecting them. Since the slider is small it can have smaller margins than the text paragraphs, but a container that knows that its middle child is a slider is a complicated and ad-hoc container.
If you want to place a slider between two text paragraphs
I don’t, I want to put a slider between A and B. I don’t know what’s there from the bottom-up rule. A or B may even have a loadable content, so I know nothing until it’s rendered. If A and B are paragraphs, that’s usually a coincidence irrelevant to the container’s purpose.
So what is the correct way to put a slider between beforehand unknown type A and type B components?
a reusable and modular layout should be bottom-up, with components knowing what CSS rules make them look good and containers respecting them
This approach is good until it’s not. You can’t just write off some layouts as “bad” and call it a day. It’s not modular, it’s pre-styled in a way that involves intimate knowledge about all of components and how they “stack” in advance, which is opposite to being modular.
It seems that I am discussing graphical design while you are discussing CSS anarchism and worst-case technical details. I mentioned text paragraphs because they are the most common and traditional type of block, but images and frames are popular since at least the middle ages and they should have about the same margins as text paragraphs (solid dark objects more, transparent images with internal empty space that adds to the "official" margin less).
The components around the slider are not "unknown": it's enough to be sure that, for example, their margins are between 20 and 30 px so the slider is allowed to claim -5px off a collapsed margin without collisions.
It seems you ain’t the one who has to look for the best turpentine, well, to each their own. Thanks for the info, I hope it will help with my next layout issue!
There are several types of designers, and even on the web itself, several different things you might be designing. Designing a text medium (eg. a blog) should have more focus on semantic tagging compared to a SPA where you probably want an entirely different approach (and where talk of "components" makes more sense).
I like TeX's box model over CSS which allows for easier "smart" spacing (look up hglue, vglue, hskip, vskip, and eg. care for orphans when typesetting etc.) and smarter column alignment (trivial alignment on decimal point in tables).
While I'd never call myself a designer, I've done plenty of TeX (print and PDF) publications that people have commended for usability and appearance.
There is no need to take sides: there are things that are easier in CSS for sure, and I only highlighted a small number of things which are very nice in TeX box model that are somewhat similar to margins in CSS (non-explicit behaviour to help with smarter laying out of text). TeX has a bunch of problems for electronic documents too (box model it uses means that each individual glyph gets positioned as a separate box, which can result in unsearchable PDFs, for instance).
But TeX typesets to a beforehand known format (I assume you mean target document size) as much as HTML+CSS does (a bitmap canvas of <width> x infinity size): it's not optimized to reflow stuff live, but you can definitely change the page size before every run with a single command, and rendering should (mostly) reflow properly (this would be equivalent to resizing the window, or having differently sized/fine target like a cell phone).
It does not solve the problem of multiple page sizes any better than HTML+CSS, it just provides some nicer and more obvious tools for aligning stuff on the page/screen that could be more easily used to achieve such support.
I mostly meant that the rendering problems are radically different.
Typesetting is a rendering a static copy a priori. You can expend a lot more time and resources rendering and reflowing the document. Rendering HTML+CSS, which can be dynamic, is a radically different problem.
I wouldn't be surprised if these posed very different constraints on the possibilities of the layout model
What I am saying is that that it is not a radically different problem. They are radically different implementations focusing on different goals, but the problem is pretty much the same.
TeX's box model is in no way less optimizable than the HTML+CSS (if anything, it's the opposite due to it being much simpler). It has had a stable algorithm and implementation since 1983, and that implementation was never optimized for reflow like HTML + CSS has. TeX itself is also Turing-complete, which makes processing more expensive by definition, and that's mostly the reason for the slow performance, rather than the box model — and it is from 1983, after all. For some things, the reflow model is even used with TeX today (eg. table of contents generation usually requires at least two passes to "reflow" the output).
Håkon Wium Lie, the author of CSS, and fellow implementers were very aware of the TeX box model
>6.6.4 Inspiration from other formatting models
In the early design phases of the CSS visual formatting model, other formatting models were frequently consulted for inspiration. In particular, TeX [Knuth 1984] was often brought up in white-board discussions.
As one of its foundations, TeX has a well-defined box model wherein all objects, including individual glyphs, are contained in boxes. The spacing between the boxes can be controlled through TeX commands. In addition to optimal spacing between boxes, TeX also allows maximum and minimum spacing to be expressed. This is referred to as glue (although Knuth suggests that springs is a better term [Knuth&Plass 1981]).
The visual formatting model in CSS is based on a box model, and all elements, both block-level and inline, are turned into boxes. Thus, CSS goes further than most other style sheet languages in creating boxes. For example, DSSSL and P94 do not use boxes for inline elements. However, CSS did not adopt TeX's glue. Although the issue was discussed, it was decided against in order to keep the VFM simple. Glue is very useful when breaking paragraphs into lines, but CSS leaves this problem to implementations. CSS allows, but does not demand, inter-paragraph line-breaking optimizations. Each box in CSS is, however, potentially richer than the boxes found in TeX since it can contain a padding, border and margin bands. CSS also borrows other features from TeX, including the em and ex units.
Håkon also goes into great detail on the historical context and technical requirements surrounding the development of CSS.
I think the reason the CSS box model differs from the TeX box model is because of the different problems they attempt to solve and various contextual difference the technologies developed under. Crucially, it's not because the authors were unaware of the TeX box model or because they thought they could do something better
Thanks, that's a nice read! (Note that I never suggested that CSS creators were unaware of the TeX box model, though I had no idea to what extent was it considered early on)
That also supports my claim that reflowing in TeX's box model would be simpler ("CSS is richer").
I simply highlighted a few things where TeX's box model does a great job for what are commonly hard problems with CSS even today (how do you align columns on decimal points?): I imagine most people, even LaTeX users today, are unaware of the internals, and I hope it's valuable for people to learn of them.
It was never something I had thought about but I got curious so I did some digging.
It's true that some things are much easier in TeX, like aligning on decimals. HTML tables are used for all sorts of crazy so I'm not surprised it's harder to that kind of stuff
That's true. That being said, Flutter Web is not entirely ideal and although it has some good use cases (very simple forms and web apps that need to be developed quickly), I would primarily suggest Flutter on iOS and Android.
I understand and agree with the sentiment expressed here regarding the outer layout of components in a page (though I'd actually recommend using `gap` with a flex or grid layout).
But margins can be incredibly helpful when implementing internals of complex components, and when laying out components next to each other that are not equal peers (like labels with form fields).
Negative margins can also be very helpful in some circumstances, like when a border shouldn't contribute to the space taken by a component, or when components should overlap without resorting to absolute or relative positioning.
Rules without margins are going to be a mess. For one you can't negative margin the padding out of the first titles in a section and other useful negative margin pulls.
Without margin collapse, you're going to need to handle first and last paragraph so they don't have half margin from their container.
Margins are respected across the elements hierarchy, which is especially useful if you're reusing components in react like systems; neither nested paddings nor grids aren't suitable do that.
Anyway, considered harmful articles considered harmful.
There is a time and place for margins. Being thoughtful with them is a better approach than "banning margin from all components."
Should I really ban the use of `margin-left: auto` when positioning my flexed elements? I don't think this article is actually advocating for that, but a novice reader may.
Being thoughtful is a better approach than "considered harmful" clickbait in any situation.
Regarding CSS margins, they are part of the box model even if certain stylesheets neglect them, and the only conflicts they can be involved in are easily solved (a rule for "container x" is more specific than a rule for "x" and can override margins, particularly with parent padding, in special cases) and they highlight genuine design defects: trying to use a component both with and without its "natural" margins (without adding appropriate classes or wrapping containers), trying to specify conflicting margins, trying to fit variable-sized content inside fixed-size containers by messing with the content's required margins, and so on.
There might be things missing to achieve whatever result you desire, but CSS does allow a parent element to define how spacing (and any other styling) works for child elements.
Out of curiosity, why do you need to use "margin-left: auto" when working with flexbox items? What is it that you're trying to do, which can't be solved with "justify-content" and "align-items"?
Not OP but I had a scenario where I had a row with a variable number of items, left-aligned, and then the final item had to be right-aligned. "margin-left: auto" on the final item achieves that effect.
The text of the article contains an argument to avoid margins when creating reusable components, instead allowing the consumer of the component define its margins. There is no argument made against using margin properties.
or may be we should continue looking for gotchas when it comes to clickbait misleading titles and finally get the message of "clickbait is wrong" across to at least some part of tech blogging community?
Thing is, clickbait works, so people will continue doing it. All your "gotcha" showed was that it works. Look at all the people in this thread engaging with this post, not because of its content but because of its title. If a clickbait title will lead to higher engagement, why would an author not use it?
The best way to combat clickbait is to not fall for it, not play into it, to either ignore the article, or to read the article and discuss or critique the content instead of bringing more attention(all press is good press) to the title.
My gotcha and the negative reaction to it shows only that the majority of readers are ok w/ using of clickbait titles. That's a pity. Although bringing attention to such things always gets negative reaction in the beginning. Not the reason to stay silent anyway.
> If a clickbait title will lead to higher engagement, why would an author not use it?
The negative reactions to your post are due to the laziness of not reading the article and the "gotcha".
I think most of us come to Hacker News for interesting discussions, and the torrent of confidently incorrect "this person is wrong" comments is not adding anything to any discussion.
The top comment is already clarifying the title, so any other comment should be unnecessary, especially snarky ones.
The gotcha is another problem in itself: not only it comes from a misunderstanding of the post, a lot of people don't have control over their publishing software, but their advice should be judged on its own merits, not on some "you criticise society yet you participate in it" way [1].
Funny and arrogant attempt to mask the problem with clickbait-ish title by turning into personal accusations in laziness, referring to memes, speaking for the rest of community, etc. The whole bag of tricks. Not gonna work, sorry. The title is wrong. Go blame the author, not the one calling out the bullshit.
The current title wasn't added by the author, it was editorialized by another person. This is also against the rules, and will probably be changed as soon as dang sees it. The original title might be cheeky, but it makes sense in the context of the post.
By the way, you broke another guideline in your comment: "Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something."
Anyway, I'm just explaining why other people flagged you. You can choose to try to understand the rationale for your flag/downvotes. Or you can cover your ears and accuse everyone else of being pro-clickbait.
Here we ago again, first it was my laziness, now the luck or real understanding :) If we are on the grounds of telling other people what their choices are (another arrogant and surprising manipulation, but whatever) you have a choice to engage into fixing the wrong message. Or you can continue posting comments directly to unknown individuals trying to enlighten them on reasons how their behavior triggers you.
> you have a choice to engage into fixing the wrong message
I'm not the OP nor dang, so I can't fix it. About talking about it, I already mentioned that this had been done done, on my first comment: The top comment is already clarifying the title. Several people also replied to you.
That comment was made an hour before you made yours. Also the article itself contextualizes the title, and that would have cleared up your misunderstanding.
> Or you can continue posting comments directly to unknown individuals trying to enlighten them on reasons how their behavior triggers you.
Nothing is triggering me. You clearly seem bothered by the flagging from your edits, so I'm trying to explain to you how this community works. I'm sorry that my explanation doesn't satisfy you, but continuously attacking me won't change anything and won't do any good.
Please don't turn this into a flame war. I'm just trying to engage with you to help you understand. Please don't assume ill intent.
> Look at all the people in this thread engaging with this post, not because of its content but because of its title.
All I see is a discussion that’s been massively derailed by a shitty title. If it had a sensible title, perhaps people would be talking about the actual concept that the article was trying to tackle instead of threads like this where people keep having to explain that the title doesn’t match the article.
“Engagement” for the sake of engagement is worthless unless you are optimising for noise instead of signal.
I mean, the top comment is someone proposing a better title. That's actually adding value to readers, compared to nonsense points that have nothing to do with the article. And that comment already was there when you commented, too.
I thought the argument, after reading the article, was to use spacer components that would define the space between elements because you would then be able to have differing margins when using in different contexts.
>avoid margins when creating reusable components
so, if this is using margins then they are not using reusable components? I mean, I have a difficult time taking the advice regarding CSS usage from someone not using reusable components.
Aside from all the other things people are saying this person doesn't know about, I don't think they know about the min, max, and clamp CSS functions which when used with margins can be amazing. Not to mention that the need to have different margins in different components uses might be handled with CSS variables, not mentioning that the variable can change due to its context seems an oversight making the rest of the article less than impressive.
on edit: it is of course a cheap shot to argue their site uses margins etc. I just wanted to note that I had sort of a disagreement as to the main takeaway from the article, and then I noted why I disagreed with that takeaway.
Without knowing if the author is using a template or otherwise not maintaining their webpage's HTML and CSS (it looks like something that could have been pre-packaged), it's hard to make the case.
We may, as engineers, use tools that internally implement software patterns that we have an academic disagreement with. And that doesn't make us any less dignified in our beliefs.
Ban layout styling from your components entirely if you can. Make everything headless (eg https://headlessui.dev/, https://www.radix-ui.com/, plain old HTML, etc). Leave the way things look up to the app that uses them.
What if a user needs it ready-to-use? Also imagine you’ve created some styleless form which I need to style according to my Bulma or Bootstrap stylesheet. What if the structure is different than these two are assuming?
I'm not suggesting the layout shouldn't be included at all. There's nothing wrong with including a default for the component - as a stylesheet in "examples" or something. The point is that layout shouldn't be a part of the component itself. The beauty of CSS is that it makes doing that absolutely trivial.
Are you saying that content and layout _should_ always remain combined?
I accept that we come to this understanding through our early introduction to language, writing and art. Most people intuitively link structure and presentation when they compose content.
Separating them is incredibly useful. You can see this at a really basic level, in plain text. Lay out a single long paragraph of plain text into lines of max 80 chars, and then insert a word. The layout goes completely wrong and if you don't have tools to help you, you spend ridiculous amounts of time realigning the text. The line-length algorithm you're following (or using) is __totally__ separate from the content. HTML and CSS are this, scaled up to allow fine grained annotation and control of both semantics and presentation, independently.
XSLT is there, chrome supports it, but no progressive rendering, or support of modern XSLT versions.
Basically, Google wants to kill XSLT, and normal web in favour of Javascript, and WASM based web. Why? They don't want people to turn off javascripts, so they can show more ads, and competitors cannot get an easier job making google.com alternative.
The problem is people treat HTML, CSS, and JavaScript like they are separate languages. They should be treated collectively like bytecode/binary and almost no one should need to know more than they exist, a compiler should be what's writing web output.
"Component" doesn't necessarily means "third party library".
The headless components need to be styled in the end, and the guideline present in the article still applies to those cases: outer margins in components causes some headaches.
"Component" doesn't necessarily means "third party library"
I didn't suggest it did. It does mean "block that could be reused somewhere" though. Devs should consider that carefully when they're making components. If your block can't be lifted and reused because it relies on the parent structure or it expects something global that's not passed in as a param/prop/whatever then you need to think some more, because you're making something that's not reusable.
One day, someone, somewhere will want to use your component in a way that you didn't plan for. If you've created a hard link to a particular part of your app such as an expectation that the parent HTML structure will look a specific way, then you've made their job harder when you didn't have to.
> Devs should consider that carefully when they're making components. If your block can't be lifted and reused because it relies on the parent structure [...] then you need to think some more.
Yes, that's what the article is talking about.
Even with headless components you need to have CSS somewhere else in the end. I don't know how you're "[leaving] the way things look up to the app that uses them" to headless components, but most people do it with (surprise) other components that belong to the "app" itself. Or with CSS-components.
So, the advice in the article could still apply to them. If you apply a style that contains an outer margin, you might run into the problems discussed by the articles.
229 comments
[ 2.9 ms ] story [ 254 ms ] threadYou might want a component, that as part of its own public API, abstracts away the usage of the spacing component (author calls this "Stack").
Ex: suppose you have a list of images and you always want them to be 8px apart. So you package up the Stack and an <Image /> component, that takes an images[] array.
This prevents the issue where engineers use the raw Stack+Image "atom" components and define random spacing rules: say the spec is 8, some engineers use 6, others 10, etc-- then you have inconsistent spacing in your app.
Yes, why not?
While eliminating them is hard, the argument here makes perfect sense. We've all been fighting margins one way or another. One could even argue that negative margins are a symptom of the problem.
When you use negative margins you're pulling the element out of the box and essentially causing overflow. Does this fix the issue sometimes? Sure. Is it the best option? Maybe it should just be the exception.
Nope - not really.
There's always been a huge distaste for the box model and it comes from a place of not understanding it vs. anything else. Margins + features like flexbox are a huge feature of modern web development.
If I were interviewing a developer and they started to go off on "ban margins" it would cause the interview to go short.
---
Since you bring up an edgecase to defend the article: negative margins.
Negative margins are almost considered an edge-case use for my entire career which is as-old as the CSS spec. They would show up in situations where complex layouts were just not achievable (holy grail w/dynamic content width and static sidebars pre-flex/grid). The other place they would show up is simple "off-by-one" issues like placing a child div 1px over it's parent border in dropdowns etc.
I'd say for the last 5-10 years specifically they've not been needed and are an artifact of legacy development before flex showed up. If I came across code using negative margins in a PR I'd ask the submitter to refactor.
Idk - just saying that using an old edgecase as an argument against such a ubiquitous feature of the box model (which is core to FE development) seems off to me.
---
One last thought - margins are still perfectly valid with components. It's just that component developers don't want to think about how their component may lay out with something else on the page. It's microservices fiefdom on the front-end calling to give up core web development features because people don't want to think about components interacting with others.
Simply put, it’s not a good article.
What does "heavily biased" mean in this context? It's a straightforward article that puts forward a position, a series of propositions supporting that position, and a potential solution.
It's biased in that the author has an opinion he's trying to convince people of by providing arguments in its favour, but that's what writing tends to do (including your comment).
The "banning" stuff is obvious hyperbole[0]. No reasonable reader could conclude the writer means CSS margins should be banned in law.
[0]: https://en.wikipedia.org/wiki/Hyperbole
Any article stating something should be “banned” can’t really be described as a balanced discussion about the usage of that thing.
I’m all for discussions on why usage of something is bad but in the case of margins there’s clearly use cases that are suited to it, which other commenters have highlighted but which the article entirely glossed over.
So the article is more than just written as a persuasive piece; it misses any balance or contextual clarity and thus ends up dishing out bad advice as a result. Bad advice that is so strongly emphasised that lesser experienced developers would easily be intimidated by it.
Now if people want to discuss the strengths and weaknesses of margins and put forward alternative solutions in the process, that at least informs lesser experienced developers about ways to solve their real world problems rather than berating them for not following some misguided idealised view of perfection.
(Yes I know there was some details about alternative ways to implement a margin, but they were crap and lacked any detail, since the article was essentially a rant piece rather than technical document)
https://tailwindcss.com/docs/adding-custom-styles#arbitrary-...
Here's the example linked by the article: https://seek-oss.github.io/braid-design-system/components/St...
[1] https://developer.mozilla.org/en-US/docs/Web/CSS
I don't think that "go read all the MDN docs" is a very useful suggestion. More useful is something like the following, which I don't think you will find anywhere in MDN:
When an element's top or bottom margin collapses with its parent, this may affect the position of the parent, because the minimum of the child and parent's margin will be used to position the parent. (MDN says the child element's margin will fall "outside the parent", but it is not clear that it will be used during layout to place the parent.)
The bigger problem is that CSS is just so complicated and arbitrary. Consider the rule for collapsing margins with parents, from MDN:
> If there is no border, padding, inline part, block formatting context created, or clearance to separate the margin-top of a block from the margin-top of one or more of its descendant blocks; or no border, padding, inline content, height, or min-height to separate the margin-bottom of a block from the margin-bottom of one or more of its descendant blocks, then those margins collapse.
They list five different factors that prevent collapse, one of which ("block formatting context created") is a link to a page that defines it in terms of 15 different constructs or situations in CSS.
On top of that, it appears that the MDN text is in error, because it lists intervening "height" as something that prevents bottom margin collapse, but not top margin collapse (when in fact it does).
It's the unintuitive collapsability that messes up margins.
Padding only works if you know everywhere your component might be used or don't mind remaking spacing decisions every time you use it. In my experience minimizing code needed for each use of a component leads to more coherently styled interfaces, particularly on larger or faster moving teams.
He reccomends spacing at the parent
Moreover,
> Margin breaks component encapsulation. A well-built component should not affect anything outside itself.
Definitely not, margins are an essential part of a component, like a garden around a house, and they make components "usable in any context or layout" (unless the context or layout is stupidly overcomplicated).
* which alone is utter nonsense
The fact that they can be misused does not make them useless.
In a better world, margins would work in a block context (where paragraphs live) but not in flex/grid ones, which take layout in their hands. Another context could be called “constraints-based”, which would space its children relatively, like A.r + 10px <= B.l; B.r = this.r - 10px. Children would expose their preferred margins, which these layout contexts could take or not take into account.
If you want to place a slider between two text paragraphs, the slider isn't a good match for them (even if rectangular, it's far smaller) and you'll have to give it small or even negative margins under the assumption of the text paragraphs having normal, big enough margins.
And this highlights the issue with the idea that "children would expose their preferred margins, which these layout contexts could take or not take into account": a reusable and modular layout should be bottom-up, with components knowing what CSS rules make them look good and containers respecting them. Since the slider is small it can have smaller margins than the text paragraphs, but a container that knows that its middle child is a slider is a complicated and ad-hoc container.
I don’t, I want to put a slider between A and B. I don’t know what’s there from the bottom-up rule. A or B may even have a loadable content, so I know nothing until it’s rendered. If A and B are paragraphs, that’s usually a coincidence irrelevant to the container’s purpose.
So what is the correct way to put a slider between beforehand unknown type A and type B components?
a reusable and modular layout should be bottom-up, with components knowing what CSS rules make them look good and containers respecting them
This approach is good until it’s not. You can’t just write off some layouts as “bad” and call it a day. It’s not modular, it’s pre-styled in a way that involves intimate knowledge about all of components and how they “stack” in advance, which is opposite to being modular.
The components around the slider are not "unknown": it's enough to be sure that, for example, their margins are between 20 and 30 px so the slider is allowed to claim -5px off a collapsed margin without collisions.
I like TeX's box model over CSS which allows for easier "smart" spacing (look up hglue, vglue, hskip, vskip, and eg. care for orphans when typesetting etc.) and smarter column alignment (trivial alignment on decimal point in tables).
While I'd never call myself a designer, I've done plenty of TeX (print and PDF) publications that people have commended for usability and appearance.
Typesetting something to a beforehand known format is radically different problem to a beforehand unknown format.
But TeX typesets to a beforehand known format (I assume you mean target document size) as much as HTML+CSS does (a bitmap canvas of <width> x infinity size): it's not optimized to reflow stuff live, but you can definitely change the page size before every run with a single command, and rendering should (mostly) reflow properly (this would be equivalent to resizing the window, or having differently sized/fine target like a cell phone).
It does not solve the problem of multiple page sizes any better than HTML+CSS, it just provides some nicer and more obvious tools for aligning stuff on the page/screen that could be more easily used to achieve such support.
Typesetting is a rendering a static copy a priori. You can expend a lot more time and resources rendering and reflowing the document. Rendering HTML+CSS, which can be dynamic, is a radically different problem.
I wouldn't be surprised if these posed very different constraints on the possibilities of the layout model
TeX's box model is in no way less optimizable than the HTML+CSS (if anything, it's the opposite due to it being much simpler). It has had a stable algorithm and implementation since 1983, and that implementation was never optimized for reflow like HTML + CSS has. TeX itself is also Turing-complete, which makes processing more expensive by definition, and that's mostly the reason for the slow performance, rather than the box model — and it is from 1983, after all. For some things, the reflow model is even used with TeX today (eg. table of contents generation usually requires at least two passes to "reflow" the output).
>6.6.4 Inspiration from other formatting models In the early design phases of the CSS visual formatting model, other formatting models were frequently consulted for inspiration. In particular, TeX [Knuth 1984] was often brought up in white-board discussions.
As one of its foundations, TeX has a well-defined box model wherein all objects, including individual glyphs, are contained in boxes. The spacing between the boxes can be controlled through TeX commands. In addition to optimal spacing between boxes, TeX also allows maximum and minimum spacing to be expressed. This is referred to as glue (although Knuth suggests that springs is a better term [Knuth&Plass 1981]).
The visual formatting model in CSS is based on a box model, and all elements, both block-level and inline, are turned into boxes. Thus, CSS goes further than most other style sheet languages in creating boxes. For example, DSSSL and P94 do not use boxes for inline elements. However, CSS did not adopt TeX's glue. Although the issue was discussed, it was decided against in order to keep the VFM simple. Glue is very useful when breaking paragraphs into lines, but CSS leaves this problem to implementations. CSS allows, but does not demand, inter-paragraph line-breaking optimizations. Each box in CSS is, however, potentially richer than the boxes found in TeX since it can contain a padding, border and margin bands. CSS also borrows other features from TeX, including the em and ex units.
https://www.wiumlie.no/2006/phd/#ch-css
Håkon also goes into great detail on the historical context and technical requirements surrounding the development of CSS.
I think the reason the CSS box model differs from the TeX box model is because of the different problems they attempt to solve and various contextual difference the technologies developed under. Crucially, it's not because the authors were unaware of the TeX box model or because they thought they could do something better
That also supports my claim that reflowing in TeX's box model would be simpler ("CSS is richer").
I simply highlighted a few things where TeX's box model does a great job for what are commonly hard problems with CSS even today (how do you align columns on decimal points?): I imagine most people, even LaTeX users today, are unaware of the internals, and I hope it's valuable for people to learn of them.
It was never something I had thought about but I got curious so I did some digging.
It's true that some things are much easier in TeX, like aligning on decimals. HTML tables are used for all sorts of crazy so I'm not surprised it's harder to that kind of stuff
I’ve worked with several awesome designers and they all appreciated when I told them this is untenable.
But margins can be incredibly helpful when implementing internals of complex components, and when laying out components next to each other that are not equal peers (like labels with form fields).
Negative margins can also be very helpful in some circumstances, like when a border shouldn't contribute to the space taken by a component, or when components should overlap without resorting to absolute or relative positioning.
Rules without margins are going to be a mess. For one you can't negative margin the padding out of the first titles in a section and other useful negative margin pulls.
Without margin collapse, you're going to need to handle first and last paragraph so they don't have half margin from their container.
Margins are respected across the elements hierarchy, which is especially useful if you're reusing components in react like systems; neither nested paddings nor grids aren't suitable do that.
Anyway, considered harmful articles considered harmful.
There is a time and place for margins. Being thoughtful with them is a better approach than "banning margin from all components."
Should I really ban the use of `margin-left: auto` when positioning my flexed elements? I don't think this article is actually advocating for that, but a novice reader may.
Regarding CSS margins, they are part of the box model even if certain stylesheets neglect them, and the only conflicts they can be involved in are easily solved (a rule for "container x" is more specific than a rule for "x" and can override margins, particularly with parent padding, in special cases) and they highlight genuine design defects: trying to use a component both with and without its "natural" margins (without adding appropriate classes or wrapping containers), trying to specify conflicting margins, trying to fit variable-sized content inside fixed-size containers by messing with the content's required margins, and so on.
It's a shame that CSS doesn't allow the parent element to define how spacing around the child elements should work.
It really would be a shame if CSS didn’t have child selectors, and if they weren’t more specific than bare selectors.
The best way to combat clickbait is to not fall for it, not play into it, to either ignore the article, or to read the article and discuss or critique the content instead of bringing more attention(all press is good press) to the title.
> If a clickbait title will lead to higher engagement, why would an author not use it?
Out of intellectual/professional honesty e.g.?
I think most of us come to Hacker News for interesting discussions, and the torrent of confidently incorrect "this person is wrong" comments is not adding anything to any discussion.
The top comment is already clarifying the title, so any other comment should be unnecessary, especially snarky ones.
The gotcha is another problem in itself: not only it comes from a misunderstanding of the post, a lot of people don't have control over their publishing software, but their advice should be judged on its own merits, not on some "you criticise society yet you participate in it" way [1].
[1] https://knowyourmeme.com/memes/we-should-improve-society-som...
By the way, you broke another guideline in your comment: "Please don't post shallow dismissals, especially of other people's work. A good critical comment teaches us something."
Anyway, I'm just explaining why other people flagged you. You can choose to try to understand the rationale for your flag/downvotes. Or you can cover your ears and accuse everyone else of being pro-clickbait.
I'm not the OP nor dang, so I can't fix it. About talking about it, I already mentioned that this had been done done, on my first comment: The top comment is already clarifying the title. Several people also replied to you.
That comment was made an hour before you made yours. Also the article itself contextualizes the title, and that would have cleared up your misunderstanding.
> Or you can continue posting comments directly to unknown individuals trying to enlighten them on reasons how their behavior triggers you.
Nothing is triggering me. You clearly seem bothered by the flagging from your edits, so I'm trying to explain to you how this community works. I'm sorry that my explanation doesn't satisfy you, but continuously attacking me won't change anything and won't do any good.
Please don't turn this into a flame war. I'm just trying to engage with you to help you understand. Please don't assume ill intent.
All I see is a discussion that’s been massively derailed by a shitty title. If it had a sensible title, perhaps people would be talking about the actual concept that the article was trying to tackle instead of threads like this where people keep having to explain that the title doesn’t match the article.
“Engagement” for the sake of engagement is worthless unless you are optimising for noise instead of signal.
>avoid margins when creating reusable components
so, if this is using margins then they are not using reusable components? I mean, I have a difficult time taking the advice regarding CSS usage from someone not using reusable components.
Aside from all the other things people are saying this person doesn't know about, I don't think they know about the min, max, and clamp CSS functions which when used with margins can be amazing. Not to mention that the need to have different margins in different components uses might be handled with CSS variables, not mentioning that the variable can change due to its context seems an oversight making the rest of the article less than impressive.
on edit: it is of course a cheap shot to argue their site uses margins etc. I just wanted to note that I had sort of a disagreement as to the main takeaway from the article, and then I noted why I disagreed with that takeaway.
We may, as engineers, use tools that internally implement software patterns that we have an academic disagreement with. And that doesn't make us any less dignified in our beliefs.
https://androidinsider-ru.cdn.ampproject.org/ii/w820/s/andro... — a green one here? (this is a hot link)
Edit: The amount of oscillation this comment has had (between -1 and +1) is amazing, I wish I could see total number of up and downvotes..
A ground up HTML rewrite is needed.
I accept that we come to this understanding through our early introduction to language, writing and art. Most people intuitively link structure and presentation when they compose content.
Separating them is incredibly useful. You can see this at a really basic level, in plain text. Lay out a single long paragraph of plain text into lines of max 80 chars, and then insert a word. The layout goes completely wrong and if you don't have tools to help you, you spend ridiculous amounts of time realigning the text. The line-length algorithm you're following (or using) is __totally__ separate from the content. HTML and CSS are this, scaled up to allow fine grained annotation and control of both semantics and presentation, independently.
Basically, Google wants to kill XSLT, and normal web in favour of Javascript, and WASM based web. Why? They don't want people to turn off javascripts, so they can show more ads, and competitors cannot get an easier job making google.com alternative.
The headless components need to be styled in the end, and the guideline present in the article still applies to those cases: outer margins in components causes some headaches.
I didn't suggest it did. It does mean "block that could be reused somewhere" though. Devs should consider that carefully when they're making components. If your block can't be lifted and reused because it relies on the parent structure or it expects something global that's not passed in as a param/prop/whatever then you need to think some more, because you're making something that's not reusable.
One day, someone, somewhere will want to use your component in a way that you didn't plan for. If you've created a hard link to a particular part of your app such as an expectation that the parent HTML structure will look a specific way, then you've made their job harder when you didn't have to.
Yes, that's what the article is talking about.
Even with headless components you need to have CSS somewhere else in the end. I don't know how you're "[leaving] the way things look up to the app that uses them" to headless components, but most people do it with (surprise) other components that belong to the "app" itself. Or with CSS-components.
So, the advice in the article could still apply to them. If you apply a style that contains an outer margin, you might run into the problems discussed by the articles.