Hacker News new | past | comments | ask | show | jobs | submit login
CSS Container Queries in Web Components (mxb.dev)
97 points by mxbck 36 days ago | hide | past | favorite | 75 comments

I've picked up css after ~5 years and I can't believe how far it's come. Flexbox, grid, `clamp()`, content queries, etc. It's a complete different experience now compared to the days of css hacks.

Every time I hear someone complain about CSS I just know they've never used it in the IE6/7 days. Good lord, the amount of hacks, shims, fallbacks, polyfill, obscure stuff you had to do to make it work in IE6, IE7, and my absolute favourite(!) the IE7 compatibility mode which was like IE6 but not quite!

Ever since the wide adoption of stuff like flexbox and grid I haven't dared to complain about not getting stuff to work.

My favorite obscure thing: you sometimes had to add the zoom:1 CSS declaration so the element would "have layout", Whatever that meant, so it behaved the way you wanted.

You also had the various filter: progid:DX… declarations to make things that came with other browsers work on IE using DirectX directives. This would, by the way, break the CSS syntax because of the colon in the value, but fortunately parsers of other browsers would recover at the right place.

You could also run arbitrary JS in this filter property, too. I don't know how this would have worked with CSPs today.

To add to the confusion, the filter property has since been repurposed, and the modern one is NOT related to the older, IE one.

One of the biggest issues at the time was the non-standard box model that IE used and there was no way to tell other browsers to use this box model, nor to tell IE to use the standard box model.

Now both can be used in any browser with box-sizing:border-box (the IE box model) or box-sizing: content-box (the default standard box model). I guess browsers needed to implement border-box for the quirks mode anyway.

Conveniently, IE would happily load specific stylesheets declared in "conditional comments" so it could be possible to fix some things. Or you could use weird syntax like prefixing property names by a star, that the IE CSS parser would not mind but the other browsers ignore. Each version of IE had its specific quirks in its CSS parser so it was possible to target one version or another. Which is fortunate, because the rendering engine behaved very differently from version to version.

The box-sizing property is actually very useful for when you want to reserve space in a percentage sized element with different sizing units.

For example (in SASS CSS):

  .container {
    $footer-size: 2em;
    box-sizing: border-box;
    height: 100%;
    padding-bottom: $footer-size;

    .footer {
      position: absolute;
      bottom: 0
      left: 0;
      height: $footer-size;

Otherwise, one would have to use calc() which isn't supported in older browsers.

Absolutely. By the way, it seems many frontend developers generally prefer box-sizing:border-box, and Bootstrap sets it for all elements by default.

Which can be a little disturbing when you don't know it, work on a project that includes bootstrap and you expect content-box. Fortunately, browser dev tools are good at telling you what is going on.

Thanks, I wasn't aware of this disparity. I handwrite my CSS, been doing it for 21 years now.

If I was to use Bootstrap or Tailwind, I'd likely use @extend and @include to compose my own classes.

A long time ago, I read an article that stated, with authority, that Bootstrap was being misused. That class names like "font-weight-light mt-4 text-white" should instead have been replaced with "subtitle" with CSS:

  .subtitle {
    @extend .font-weight-light, .mt-4, .text-white
The article resonated with me. This approach avoids mixing HTML/CSS concerns and also avoids polluting the CSS namespace. Even if tree shaking and css pruning is applied, I believe this approach would win out in performance for having less classes. I would be wrong if there are tools that will run through HTML and CSS and transform the long bootstrap class attributes into consolidated, shared classes.

Global classes, like in Bootstrap, also violate web component encapsulation.

Global CSS classes are kind of like global variables in programming languages (like PHP.) Sure, they work and used to be common, but we've since moved on to closures and scope containment for performance and reliability.

I thought this when I first encountered Bootstrap, and it is still my opinion today. I think class names should convey intent and meaning, not the look. I'm glad someone wrote on this.

People seem to like bootstrap, but it seems with bootstrap, not only you have to master CSS, but also bootstrap, while without it you only need to master CSS. I'm also used to hand write CSS and I'm a bit at loss when I need to use such CSS frameworks. It seems that some people find it easier to deal with CSS with Bootstrap (including people who don't really like CSS), but haven't really understood this to this day. I know the default behavior of a web page pretty well, but as soon as bootstrap is there, this knowledge is partly gone and my assumptions are broken. It just makes my life a bit harder.

This would be fixed by learning Bootstrap properly but I just don't see the appeal, especially that I noticed defaults that I don't like (the sizing for headings for instance). It does not seem to solve a problem I have. It does provide interesting components like popovers though.

There is a site called maintainable css that resonated with myself regarding CSS naming and approach. https://maintainablecss.com/

Thank you, just learned a bunch from that, unexpected considering how long I've been doing CSS. Cheers.

I've seen things you people wouldn't believe. Clearfix classes assigned to every element. I watched rounded rectangles built in Photoshop, sliced and exported to PNGs, then aligned with tables and a prayer. All those hacks will be lost in time, like tears in rain. Time to design.

Just to give the less grizzled devs among us an idea how much better things are today: 14-ish years ago we all wanted rounded corners, but there was no border-radius (or at least we couldn't use it because IE). So it seemed like the web was full of rounded corner tutorials, and all of them involved jumping through a bunch of hoops. This thread reminded me of this parody of rounded-corners called "How to Make Square Corners with CSS" containing their coveted 84 step process to beautiful square corners in CSS:


want a drop shadow on a div? no problem, just wrap it in 8 other divs and give each of them a different background for the sides and corners

I remember the dumpster-fire days too.

The thing that I can't understand is, why did it take SO LONG to get useable, proper, and intuitive CSS-based layout on web-pages?

I mean, we've had all kinds of rock-solid mechanisms for layout in desktop applications since the dawn of GUI's in the NINETEEN EIGHTIES. Meanwhile, in CSS, people had resort to HTML tables up until sometime in the early naughts, when AWFUL, counterintuitive float-based hacks were part of the "Web 2.0" buzz.

For Christ's sake, just getting fixed side-bars and a width-adaptive central area was called "The Holy Grail" by CSS experts. Isn't that the one of the most fundamental layouts GUI's-- AKA "The Docpanel"? It wasn't possible to get really nice layout without crazy hacks until flexbox in 2010-ish?

Finally, a few years after flexbox, CSS grid comes out, and oopsie, we weren't supposed to use flexbox for overall layout anyway. Now it's CSS-grid for 2D (page layout), Flexbox for 1D (component layout), and floats for what they were originally intended for (putting pictures into a block of text and have the text flow around the pictures).

To be fair, I actually like CSS now. It seems like it's really reached a point where you don't have to cling tightly to somebody's zany overcomplicated framework and can pretty much execute your will without frenetic trial and error.

So NOW it's a success, but it's distressing that I feel CSS deserves nothing more than a sarcastic SLOW CLAP?

> The thing that I can't understand is, why did it take SO LONG to get useable, proper, and intuitive CSS-based layout on web-pages?

Many reasons:

- HTML and CSS are not designed for anything complex.

HTML and CSS at their core are only meant to display a static page of text and some images in a single rendering pass on a computer from 1990s.

- Many decisions in CSS (especially early CSS) are one-off solutions that might not even have correct specifications compared to how people usually use it

Float is really a one-off solution for a very specific subset of layout. The standard box model famously has a default that no one in real world uses, and that IE actually got right. There are more: https://pavpanchekha.com/blog/css-problems.html and https://www.impressivewebs.com/css-the-bad-parts/

- Any solution has to be aware of any previous solution and mistake

Let's say, you introduce flex. How will it work with floats? What about display:inline or display:inline-block? Tables? Inside tables?

Let's say you introduce grid. All the question above plus all the questions on how it will behave with flex.

Let's say you introduce...

- Standards are mostly driven by browser implementors, who are not known for any/much of web work. Additionally, solutions have to be "fully complete including edge cases that maybe one person in the world cares about".

Cant' find the link for that, sorry, you'd have to take me at my word :)

- All that still has to work reasonably fast for some definition of fast, including all the weird interactions between mistakes and other workarounds of past, present, and future

For example, Cassowary constraint solving algorithm for layouts was proposed in 1999, but was rejected because it was deemed too costly to process.

> HTML and CSS are not designed for anything complex.

Yeah, I believe you, I can see how that would have been the thinking back in the 90's. But there started to be significant web applications in the early 2000's.

It's all water under the bridge now, but what if there had been more "throwing away" (deprecation) of the bad stuff and less mitigation with the whims of browser implementors? I feel like we would be in a better position today.

What if the W3C had taken a more standards-based approach with hard PASS/FAIL requirements on styling/layout/semantics rather than "recommendations" that browser implementors have always taken as optional and subject to interpretation?

> But there started to be significant web applications in the early 2000's.

And then you had IE6 and stagnation on the web :)

> It's all water under the bridge now, but what if there had been more "throwing away" (deprecation) of the bad stuff and less mitigation with the whims of browser implementors? I feel like we would be in a better position today.

You could view Canvas, WebGL, WebGPU and WebASM as going in that direction.

> What if the W3C had taken a more standards-based approach with hard PASS/FAIL requirements

W3C has no power over browsers, and is made up of browser implementors (among other people).

Now we're doing "WebAssembly", "WASM", and "WebASM"?!

Ah you young ones only supporting IE6. I still have trauma from supporting IE5!

ie 5...mac edition :shudder:

position:relative on everything if you wanted it to be visible. var undefined; Fun times.

that's nothing, back in my day we had to manually carve the website layout into clay tablets


There it’s fixed

I had been trying to get into Tailwind CSS in recent projects but noticed some of the Bootstrap functionality I tend to like was missing out of the box so with Bootstrap 5 coming out last week I switched gears to start using that for a new project.

The project itself is an update to an older one that was originally built with Bootstrap 2.

For the old one, when I go to print the somewhat detailed tables I'm using show up fine, but in the new Bootstrap 5 version, one of the tables sticks outside of it's container when going to print and for the life of me I've been struggling to figure out a solution that works consistently for the print side of things (which I feel tends to be overlooked quite a bit in regards to CSS). What's even odder, is that when I implement a change that helps with the second table (making it appear contained within the page dimensions) the first table above starts exhibiting the issue of it being outside of the container. Also, in this case, if I were to leave the default styling of the "table-responsive" div containing the table, you wouldn't be able to see the rest of the columns at all when printing (since the scrollbar would show up) so everything I'm describing above is with an override to have "overflow-x: visible" when printing. Some other suggestions online included adding some overrides that use "page-break-inside: avoid;" for tables/tr/td/div elements and "display:block !important;" for the body and div elements but I'm not completely happy with those results, but yup that's been a bit frustrating trying to sort out since I'm not even sure why it's behaving the way it is at the moment.

I haven't kept up fully with all of the Sass/SCSS advancements in recent years but have a semi-decent CSS foundation to build off of (from my understanding those advancements primarily help with some additional programmatic elements that then get pre-processed back into CSS? Along with some syntactic sugar to simplify some of the repetitiveness that CSS can require).

The other big annoyance I was dealing with was related to what appears to be a long-standing WebKit issue related to scrollbars on mobile devices? (for the theme I'm using, I'd scroll down on an iOS device and wouldn't be able to see the very last item in the mobile menu). I found a reference somewhere (probably Stack Overflow of course) that mentioned using "@supports (-webkit-touch-callout: none)" to try and target the mobile browsers specifically and I reduced the height by an extra 65px or so which seemed to be enough to help with that particular issue (the theme utilizes "perfect scrollbar" it seems, but not entirely sure about all of the styles involved). (Before settling on this solution I had already tried out the solution described over here: https://allthingssmitty.com/2020/05/11/css-fix-for-100vh-in-...).

One last item I was dealing with this week seems to have to do with SVG rendering on the desktop vs. on mobile (for a logo). We sort of have a designer on staff but he deals more with print than with web stuff so I asked for a variation of our logo with the name of the application integrated into it and provided back to me as an SVG (since the PNG I had created myself looked slightly fuzzy when it was downscaled to fit the space I was using it in on the page, so I felt an SVG version would look crisper). After swapping things to the SVG version provided to me, it looks pretty good on mobile, but on the desktop (both in Chrome and Firefox), things just don't look as good. Some resources online mention it could be related to the lower DPI of a desktop monitor vs. the retina type DPI of a mobile device, but I don't know...I also saw some mention of a "pixel hinting" approach that might be able to be utilized by the designer in Adobe Illustrator perhaps that might help as well so that's something I've asked him to give a try for me so we can see the results, but I was kind of disappointed about the way the SVG looked as well (and now that'll require a bit of extra time to research/learn/experiment about, rather than focusing more on the application I'm trying to actually build...but at the same time it's semi worth it at the moment since I'm hoping the foundation I'm building with this new web app will be utilized in a couple of other updates that I'd like to make over the coming year, but we'll see how it goes ;-).

I'll postscript this message that I'm not a frontend dev, but since I'm basically a team of one with an eye for certain details/issues, I try and get these sorts of problems sorted out at the beginning of a project so they don't cause issues, but also as a team of one, I really wish that in addition to the backend frameworks that are available (Laravel in my case is the one I'm currently ramping up on, as it's the more or less leader on the PHP side), it would be nice to have a nice frontend option with "batteries included" for a developer to really utilize and not have to worry too much about (Bootstrap has probably been the closest in that regard...I do like a lot of what Tailwind CSS is doing though, and of course it's heavily promoted in the Laravel community, but I just found that it would require too much work for me and too much time...and my workplace isn't exactly software development focused so I have to pick my battles in that regard vs. spending a lot of time getting something basic going vs. getting something shipped for users to start using).

Hopefully one day we'll be completely away from needing to do any sort of CSS hacks (and things have come an extremely long way in the past few years), but at the moment I wouldn't say things are completely hack free yet (at least for us non-100% frontend folks...you all might have some extra magic you can cook up on the fly to solve any problems encountered maybe using what's already available :-).

I’ve been there. The truth is that css media print doesn’t work with anything complex. After spending a week at it back in January, it felt very much like IE6 whac-a-mole. Long story short, I ended up fixing it in python using rst2pdf. Brilliant library.

I was explaining to a much younger colleague the hoops we used to have to jump through to get rounded corners and drop shadows. He honestly thought I was lying when I told him it involved exporting sliced-up images from Fireworks and placing them in tables.

Now it's two lines of CSS.

LOL fireworks! I had forgotten about that.

I used to be a full-stack developer 5 years ago, and while I wasn't an expert I was pretty good with front-end development.

Recently I've started picking up a new side project, and I'm absolutely gobsmacked how far front-end development has gotten in just 5 years. It's a completely new landscape. It feels like I'm having to learn it all from scratch again.

Styling <table> still sucks though. I mean for displaying tables, not layout.

Agreed, and to make matters worse if you mess with the display property on any of the table components (<table>, <tbody>, <th>, <tr>, etc.), or position them anything other then static, you loose the accessibility layout. Meaning that you must explicitly set the role (e.g. <tr role="row">, <th role=columnheader>, etc.) or else with assistive technology wont be able to navigate the table intuitively.

> not layout

email would like a word.

i wish they would at least add colspan/rowspan to css. doesn't cost browsers anything to implement, would make responsive tables a lot easier

making tables a css grid is not an option?

not if it's a really long table, grid fails at 1000ish rows in chrome

tbf, if you have a 1000 row table in html - you might have other problems.

agreed. To be fair in my case it was a 500+-row table that i was trying to split into 2 rows each on small screens. Still arguably way more than reasonable, but this was a situation where it's legacy code and I could only change the html/css. I ended up doing each row as it's own flex, which is slightly annoying since it can't adapt to the contents being displayed, and I had to just stipulate widths for each column, but I guess it's not hard to see why dynamically calculating the widths would be a bit laggy.

Firefox handled arbitrarily big grids like a champ though

I've been really impressed with the simplicity of

    display: flex
    gap: 10px
No more having to deal with :first-() :last-() selectors to remove margins

gap only applies to the inner contents tho - so still need to (potentially) handle outer margins. still, css grid is wonderful...just waiting for sub grids so i can do away with some hacky js height calculation i still need to do.

Yea, I should've clarified I meant not having to deal with margins for children elements. Thankfully with gap, I rarely have to worry about parent container's margins

What are some good resources to learn modern css?

I really liked this zine by Julia Evans: https://jvns.ca/blog/2020/11/22/new-zine--hell-yes--css-/ It helped me get over the hump of realizing most modern CSS is a very simple and clear subset of all CSS. I.e. don't get bogged down in legacy or browser specific quirks and eccentricities--stick with modern conventions like flexbox, grid, etc.

kevin powell on youtube makes good videos, it's how i finally jumped into flexbox and grid a while back. I think for something like CSS videos really are a good medium for teaching

I keep having mixed feelings about web components...

Why can't we have templates, custom elements and scoped CSS without JS?

If I remember correctly some WHATWG members are trying to settle on a syntax for declarative shadow DOM[1]. I personally wouldn’t hold my breath for it though, I don’t know how enthusiastic the rest of WHATWG is about this.

In the meantime I would look for technology which applies server side rendering to your web components.

1: https://web.dev/declarative-shadow-dom/

> I personally wouldn’t hold my breath for it though, I don’t know how enthusiastic the rest of WHATWG is about this.

DSD is already shipping in Chrome 90 and Edge 91. I suspect that will put pressure on others to either adopt or continue with the standardization process until it addresses their outstanding concerns.

Why server side rendering? Content that needs rendering just put in the tree and target a slot. My perception was this is the best practice. I haven't used the lit included intl translation and am curious if and how these concerns work.

Doesn’t that still require JavaScript?

As I understand it (and I might not; I don’t have servers to do SSR) people want SSR for two reasons. a) To allow users that don’t have JavaScript for some reason to at get good UX, and b) to prevent the styles from kicking in after the initial render. There are ways to author your components in a way that fixes (b), but I’m not aware of any technique other then SSR that will fix (a).

I don't think anyone is really targeting JS-less users. It's mostly for faster first renders and the examples of JS-less is to typically show something has been SSR'd and not yet hydrated / not loading anything that isn't needed for first render.

Isn't SSR also attractive because it's simple?

For things that aren't web apps, like blog/wiki/docs/news-site the primary content is text + images + links.

Is it not attractive to avoid JS where not needed? And only use it for the tiny bits that really do need it.

There's no generic HTML import function yet. Right now you can only have a page pull in javascript (through a script tag or ES module import) or CSS files, but critically not component HTML files. So it's hard to have a component defined by HTML and CSS that can be shared and imported in other pages. There's no "grab this HTML page and give me the DOM to insert/clone/use how I please" in pure HTML. The closest thing is iframe but it's not really a general component tool. For better or worse JS is currently the way to share logic and fragments between HTML pages. There was a working group looking at HTML imports but I think it all got spun down.

HTML Imports did exist and was the general authoring idea for web components, but it didn't work exactly as you described and Apple and Mozilla shut it down. Polymer had to release a new version that was JS focused and caused a huge painful migration for users.

I am not very familiar with the technology. Under current standards, is it possible to choose to write a web component that does not have any JS, it just uses CSS to take advantage of these things?

No, a web component by definition must be a class that inherits from a HTMLElement base class and implement some basic rendering functions. In addition you must make the browser aware of the component by calling a CustomElementRegistry.define function with your class and the desired component name. So at a minimum there's about 5-10 lines of boilerplate JS necessary to define and register a basic component.

You described a Custom Element a Web Component is a branding phrase for component that uses the four following specs:

* Custom Elements

* Shadow DOM (seems to be optional in practice)

* HTML Template Elements

* ES Modules (formerly HTML Imports)

that's arguable, the encapsulation web components affords is built into the system and simply being exposed by way of this bucket of technologies

When compared with React and similar solutions doing the same and similar thing(s) it runs circles around them... or am I misunderstanding the comment and is the position asserted that container queries (not web components) are the effect?

What is the inner-platform effect comment applied to specifically?

> What is the inner-platform effect comment applied to specifically?

Adding more flexibility to CSS/HTML without requiring Javascript would eventually turn CSS and HTML into to the equivalent of a general purpose programming language, which we already have in the form of Javascript.

Right, but maybe later versions of CSS won't be indistinguishable from malware for basic web browsing purposes.

> Each of these books is a custom element, or “web component”.

I always wondered about custom 'web components'. Is it safe to do something like this? -->



    <red>I should be red</red>
It works in latest Firefox. It feels weird being able to create arbitrary custom elements like that!

Short answer: No. There is no guarantee that a future HTML spec will include a standard element <red> which will affect yours. For your element to be a legal custom element it must include a hyphen (e.g. <my-red>).

Longer answer: What you did here is a simple CSS selector using a tag matcher. Each tag with the name "red" will be matched and styles applied. If you want some custom script applied when this kind of element is created, attached, destroyed, etc. you must create a class for it and register it to the custom element registry[1]:

      class extends HTMLElement {
        // ...
Now you have a custom element. But when people normally speak of web components they are talking about scoped elements, which means styles and idrefs are encapsulated. For that you must attach a shadow DOM[2] to your element:

    class MyRed extends HTMLElement {
      constructor() {

        const shadowRoot = this.attachShadow();
        const style = document.createElement("style");
        const slot = document.createElement("slot");

        style.textContent = ":host { color: red; }"

        shadowRoot.append(style, slot);
1: https://developer.mozilla.org/en-US/docs/Web/API/CustomEleme...

2: https://developer.mozilla.org/en-US/docs/Web/API/Element/att...

Thanks for clarifying

IIRC that's a Firefox quirk and doesn't work in every browser.

Do you know what the quirk is called? Is there a blogpost detailing this strange method? Is there any mention of it in the web standards sites?

I don't believe it's a quirk. Browsers are supposed treat tags they don't recognize basically the same as a <div> (or some other reasonable default presentation). It's intentionally designed that way for forward compatibility. We rely on this behavior when we provide some content inside an <object> tag for browsers that don't support it.

Fun fact: <blink> is an HTMLUnknownElement. What GGGP did is essentially the same as:

    blink {
      animation: blink 1s steps(2, jump-none) infinite;

    @keyframes blink {
      to {
        opacity: 0;
Now when you write <blink> in your HTML you will essentially get an HTMLUnknownElement with the specific style of blinking every ½ second.

I guess the other browsers caught up because I remember trying it in a few different browsers after doing it in Firefox and it only worked in Firefox.

Yes, that is safe. It was introduced in 2014. I believe it should work in most browsers. (Rough testing shows it working for me in Firefox, Chrome, Safari).

Is there some page/article/reference to that method that you know of?

Custom Elements [0][1] is the specification that came after the implementation was already gaining use.

[0] https://www.w3.org/TR/custom-elements/

[1] https://html.spec.whatwg.org/multipage/scripting.html#custom...

Thank you!

Does anyone know if React will be able to interop with this? Certainly there are solutions to letting a React component re-render based on its own width, even as that might change over time. But I imagine there would be performance improvements to let CSS container queries handle all styling for a component, rather than needing to go back into JS land every time. And because said CSS would be scoped, it would make CSS-in-JS possible without needing to add auto-generated prefixes etc. You'd perhaps need your React component (not each component instance) to maintain a template for itself, which might be tricky.

If I remember correctly, React web component support is limited. But Preact explicitly supports them, as well as many other JSX libraries.

Why would you want React interop for the styling? What would that even mean? Struggling to understand the use case here.

I tried to read through this I couldn't figure out what problem was solved. Does anyone have TLDR?

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