Lately I’ve been sharing some CSS Tricks I’ve stumbled in to while trying to solve some problems on client work. It’s been fun uncovering new little solutions.
On both of those, some alternative solutions people proposed were using negative margins and calc()
. It’s great if you have a clever way to do things already, but I noticed that I personally experience a phobic reaction whenever negative margins are proposed as a solution. For some reason, I don’t trust them whatsoever.
But real quick tho: I’m not going to declare an anti-pattern or add some moral implication to say you’re “wrong” if you use some perfectly valid technology. I’m trying to diagnose why I feel so strongly untrusting of negative margins.
On a high level, I think it could be emotional baggage from the old Internet Explorer days. Different box models, really different math engines, subpixel rounding errors. When you used display: inline-block
on a navigation, you’d have to negative margin the whitespace with a magic number. Uf.
Standardization around box-sizing: border-box
and display: flex
has solved a lot of those ancient problems. Simply put, kids these days don’t have this problem. Now that probably comes across as Old Man Yells At Cloud, but I actually envy the freedom that comes from those problems not existing anymore. I often think about how neat it’d be to reset my brain and to be able to write only modern CSS.
On a lower, more technical level, negative margins can be tricky. I prefer percentage-based horizontal margins and padding becuase it a allows a column of content to maintain a good CPL measure longer while expanding the viewport. Where it gets weird is %
-unit margins are based off the parent, not the viewport. So a viewport margin’d parent element, and a negative margin’d child element do not have the same margin. Maybe you can use static px
, em
units instead for exact negative margins, this may work for your implementation, but now the CSS solution is less fluid and forcing your content to max-width
or hit a breakpoint sooner.
On to calc()
, which is awesome. The support is pretty great too but whenever I write a calc()
statement in the back of my head I hear a ghostly voice saying, “That doesn’t work on Opera Mini or UC Browser…” Uf.
But let’s just pretend ~16% of the global browser market share doesn’t exist… It’s easier.
When I see the margin-left: calc(-50vw + 50%)
or similar margin
+translateX
trick to shift the whole column of content, my brain imagines a Jenga tower positioned on a food cart moving side to side. This is probably unfair paranoia. But what I do notice is that this trick has the potential to introduce a slight horizontal scrollbar, which you probably didn’t notice on macOS. Now we’re in shifty viewport territory. The way around that is body { overflow-x: hidden }
but you’ve mixed concerns and again your <article>
component is dictating your <body>
component.
In someways negative margin confounds itself with position. That’s maybe my biggest beef. Margin is for controlling whitespace between elements. Using negative margin to break the container and annex whitespace seems more like a position issue (e.g. “I want to position this outside of the container”).
And sometimes negative margin is used to counterspell the introduction of a positive margin.
Maybe I’m a margin purist. To the extent that I like most of my vertical margins to go only one way: margin-bottom
. Margins do a cool thing where they collapse on eachother, but I’ve found that only managing margins in one direction simplifies my cognitive load quite dramatically. So when I see a negative margin, my reaction could be rooted in the fact that not only does this violate my personal One Direction policy, it compounds it into positive and negative values.
So that about sums up how I feel about negative margins. For me, the …wait for it.. negatives outweight the positives.