Hacker News new | past | comments | ask | show | jobs | submit login
What does 100% mean in CSS? (2020) (wattenberger.com)
325 points by feross on July 9, 2021 | hide | past | favorite | 68 comments



Sadly the most interesting CSS percentage mechanic is missing there:

    background-position
Unlike all other cases, here `background-position-x: [25]%` means:

> "Place image so its inner left [quarter] boundary matches inner left [quarter] boundary of its container."

So 0% = align left edges, 100% = align right edges, 50% = align centers (= center) etc. Super intuitive on the first sight, but I was quite surprised how thought-out it was underneath.

https://developer.mozilla.org/en-US/docs/Web/CSS/background-...


So it's equivalent to setting:

    left: x%;
    top: y%;
    transform: translate(-x%, -y%);


I use this all the time. One of the best ways to reliably center absolute elements.


I mean… how else would you implement it? In GW-BASIC (when I was 10) I created a windowing system and that’s pretty much the only way to do it: Calculate the gap remaining among the parent and apply the rule on the parent. Otherwise you always end up mistaking the calculation and having your element overflow.


How else, you ask? As a percentage of the background clip box would be the obvious possibility. It’d be less useful, but it’d be arguably more consistent with percentages just about everywhere else. (Though, being based on the element’s background clip box rather than its containing block’s content box, it would still be somewhat different.)

It’s common for people to wish that percentages worked this way with other properties, because in some cases that’d be useful, but they don’t. (Example: margin-based centring, `width: 20em; margin-left: calc(50% - 10em);`.)


Just a little correction: percentage values are computed based on the element's _containing block_, not parent.

Most of the time, an element's containing block is its parent, but not always.

For more on this: https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_...


I found the rule about absolutely positioned elements interesting given that I often thought their containing block was the closest relatively positioned parent. As outlined in that documentation, though, it's just the closest element that is not statically positioned.


Oh, wow. That explains a few baffling bugs I’ve seen.


Wait there are sooo many more edge cases of percentages! When this article finished I think it should be half way through or even one third of 100% weirdness.

Examples: with flexbox and/or tables, 100% behaves differently. What about 100% vs 100vh/vw? This would be very nice to show here as well. As others note, background-position or background-size. Collapsing margins might be interesting, but probably not the best fit for this example. How other types of `display` interact with the 100% (e.g. `inline` just ignores it). As it's just very briefly touched, but how box-sizing affects the height/width. SVGs viewBox, canvas, hiding navbars on mobile, body's default width/height, the trick of `width: 100%; max-width: 1200px; margin: 0 auto;`, etc. there's such a vast amount of topics relating/breaking the concept of 100% in CSS that it's mind-numbing.


And that's just scratching the surface! There are all sorts of additional quirks, e.g. on mobile browsers the URL bar and the bottom bar (only on some OSs) will be ignored in the calculation, while the keyboard being toggled will not, which can cause all sorts of issues unless you combine it with viewport heights too: https://css-tricks.com/the-trick-to-viewport-units-on-mobile...


My CSS skills are rusty. It has been 10+ years since I stopped except for the occasional upkeep and maintenance of my own websites.

However, does this not make it much easier to understand if you are clear and understand the CSS Box Model[1] very well. I remember visualizing it in my head in kinda 3D model of the CSS Box, whenever something obvious do not work while placing objects on the page/layout for the browser. Once you know where your bearing and browser quarks, either you position your mark or find another way inside the Box.

I'm hoping they haven't change the CSS Box Model.

1. https://en.wikipedia.org/wiki/CSS_box_model


and the interesting "trick" I learnt the other day for fixed/absolute positioning, if you add

  inset:0rem;
  margin: auto;
it will center vertical and horizontal it without having to translate it

courtesy of Kevin Powell - https://www.youtube.com/watch?v=HOM47v73yG8 ( who I've found to be an amazing resource for learning all kinds of CSS info )


Note that inset is a very recent introduction, only supported by Firefox 66+, Chrome 87+ and Safari 14.1+ (14.5+ in iOS). It will take quite a while to use it without thinking.


Tooling can take care of these things, letting you write in the logical property style and translating it into the physical property style for compatibility.

e.g. https://github.com/csstools/postcss-logical


Why not you polyfill it if you care enough to hesitate?


Note - this method requires the element have a height defined; or a height derived from a declaration like `aspect-ratio`

That's because `inset: 0rem` is equivalent to `top: 0rem; right: 0rem; bottom: 0rem; left: 0rem;` - which is a well know technique to force 100% height.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/inset

[2] https://codepen.io/leepowers/pen/KKmgpwB


In my limited experience I find CSS examples always make things look simple, but then in reality I'm forced to do something stupid like this for a 400px canvas:

            left: 50%;
            margin-left: -205px;
            border: 0px;
            width: 410px;
Because when sized to 400px it always clips 10 pixels of the canvas.


i'd have to poke around to be sure, but i have a suspicion:

    box-sizing: border-box;
    width: 400px;
might be the fix for that scenario


This is why I knew how to be a frontend engineer at one point in life but never pursued it past the early 2000s.

The brainpower wasted on web layout is immense.


This is how I know you haven't touched CSS since the early 2000s - the bad old days are gone, flex and grid have been here for years and years.


Responsive design did this. Early 2000s there was only 1024 x 768px or a little above maybe.


The quest for equal height columns and people thinking “how hard can it possibly be to vertically center a div?” predate responsive design


I’m not sure it’s a waste. Yes, CSS layout is complex, bordering on stupidly complex. But I’m not aware of any other reflowable layout system of comparable power. The sheer amount of pain it takes to wrangle something like CSS floats out of TeX—on a fixed-size page!—certainly makes me appreciate just how difficult the problems CSS solves are.

Though it sure would be nice if people were exploring other approaches to reflowable layout without tying themselves to CSS and modern browsers’ codebases.


CSS grid and flexbox have resolved most of those issues though.


What about UI development is a waste?


When you want to do something simple but you have to bring the entire philosophy of CSS into consideration to figure out what the right way to do it is.


Its a common misconception that CSS is easy, that's its not a programming language. Its however one of the most difficult to understand. You can write CSS a whole career without understanding the basics, and responsive design made it exponential harder. And there are popular anti-patterns such as trying to overwrite an existing css file... But if you do learn it - its very powerful, and much better then defining design rules in JS or XML or a graphical design tool.


Doing it in browser. Android, iOS, native macOS apps, QT, none of them have the insanity of layout that is CSS. I bet most other frameworks don't as well, but those are the 4 I'm familiar with. CSS is the odd man out when it comes to being utter shit at layout, and yes that is including flexbox and grid.


That you have to redo it all the time, as in kitchen remodels.

Blame it on folks outside of dev? I would ban the word “modern” if possible. Everyone thinks that it’s obvious but no one seems to be able to define it once and for all, lol


the amount of blood sweat and tears spent trying to center something before flexbox


Only vertical centering was ever tricky


I still find it hard to believe that there is no CSS rule for "100% of viewport width, excluding the vertical scrollbar width".


scrollbar-gutter

https://developer.mozilla.org/en-US/docs/Web/CSS/scrollbar-g...

Not something you can actually use though.


Not gonna lie, the last example made me happy, but my practical side was screaming "just use flexbox, jeez"


Or table


Tables are not a layout tool, and you'll cause more problems than you solve by using them that way.


Modifying tables are extremely difficult after they are created.


Tables can be set to display: block/flex/grid like anything else. Not that I recommend.


if display:flex is not good enough display:grid will most like help.


I'm a little embarrassed to admit that I've been working with this stuff for decades and I just now found out that margin and padding top is based on parent width if expressed in percentages. I'm only a little embarrassed because who expresses margins in percentages anyway.


You never needed to set some flexible containers dimensions to have some precise aspect ratio? Up until very recently [1] the "padding hack" used to be the only option…

https://css-tricks.com/aspect-ratio-boxes/

[1] Recently `aspect-ratio` got into evergreen browsers: https://developer.mozilla.org/en-US/docs/Web/CSS/aspect-rati...


Exactly, I do this at least once a year, enough that I don't need to search anymore for the actual CSS (I just need to try two variations when I mix `padding-top: ratio%` or `padding-top 1/ratio%`)


Nope, never needed to do that. I've mostly only worked on some extremely unique use cases that use the browser in non-standard ways though (games, vehicle control, IDEs).


It sure is useful when hacking together “always-square”, responsive elements.

But otherwise you’re right, it doesn’t really come up.


Amelia is an awesome person and continues to post awesome, useful content.

I always trip up on height/width being a % of the parent, and just default to using vh instead.


Oh yes, what is 100% VH on mobile phones with these native sticky menúes on the bottom or top, some activated by swiping screen, they behave kinda like amp pages, but even worse imo.


What's going on with the the 'f' in the first `.self {`? I struggled to convince myself it wasn't a speck on my screen even with it following my scroll. The later boxes don't feature it.

Edit - Ah! - it's clear with the 'height' slider dragged up: it's one of the dots from the background (except it isn't in the background) grid.


> The surrounding blue box is the parent element.

(R: 93, G: 200, B: 195) That's more green than blue. When you consider that humans have stronger green color preceptors it's definitely green.


You might be interested in this article: https://en.wikipedia.org/wiki/Blue%E2%80%93green_distinction...

"Definitely" green is a difficult assertion to make universal. It's true that it has slightly more green than blue in the sRGB space, but the blue/green boundary is not as culturally universal as you may expect


I would say turquoise cause it is probably the closest named color used in my language. I can recommend a dive into the field of blue-green distinction science.


That puzzled me too (“that’s not blue, that’s more like aqua”). I thought it was my monitor or something.


See also: Cambridge Blue


This is great, very high quality!

However, I'd also highlight the "padding" area in the box, so the "#Padding" example became more self-explanatory.


What percentages refer to is defined on a property-by-property basis in the specs, so while groups of properties typically have the same semantics, this isn't globally true. (For example, the background-position case already mentioned.)


The slider knobs aren't vertically centered for me on that site (iOS Safari).


Should've used <input type="range"> instead of reinventing that particular wheel. They may not have liked the need to use multiple vendor-specific pseudo-elements to style them.


Welcome to CSS


Same here on Android Chrome


Is it only me whose "just give me the gist" button is not working and only jumping back to top of the page? (Browsing on iPhone iOS 14.6)


Does on chrome desktop too.


100% mean that you will spend an hour trying to find that element with a margin that causes a page to wobble when you scroll it.


Damn, somebody plz develop a sane alternative to CSS.


How would that look in your opinion?


To be fair, newer CSS elements such as flex do exist.


It is actually fine. The damn libraries and frameworks make it wonky.


Consider the fact those frameworks exist in the first place. It suggests that people find the need to fix CSS in some way.


Or people like building frameworks.


Because people still think that CSS is something beneath their dignity and not worth learning.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: