Hacker News new | past | comments | ask | show | jobs | submit login
Layout Breakouts with CSS Grid (ryanmulligan.dev)
137 points by clairity on Oct 11, 2022 | hide | past | favorite | 15 comments



> In the last version of my site, selected elements – images, code blocks, quotes – were made wider than the page content area using negative margins.

Yes, negative margins are often (not always!) a bad idea. Especially for something like a full-bleed layout. The other way around makes much more sense and does not need Grid. Make selected elements narrower than the main section. That has worked for a long time and still works today.


I’ve used this technique, with some tweaks, and it’s great. For my usage I generally want full-bleed sections to extend their background but to have their inner content width the same (or close to the same) as normal content. It’s trivial to do, but might not be obvious if you’re not comfortable yet with CSS grid: you can nest the same technique, eg

  <div class="content">
    <div class="full some-bg content">
      <!-- Container bg is full width, everything inside is normal width -->
      <div class="feature">
        <!-- Container bg is full width, everything inside is feature width -->
      </div>
    </div>
  </div>


right, but that's the old, divitis way of doing it. using grid this way let's you set all the children to the content width and then selectively break out of that with just a class on the child element (without extra divs).

i use a responsive gutter in my default grid that is akin to the article's technique, for the same issue that sometimes you want a little padding and sometimes you want full bleed (usually for just the background). once subgrid comes to chrome, it will be even easier to control content width without divitis.


> right, but that's the old, divitis way of doing it. using grid this way let's you set all the children to the content width and then selectively break out of that with just a class on the child element (without extra divs).

I think you may have misunderstood my comment. I’m saying you can use the grid technique described in the article and nest the technique to achieve similar results within sub-sections. Note that I used the classes defined in the article. My stated use case is exactly “usually just for the background”. My HTML only differs from the article’s example HTML by adding the content class to the full-width element, and a class which would hypothetically add the background to that element. I didn’t add any extra divs.


yah, that's the kind of thing subgrid is meant to solve. in my head, the structure looks more like:

  <body class="content">
    <header class="popout"></header>
    <main></main> <!-- implicitly in the content track -->
    <footer class="full"></footer>
  </body>
you shouldn't have to add an extra div inside <main> to be able to use the parent grid. so you subgrid on <main> and get the benefits of just adopting the parent grid for popping things out, rather than nesting with extra divs/classes.


There is no extra div! The classes are necessary if you want to support the >90% of users whose browser supports grid but not su grid. My example, adapted to your preferred nomenclature, the “extra” classes renamed for their CSS functionality equivalent, and some content added:

  <main class="grid">
    <h1>I’m normal content width</h1>

    <p>Ideally you wouldn’t need that grid class for this. But it keeps the CSS DRY for…</p>

    <section class="full some-bg grid">
      <h2>I’m normal content width too</h2>

      <aside class="feature">
        <p>I’m “feature” width!</p>
      </aside>
    </section>

    <p>The “extra” class on the section above is <b>currently</b> necessary because…</p>

    <section class="full some-bg">
       <p>Whoops, no subgrid support? I’m full width on 95% of browsers currently in use!</p>
    </section>
  </main>
It’ll be cool when those classes can go away. You can certainly just make `full` always apply the main grid styles if you have no use case for full width sections without a grid. Or even have distinct `full` and `full-grid` classes, but you’re just swapping a character at that point.


Love how this is possible in such a clean way now. Layout breakouts are one of those things that look simple, but if done incorrectly can lead to terrible bugs, issues with scrollbars, etc.


> Love how this is possible in such a clean way now.

Yes. What I would've given for CSS functions 20 years ago!


ok this is a fantatsic solution. took me a while to get why this is better than joshwcomeau's solution, but now i am using this as my default.

I made a responsive version here: https://github.com/sw-yx/spark-joy/blob/master/README.md#lay...

  .swyxcontent {
   --gap: clamp(1rem, 6vw, 3rem);
   --full: minmax(var(--gap), 1fr);
   --content: min(65ch, 100% - var(--gap) * 2);
   --popout: minmax(0, 2rem);
   --feature: minmax(0, 5rem);

   display: grid;
   grid-template-columns: 
    [full-start]
    [feature-start]
    [popout-start]
    [content-start] var(--content) [content-end]
    [feature-end]
    [popout-end]
    [feature-end]
    [full-end]
  }

  @media (min-width: 640px) {
   .swyxcontent {
    grid-template-columns:
     [full-start] var(--full)
     [feature-start] var(--feature)
     [popout-start] var(--popout)
     [content-start] var(--content) [content-end]
     var(--popout) [popout-end]
     var(--feature) [feature-end]
     var(--full) [full-end];
   }
  }


I arrived at a somewhat similar grid https://florian.geierstanger.org/blog/css-layout-grid


Your modification is actually harming the responsiveness. What’s there already handles responsiveness perfectly, whereas your alterations break the whole point of the exercise, bleed, as well as breaking column centring.


i effectively set the differences to 0, to let it bleed on mobile.

what do you mean breaking column centring? it looks fine on my test https://deploy-preview-127--swyxkit.netlify.app/layout-break...


With the code you posted in this thread paired with the proper markup, below a viewport width of 640px the column will be hard against the left edge, with a double gap (or a bit more, depending on font metrics) on the right.

The problem is you’ve put this inside a container that already has a side gap, which is not how it was supposed to be used. Inspect the grid tracks on the original article at various viewport sizes. Full bleed means that the item goes right to the edge of the viewport.


How does that slider in the top left work?? Very cool site!


It appears to use JavaScript to set a data attribute on the <html> element, and then the CSS has selectors to match that data attribute and set some color variables. There's also a transition CSS property on the elements that change color to achieve the fade effect.

Pretty simple solution and looks great.




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

Search: