a 50/50 items in the -- no wrapper mindset with css grid

Hi Kevin, i really love the approach of getting rid of container and wrappers, like you showed in this video. https://www.youtube.com/watch?v=c13gpBrnGEw ... My question using this approach. How would you make a section have in it two 50% sections that are full-width (meaning one section goes from full-width-start to "content-middle" and the other one goes from "content-middle to full-width end. In each of those sections, the hero-left section the content is align on the content-start to the "content-middle" and the hero-right section content is align with "content-middle" to content-end Like theses 2 examples :
Kevin Powell
YouTube
A new approach to container and wrapper classes
The wrapper or container is probably the most common design pattern around, but after coming across an article by Stephanie Eckles looking at how we can use a grid to emulate a container, and have simple breakouts — https://smolcss.dev/#smol-breakout-grid — I had an idea of how we could do this to completely drop the idea of containers, and then...
No description
No description
20 Replies
Skylark
Skylark12mo ago
I think you’d put the pair into the grid as full width and then either flexbox or grid them into position
districtw
districtwOP12mo ago
I'm not sure i understand what you say
Js23
Js2312mo ago
You can flex of the following way: the parent must be contain display: flex then on children must apply of property flex: 1 1 50%. Remember that flex is a shorthand the following properties flex-grow, flex-shrink and flex-basis precisely in this order
.parent {
display: flex;
align-items: center;
}

.parent > * {
flex: 1 1 50%
}
.parent {
display: flex;
align-items: center;
}

.parent > * {
flex: 1 1 50%
}
districtw
districtwOP12mo ago
And how do you align the content inside the div. The left div, you wanna have it align with the content-start line. ? The right div, you wanna place it the content-end line ?
Js23
Js2312mo ago
i believe that you can use inside parent the justify-content: space-between oh i think it was justifay-items: space-between
clevermissfox
clevermissfox12mo ago
You were right initially, in flex it’s only “justify-content, align-content, and align-items”. Grid has all of them , including “place-X” and “X-self”.
Kevin Powell
Kevin Powell12mo ago
I've been thinking about this too actualy @Js23 - I'd probably make another grid line, so it's something like:
grid-template-columns: [full-start left-half-start] ... [content-start] ... [left-half-end right-half-start] ... [content-end] ... [full-end right-half end];
grid-template-columns: [full-start left-half-start] ... [content-start] ... [left-half-end right-half-start] ... [content-end] ... [full-end right-half end];
It does mean, for the part between content-start and left-half-end, you'd need to do something like `calc(var(--content-max-width) / 2), so half ends up in one column, and then the same thing on the other side. If this doesn't make sense, let me know 😅 If you go all-in with this method, you could come up with a bit of a disasterous looking bit of code that could be really robust though. I'm thinking of building part of an upcoming talk around the idea, lol. Cause you could have full-width, full-left-only, full-right-only, extra-wide, extra-wide-left-only, extra-wide-right-only, wide, wide-left-only, wide-right-only, narrow, narrow-left-only, narrow-right-only, and so on.
districtw
districtwOP12mo ago
Interesting I'll try that tonight. I did try splitting the content part in 2 and putting a middle line and adjusting the content width accordiagnly (instead of 100%, I have put 50% twice). But it did not work. For some reason I haven't found yet, the grid just broke.
grid-template-columns:
[full-width-start hero-lt-start]
minmax(var(--padding-inline), 1fr)
[breakout-start]
minmax(0, var(--breakout-size))
[content-start menu-start]
min(50% - (var(--padding-inline)), var(--content-max-width))
[hero-lt-end hero-rt-start]
min(50% - (var(--padding-inline)), var(--content-max-width))
[content-end]
minmax(0, var(--breakout-size))
[breakout-end menu-end]
minmax(var(--padding-inline), 1fr)
[full-width-end hero-rt-end];
grid-template-columns:
[full-width-start hero-lt-start]
minmax(var(--padding-inline), 1fr)
[breakout-start]
minmax(0, var(--breakout-size))
[content-start menu-start]
min(50% - (var(--padding-inline)), var(--content-max-width))
[hero-lt-end hero-rt-start]
min(50% - (var(--padding-inline)), var(--content-max-width))
[content-end]
minmax(0, var(--breakout-size))
[breakout-end menu-end]
minmax(var(--padding-inline), 1fr)
[full-width-end hero-rt-end];
I really love your approach @Kevin and looking to build a project with it. I always been a lover of as pure html and css possible and this is a great way to acheive it. Even if the grid template is a mess, at least the mess is only in one place. Not every where.
Kevin Powell
Kevin Powell12mo ago
Even if the grid template is a mess, at least the mess is only in one place. Not every where.
💯 !! That's exactly how I see it. I pasted what you had in codepen (and gave all the custom props some filler values), and it works for me 🤔 Is it possible one of the custom props isn't matching up?
districtw
districtwOP12mo ago
@Kevin Thanks ,, i'll take a closer look tonight After a few tries, I have come to be able to do it but with some subgrids.
districtw
districtwOP12mo ago
It does work when I put fixed sizes in the grid declarations. But when I come to changing to the more flexible values with the min function that the layout breaks out.
min(50% - (var(--padding-inline)), var(--content-max-width))
min(50% - (var(--padding-inline)), var(--content-max-width))
Ok I got it to work . I just realised that if I had 2 cols now instead of one I needed to split all values in half too.
min(50% - (calc(var(--padding-inline)/2)), calc(var(--content-max-width) / 2))
min(50% - (calc(var(--padding-inline)/2)), calc(var(--content-max-width) / 2))
Now just need to make it responsive Still unfortunatly this declaration of grid-template-columns is pretty ugly.
grid-template-columns:
[full-width-start hero-left-start]
minmax(var(--padding-inline), 1fr)
[breakout-start]
minmax(0, var(--breakout-size))
[content-start menu-start hero-left-content-start]
min(
50% - (calc(var(--padding-inline) / 2)),
calc(var(--content-max-width) / 2)
)
[hero-left-end hero-right-start hero-left-content-end hero-right-content-start]
min(
50% - (calc(var(--padding-inline) / 2)),
calc(var(--content-max-width) / 2)
)
[content-end hero-right-content-end]
minmax(0, var(--breakout-size))
[breakout-end menu-end]
minmax(var(--padding-inline), 1fr)
[full-width-end hero-right-end];
grid-template-columns:
[full-width-start hero-left-start]
minmax(var(--padding-inline), 1fr)
[breakout-start]
minmax(0, var(--breakout-size))
[content-start menu-start hero-left-content-start]
min(
50% - (calc(var(--padding-inline) / 2)),
calc(var(--content-max-width) / 2)
)
[hero-left-end hero-right-start hero-left-content-end hero-right-content-start]
min(
50% - (calc(var(--padding-inline) / 2)),
calc(var(--content-max-width) / 2)
)
[content-end hero-right-content-end]
minmax(0, var(--breakout-size))
[breakout-end menu-end]
minmax(var(--padding-inline), 1fr)
[full-width-end hero-right-end];
But it works like charm. thumbup
Kevin Powell
Kevin Powell12mo ago
I mean, the point of it is to put it in place so it just works. Who cares what it looks like 😅. Some people like to complain about readability, but the readability and maintainence come from the easy way to adjust it through custom properties.
Skylark
Skylark12mo ago
It's all clearly labelled which is a good thing and worst case scenario you can include an ASCII diagram to show how each area of content should show
| | | | | | |
| . . hero . . |
. . | content | . .
. | . feature . | .
| left content | . . .
. . . | right content|
| | | | | | |
| . . hero . . |
. . | content | . .
. | . feature . | .
| left content | . . .
. . . | right content|
You could also make it wider and show the expected size both at desktop but also mobile sizes as well as if anything shifts
J-Sun 🎷☀
J-Sun 🎷☀2mo ago
Yes! This is actually really fantastic (the use of subgrid now to solve this). I'm going to apply this to my now 2nd project using the grid-layout-only approach. What I've actually been trying to do is use a similar 50/50 section: - left half staying within the content-start - right half (with a hero image– see the subscribe form at bottom of example site) start in middle, but bleed to full-width-end. Just tested in your codepen and it totally works! Incidentally, can anyone see why my content-grid seems to scale perfectly fine when resizing the viewport. But if you swich to actual mobile device width, it's only taking about 50% of the width? Happening when actually viewing on mobile devices. https://pyctxstg.wpenginepowered.com/
Jason Shanks
PYC Therapeutics
Home - PYC Therapeutics
PYC Therapeutics is a clinical-stage biotech company that creates therapies for rare genetic diseases. Our purpose is to change lives.
luca
luca2mo ago
I would just use flex, if you want to recreate the designs you mentioned. I think you can use flex wrap to make it responsive too
J-Sun 🎷☀
J-Sun 🎷☀4w ago
I ended up running with your variation to this @districtw and expanded further with some asymetrical layouts:
/* No container page grid */

.content-grid {
--padding-inline: clamp(1.25rem, 11vw, 10rem);
--content-max-width: 70rem;
--breakout-max-width: 90rem;

--breakout-size: calc(
(var(--breakout-max-width) - var(--content-max-width)) / 2
);

display: grid;
grid-template-columns:
[full-width-start]
minmax(var(--padding-inline), 1fr)
[breakout-start]
minmax(0, var(--breakout-size))
[content-start]
min(
calc((100% - (2 * var(--padding-inline))) / 2),
calc(var(--content-max-width) / 2)
)
[content-middle]
min(
calc((100% - (2 * var(--padding-inline))) / 2),
calc(var(--content-max-width) / 2)
)
[content-end]
minmax(0, var(--breakout-size))
[breakout-end]
minmax(var(--padding-inline), 1fr)
[full-width-end];
}

.grid-in {
display: grid;
grid-template-columns: subgrid;
}

/* Base classes for different column spans */
.full-width {
grid-column: full-width;
}

/* Default content positioning */
section article {
grid-column: content;
}

/* Utility classes for grid spans */
.content-grid > .full-width {
grid-column: full-width;
display: grid;
grid-template-columns: inherit;
width: 100%;
max-width: 100vw;
}

.content-span {
grid-column: content;
}

.breakout {
grid-column: breakout;
}

.content-left-start {
grid-column: content-start / content-middle;
}

.content-right-end {
grid-column: content-middle / content-end;
}

/* Asymmetrical layout classes */
.breakout-start {
grid-column: breakout-start / content-middle;
}

.breakout-end {
grid-column: content-middle / breakout-end;
}

.full-width-end {
grid-column: content-middle / full-width-end;
}
/* No container page grid */

.content-grid {
--padding-inline: clamp(1.25rem, 11vw, 10rem);
--content-max-width: 70rem;
--breakout-max-width: 90rem;

--breakout-size: calc(
(var(--breakout-max-width) - var(--content-max-width)) / 2
);

display: grid;
grid-template-columns:
[full-width-start]
minmax(var(--padding-inline), 1fr)
[breakout-start]
minmax(0, var(--breakout-size))
[content-start]
min(
calc((100% - (2 * var(--padding-inline))) / 2),
calc(var(--content-max-width) / 2)
)
[content-middle]
min(
calc((100% - (2 * var(--padding-inline))) / 2),
calc(var(--content-max-width) / 2)
)
[content-end]
minmax(0, var(--breakout-size))
[breakout-end]
minmax(var(--padding-inline), 1fr)
[full-width-end];
}

.grid-in {
display: grid;
grid-template-columns: subgrid;
}

/* Base classes for different column spans */
.full-width {
grid-column: full-width;
}

/* Default content positioning */
section article {
grid-column: content;
}

/* Utility classes for grid spans */
.content-grid > .full-width {
grid-column: full-width;
display: grid;
grid-template-columns: inherit;
width: 100%;
max-width: 100vw;
}

.content-span {
grid-column: content;
}

.breakout {
grid-column: breakout;
}

.content-left-start {
grid-column: content-start / content-middle;
}

.content-right-end {
grid-column: content-middle / content-end;
}

/* Asymmetrical layout classes */
.breakout-start {
grid-column: breakout-start / content-middle;
}

.breakout-end {
grid-column: content-middle / breakout-end;
}

.full-width-end {
grid-column: content-middle / full-width-end;
}
You can see the results in this (not yet launched) website: https://pyctxstg.wpenginepowered.com/
Jason Shanks
PYC Therapeutics
Home - PYC Therapeutics
PYC Therapeutics is a clinical-stage biotech company that creates therapies for rare genetic diseases. Our purpose is to change lives.
J-Sun 🎷☀
J-Sun 🎷☀4w ago
What I am struggling with (non-related) is the mobile menu having some overlay/z-index/isolation issues (on mobile Safari ONLY), over the .hero-banner/.carousel underneath. aarrrrgh! I've thrown everything at it: - additional z-index layering - isolation: isolate (new one on me) - additional Safari-only styles:
transform: translateZ(0); /* Force GPU acceleration and new stacking context */
-webkit-transform: translate3d(0,0,0); /* Safari fix */
backface-visibility: hidden; /* Additional Safari fix */
transform: translateZ(0); /* Force GPU acceleration and new stacking context */
-webkit-transform: translate3d(0,0,0); /* Safari fix */
backface-visibility: hidden; /* Additional Safari fix */
Any ideas would be appreciated!
Simon
Simon4w ago
mmhhyeah good input ... I approached this by declaring an additional class.split to add another grid
grid-template-columns:
minmax(0, 1fr)
repeat(auto-fit, minmax(50%, 200px))
minmax(0, 1fr);
}
grid-template-columns:
minmax(0, 1fr)
repeat(auto-fit, minmax(50%, 200px))
minmax(0, 1fr);
}
and adding :has() conditions to let these parents further act on their children. experimental context ... and I am unsure if I like it. lol – it feels a wee bit gimmicky and unclean
J-Sun 🎷☀
J-Sun 🎷☀4w ago
nm, after frustrating hours trying to debug Safari layering issues, I just went nuclear and seting everything else beside mobile nav to 'hide' while it was open. 🤷🏼‍♂️
Want results from more Discord servers?
Add your server