You May Not Want A Framework For That — Smashing Journal

0
20
You Might Not Need A Framework For That — Smashing Magazine


Establishing layouts in CSS is one thing that we, as builders, typically delegate to no matter framework we’re most snug utilizing. And though it’s doable to configure a framework to get simply what we want out of it, how typically have you ever built-in a whole CSS library merely for its structure options? I’m positive many people have carried out it sooner or later, relationship again to the times of 960.gs, Bootstrap, Susy, and Basis.

Fashionable CSS options have considerably lower the necessity to attain for a framework merely for its structure. But, I proceed to see it occur. Or, I empathize with a lot of my colleagues who discover themselves re-creating the identical Grid or Flexbox structure over and over.

On this article, we’ll achieve larger management over internet layouts. Particularly, we’ll create 4 CSS courses that it is possible for you to to take and use instantly on nearly any undertaking or place the place you want a specific structure that may be configured to your wants.

Whereas the ideas we cowl are key, the actual factor I would like you to remove from that is the confidence to make use of CSS for these issues we are likely to keep away from doing ourselves. Layouts used to be a problem on the identical stage of styling kind controls. Sure artistic layouts should still be troublesome to drag off, however the way in which CSS is designed at present solves the burdens of the established structure patterns we’ve been outsourcing and re-creating for a few years.

What We’re Making

We’re going to ascertain 4 CSS courses, every with a distinct structure strategy. The thought is that if you happen to want, say, a fluid structure based mostly on Flexbox, you could have it prepared. The identical goes for the three different courses we’re making.

And what precisely are these courses? Two of them are Flexbox layouts, and the opposite two are Grid layouts, every for a selected goal. We’ll even prolong the Grid layouts to leverage CSS Subgrid for when that’s wanted.

Inside these two teams of Flexbox and Grid layouts are two utility courses: one which auto-fills the obtainable house — we’re calling these “fluid” layouts — and one other the place we’ve got larger management over the columns and rows — we’re calling these “repeating” layouts.

Lastly, we’ll combine CSS Container Queries in order that these layouts reply to their very own measurement for responsive habits slightly than the scale of the viewport. The place we’ll begin, although, is organizing our work into Cascade Layers, which additional can help you management the extent of specificity and stop fashion conflicts with your personal CSS.

Setup: Cascade Layers & CSS Variables

A method that I’ve used a number of occasions is to outline Cascade Layers firstly of a stylesheet. I like this concept not solely as a result of it retains types neat and arranged but additionally as a result of we are able to affect the specificity of the types in every layer by organizing the layers in a selected order. All of this makes the utility courses we’re making simpler to take care of and combine into your personal work with out working into specificity battles.

I believe the next three layers are sufficient for this work:

@layer reset, theme, structure;

Discover the order as a result of it actually, actually issues. The reset layer comes first, making it the least particular layer of the bunch. The structure layer is available in on the finish, making it the most particular set of types, giving them increased precedence than the types within the different two layers. If we add an unlayered fashion, that one could be added final and thus have the very best specificity.

Chrome DevTools in Chrome showing CSS layers
Determine 1: Inspecting Cascade Layers in Chrome’s DevTools. (Massive preview)

Associated: “Getting Began With Cascade Layers” by Stephanie Eckles.

Let’s briefly cowl how we’ll use every layer in our work.

Reset Layer

The reset layer will comprise types for any consumer agent types we wish to “reset”. You possibly can add your personal resets right here, or if you have already got a reset in your undertaking, you’ll be able to safely transfer on with out this explicit layer. Nonetheless, do do not forget that un-layered types might be learn final, so wrap them on this layer if wanted.

I’m simply going to drop in the favored box-sizing declaration that ensures all parts are sized constantly by the border-box in accordance with the CSS Field Mannequin.

@layer reset {
  *,
  *::earlier than,
  *::after {
    box-sizing: border-box;
  }

  physique {
    margin: 0;
  }
}

Theme Layer

This layer gives variables scoped to the :root component. I like the concept of scoping variables this excessive up the chain as a result of structure containers — just like the utility courses we’re creating — are sometimes wrappers round numerous different parts, and a worldwide scope ensures that the variables can be found wherever we want them. That mentioned, it’s doable to scope these regionally to a different component if that you must.

Now, no matter makes for “good” default values for the variables will completely depend upon the undertaking. I’m going to set these with explicit values, however don’t assume for a second that you must stick to them — that is very a lot a configurable system that you could adapt to your wants.

Listed here are the one three variables we want for all 4 layouts:

@layer theme {
  :root {
    --layout-fluid-min: 35ch;
    --layout-default-repeat: 3;
    --layout-default-gap: 3vmax;
  }
}

So as, these map to the next:

Discover: The variables are prefixed with layout-, which I’m utilizing as an identifier for layout-specific values. That is my private choice for structuring this work, however please select a naming conference that matches your psychological mannequin — naming issues will be arduous!

Structure Layer

This layer will maintain our utility class rulesets, which is the place all of the magic occurs. For the grid, we’ll embrace a fifth class particularly for utilizing CSS Subgrid inside a grid container for these doable use instances.

@layer structure {  
  .repeating-grid {}
  .repeating-flex {}
  .fluid-grid {}
  .fluid-flex {}

  .subgrid-rows {}
}

Now that every one our layers are organized, variables are set, and rulesets are outlined, we are able to start engaged on the layouts themselves. We are going to begin with the “repeating” layouts, one based mostly on CSS Grid and the opposite utilizing Flexbox.

Repeating Grid And Flex Layouts

I believe it’s a good suggestion to start out with the “easiest” structure and scale up the complexity from there. So, we’ll sort out the “Repeating Grid” structure first as an introduction to the overarching method we might be utilizing for the opposite layouts.

Repeating Grid

If we head into the @structure layer, that’s the place we’ll discover the .repeating-grid ruleset, the place we’ll write the types for this particular structure. Primarily, we’re setting this up as a grid container and making use of the variables we created to it to ascertain structure columns and spacing between them.

.repeating-grid {
  show: grid;
  grid-template-columns: repeat(var(--layout-default-repeat), 1fr);
  hole: var(--layout-default-gap);
}

It’s not too sophisticated to this point, proper? We now have a grid container with three equally sized columns that take up one fraction (1fr) of the obtainable house with a spot between them.

That is all fantastic and dandy, however we do wish to take this a step additional and switch this right into a system the place you’ll be able to configure the variety of columns and the scale of the hole. I’m going to introduce two new variables scoped to this grid:

  • --_grid-repeat: The variety of grid columns.
  • --_repeating-grid-gap: The quantity of house between grid objects.

Did you discover that I’ve prefixed these variables with an underscore? This was really a JavaScript conference to specify variables which can be “non-public” — or locally-scoped — earlier than we had const and let to assist with that. Be happy to rename these nevertheless you see match, however I wished to notice that up-front in case you’re questioning why the underscore is there.

.repeating-grid {
  --_grid-repeat: var(--grid-repeat, var(--layout-default-repeat));
  --_repeating-grid-gap: var(--grid-gap, var(--layout-default-gap));

  show: grid;
  grid-template-columns: repeat(var(--layout-default-repeat), 1fr);
  hole: var(--layout-default-gap);
}

Discover: These variables are set to the variables within the @theme layer. I like the concept of assigning a worldwide variable to a locally-scoped variable. This fashion, we get to leverage the default values we set in @theme however can simply override them with out interfering wherever else the worldwide variables are used.

Now let’s put these variables to make use of on the fashion guidelines from earlier than in the identical .repeating-grid ruleset:

.repeating-grid {
  --_grid-repeat: var(--grid-repeat, var(--layout-default-repeat));
  --_repeating-grid-gap: var(--grid-gap, var(--layout-default-gap));

  show: grid;
  grid-template-columns: repeat(var(--_grid-repeat), 1fr);
  hole: var(--_repeating-grid-gap);
}

What occurs from right here after we apply the .repeating-grid to a component in HTML? Let’s think about that we’re working with the next simplified markup:

If we had been to use a background-color and peak to these divs, we’d get a pleasant set of packing containers which can be positioned into three equally-sized columns, the place any divs that don’t match on the primary row routinely wrap to the subsequent row.

See the Pen [Layout Utility: Repeating Grid [forked]](https://codepen.io/smashingmag/pen/gOJrqmL) by Geoff Graham.

See the Pen Structure Utility: Repeating Grid [forked] by Geoff Graham.

Now, in fact, we don’t have to have simply three columns. Let’s say we would like a product grid the place we wish to change the repeating columns from 3 to 5 whereas updating the hole from 2vw to 3vw utilizing the identical HTML, solely with a brand new class we are able to use override these values.

See how that is shaping up? We have now a grid structure based mostly on a set of globally-scoped variables that we are able to re-assign to variables which can be locally-scoped to the utility class and additional personalized with a category of our personal that provides context to the component’s goal and means that you can alter the responsive habits.

.products-grid {
  --grid-repeat: 2;
  --grid-gap: 2vw;

  @media (width >= 1000px) {
    --grid-repeat: 3;
    --grid-gap: 3vw;
  }
}

See the Pen [Layout Utility: Repeating Grid [forked]](https://codepen.io/smashingmag/pen/YzbqBVy) by Geoff Graham.

See the Pen Structure Utility: Repeating Grid [forked] by Geoff Graham.

The profit is that we are able to overwrite our default values with out polluting the HTML with superfluous courses. That is the overarching strategy we will even use within the three different structure courses. Subsequent up is the “Repeating Flex” model of what we simply made.

Repeating Flex

The “Repeating Grid” structure is nice, however you may not all the time need equally-sized columns. CSS Grid is actually able to auto-filling parts with no matter house is offered, however Flexbox is extraordinarily proficient at it.

Let’s say we’ve got the identical 5 divs from earlier than. That leaves us with two divs on the second row subsequent to an empty column on the precise. Maybe we would like these final two leftover divs to stretch out and take up the house within the empty column.

Two rows of pink rectangles, with three boxes on the top and two boxes on the bottom.
Determine 2: Versatile objects routinely fill any remaining house that will in any other case be introduced as an empty third column on the second row. (Massive preview)

Time to place the method we established with the Repeating Grid structure to make use of on this Repeating Flex structure. This time, we leap straight to defining the non-public variables on the .repeating-flex ruleset within the @structure layer since we already know what we’re doing.

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));
}

Once more, we’ve got two locally-scoped variables used to override the default values assigned to the globally-scoped variables. Now, we apply them to the fashion declarations.

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));

  show: flex;
  flex-wrap: wrap;
  hole: var(--_repeating-flex-gap);
}

We’re solely utilizing one of many variables to set the hole measurement between flex objects for the time being, however that may change in a bit. For now, the essential factor to notice is that we’re utilizing the flex-wrap property to inform Flexbox that it’s OK to let further objects within the structure wrap into a number of rows slightly than attempting to pack every little thing in a single row.

However as soon as we try this, we additionally should configure how the flex objects shrink or develop based mostly on no matter quantity of accessible house is remaining. Let’s nest these types contained in the guardian ruleset:

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));

  show: flex;
  flex-wrap: wrap;
  hole: var(--_repeating-flex-gap);

  > * {
    flex: 1 1 calc((100% / var(--_flex-repeat)) - var(--_gap-repeater-calc));
  }
}

Should you’re questioning why I’m utilizing the common selector (*), it’s as a result of we are able to’t assume that the structure objects will all the time be divs. Maybe they’re

parts,

s, or one thing else fully. The kid combinator (>) ensures that we’re solely deciding on parts which can be direct kids of the utility class to stop leakage into different ancestor types.

The flex shorthand property is a kind of that’s been round for a few years now however nonetheless appears to mystify many people. Earlier than we unpack it, did you additionally discover that we’ve got a brand new locally-scoped --_gap-repeater-calc variable that must be outlined? Let’s do that:

.repeating-flex {
  --_flex-repeat: var(--flex-repeat, var(--layout-default-repeat));
  --_repeating-flex-gap: var(--flex-gap, var(--layout-default-gap));

  /* New variables */
  --_gap-count: calc(var(--_flex-repeat) - 1);
  --_gap-repeater-calc: calc(
    var(--_repeating-flex-gap) / var(--_flex-repeat) * var(--_gap-count)
  );
  
  show: flex;
  flex-wrap: wrap;
  hole: var(--_repeating-flex-gap);

  > * {
    flex: 1 1 calc((100% / var(--_flex-repeat)) - var(--_gap-repeater-calc));
  }
}

Whoa, we really created a second variable that --_gap-repeater-calc can use to correctly calculate the third flex worth, which corresponds to the flex-basis property, i.e., the “splendid” measurement we would like the flex objects to be.

If we take out the variable abstractions from our code above, then that is what we’re :

.repeating-flex {
  show: flex;
  flex-wrap: wrap;
  hole: 3vmax

  > * {
    flex: 1 1 calc((100% / 3) - calc(3vmax / 3 * 2));
  }
}

Hopefully, this may enable you to see what kind of math the browser has to do to measurement the versatile objects within the structure. In fact, these values change if the variables’ values change. However, in brief, parts which can be direct kids of the .repeating-flex utility class are allowed to develop (flex-grow: 1) and shrink (flex-shrink: 1) based mostly on the quantity of accessible house whereas we inform the browser that the preliminary measurement (i.e., flex-basis) of every flex merchandise is the same as some calc()-ulated worth.

As a result of we needed to introduce a few new variables to get right here, I’d wish to not less than clarify what they do:

  • --_gap-count: This shops the variety of gaps between structure objects by subtracting 1 from --_flex-repeat. There’s one much less hole within the variety of objects as a result of there’s no hole earlier than the primary merchandise or after the final merchandise.
  • --_gap-repeater-calc: This calculates the overall hole measurement based mostly on the person merchandise’s hole measurement and the overall variety of gaps between objects.

From there, we calculate the overall hole measurement extra effectively with the next components:

calc(var(--_repeating-flex-gap) / var(--_flex-repeat) * var(--_gap-count))

Let’s break that down additional as a result of it’s an inception of variables referencing different variables. On this instance, we already offered our repeat-counting non-public variable, which falls again to the default repeater by setting the --layout-default-repeat variable.

This units a spot, however we’re not carried out but as a result of, with versatile containers, we have to outline the flex habits of the container’s direct kids in order that they develop (flex-grow: 1), shrink (flex-shrink: 1), and with a flex-basis worth that’s calculated by multiplying the repeater by the overall variety of gaps between objects.

Subsequent, we divide the person hole measurement (--_repeating-flex-gap) by the variety of repetitions (--_flex-repeat)) to equally distribute the hole measurement between every merchandise within the structure. Then, we multiply that hole measurement worth by one minus the overall variety of gaps with the --_gap-count variable.

And that concludes our repeating grids! Fairly enjoyable, or not less than attention-grabbing, proper? I like a little bit of math.

Earlier than we transfer to the ultimate two structure utility courses we’re making, you may be questioning why we would like so many abstractions of the identical variable, as we begin with one globally-scoped variable referenced by a locally-scoped variable which, in flip, will be referenced and overridden once more by one more variable that’s regionally scoped to a different ruleset. We might merely work with the worldwide variable the entire time, however I’ve taken us by the additional steps of abstraction.

I prefer it this fashion due to the next:

  1. I can peek on the HTML and immediately see which structure strategy is in use: .repeating-grid or .repeating-flex.
  2. It maintains a sure separation of issues that retains types so as with out working into specificity conflicts.

See how clear and comprehensible the markup is:


The corresponding CSS is prone to be a slim ruleset for the semantic .footer-usps class that merely updates variable values:

.footer-usps {
  --flex-repeat: 3;
  --flex-gap: 2rem;
}

This offers me the entire context I would like: the kind of structure, what it’s used for, and the place to search out the variables. I believe that’s helpful, however you actually might get by with out the added abstractions if you happen to’re seeking to streamline issues a bit.

Fluid Grid And Flex Layouts

All of the repeating we’ve carried out till now could be enjoyable, and we are able to manipulate the variety of repeats with container queries and media queries. However slightly than repeating columns manually, let’s make the browser do the work for us with fluid layouts that routinely fill no matter empty house is offered within the structure container. We could sacrifice a small quantity of management with these two utilities, however we get to leverage the browser’s potential to “intelligently” place structure objects with a number of CSS hints.

Fluid Grid

As soon as once more, we’re beginning with the variables and dealing our solution to the calculations and elegance guidelines. Particularly, we’re defining a variable referred to as --_fluid-grid-min that manages a column’s minimal width.

Let’s take a slightly trivial instance and say we would like a grid column that’s not less than 400px large with a 20px hole. On this scenario, we’re primarily working with a two-column grid when the container is larger than 820px large. If the container is narrower than 820px, the column stretches out to the container’s full width.

If we wish to go for a three-column grid as an alternative, the container’s width ought to be about 1240px large. It’s all about controlling the minimal sizing values within the hole.

.fluid-grid {
  --_fluid-grid-min: var(--fluid-grid-min, var(--layout-fluid-min));
  --_fluid-grid-gap: var(--grid-gap, var(--layout-default-gap));
}

That establishes the variables we have to calculate and set types on the .fluid-grid structure. That is the total code we’re unpacking:

 .fluid-grid {
  --_fluid-grid-min: var(--fluid-grid-min, var(--layout-fluid-min));
  --_fluid-grid-gap: var(--grid-gap, var(--layout-default-gap));

  show: grid;
  grid-template-columns: repeat(
    auto-fit,
    minmax(min(var(--_fluid-grid-min), 100%), 1fr)
  );
  hole: var(--_fluid-grid-gap);
}

The show is about to grid, and the hole between objects is predicated on the --fluid-grid-gap variable. The magic is going down within the grid-template-columns declaration.

This grid makes use of the repeat() perform simply because the .repeating-grid utility does. By declaring auto-fit within the perform, the browser routinely packs in as many columns because it presumably can within the quantity of accessible house within the structure container. Any columns that may’t match on a line merely wrap to the subsequent line and occupy the total house that’s obtainable there.

Then there’s the minmax() perform for setting the minimal and most width of the columns. What’s particular right here is that we’re nesting one more perform, min(), inside minmax() (which, bear in mind, is nested within the repeat() perform). This a bit of additional logic that units the minimal width worth of every column someplace in a spread between --_fluid-grid-min and 100%, the place 100% is a fallback for when --_fluid-grid-min is undefined or is lower than 100%. In different phrases, every column is not less than the total 100% width of the grid container.

The “max” half of minmax() is about to 1fr to make sure that every column grows proportionally and maintains equally sized columns.

See the Pen [Fluid grid [forked]](https://codepen.io/smashingmag/pen/GRaZzMN) by utilitybend.

See the Pen Fluid grid [forked] by utilitybend.

That’s it for the Fluid Grid structure! That mentioned, please do take word that it is a sturdy grid, notably when it’s mixed with trendy relative items, e.g. ch, because it produces a grid that solely scales from one column to a number of columns based mostly on the scale of the content material.

Fluid Flex

We just about get to re-use the entire code we wrote for the Repeating Flex structure for the Fluid Flex structure, however solely we’re setting the flex-basis of every column by its minimal measurement slightly than the variety of columns.

.fluid-flex {
  --_fluid-flex-min: var(--fluid-flex-min, var(--layout-fluid-min));
  --_fluid-flex-gap: var(--flex-gap, var(--layout-default-gap));

  show: flex;
  flex-wrap: wrap;
  hole: var(--_fluid-flex-gap);

  > * {
    flex: 1 1 var(--_fluid-flex-min);
  }
}

That completes the fourth and ultimate structure utility — however there’s one bonus class we are able to create to make use of along with the Repeating Grid and Fluid Grid utilities for much more management over every structure.

Non-obligatory: Subgrid Utility

Subgrid is helpful as a result of it turns any grid merchandise right into a grid container of its personal that shares the guardian container’s observe sizing to maintain the 2 containers aligned with out having to redefine tracks by hand. It’s bought full browser assist and makes our structure system simply that rather more strong. That’s why we are able to set it up as a utility to make use of with the Repeating Grid and Fluid Grid layouts if we want any of the structure objects to be grid containers for laying out any baby parts they comprise.

Right here we go:

.subgrid-rows {
  > * {
    show: grid;
    hole: var(--subgrid-gap, 0);
    grid-row: auto / span var(--subgrid-rows, 4);
    grid-template-rows: subgrid;
  }
}

We have now two new variables, in fact:

  • --subgrid-gap: The vertical hole between grid objects.
  • --subgrid-rows The variety of grid rows defaulted to 4.

We have now a little bit of a problem: How will we management the subgrid objects within the rows? I see two doable strategies.

Methodology 1: Inline Types

We have already got a variable that may technically be used straight within the HTML as an inline fashion:

This works like a attraction because the variable informs the subgrid how a lot it might probably develop.

Methodology 2: Utilizing The :has() Pseudo-Class

This strategy results in verbose CSS, however sacrificing brevity permits us to automate the structure so it handles virtually something we throw at it with out having to replace an inline fashion within the markup.

Test this out:

.subgrid-rows {
  &:has(> :nth-child(1):last-child) { --subgrid-rows: 1; }
  &:has(> :nth-child(2):last-child) { --subgrid-rows: 2; }
  &:has(> :nth-child(3):last-child) { --subgrid-rows: 3; }
  &:has(> :nth-child(4):last-child) { --subgrid-rows: 4; }
  &:has(> :nth-child(5):last-child) { --subgrid-rows: 5; }
  /* and so on. */

  > * {
    show: grid;
    hole: var(--subgrid-gap, 0);
    grid-row: auto / span var(--subgrid-rows, 5);
    grid-template-rows: subgrid;
  }
}

The :has() selector checks if a subgrid row is the final baby merchandise within the container when that merchandise is both the primary, second, third, fourth, fifth, and so forth merchandise. For instance, the second declaration:

&:has(> :nth-child(2):last-child) { --subgrid-rows: 2; }

…is just about saying, “If that is the second subgrid merchandise and it occurs to be the final merchandise within the container, then set the variety of rows to 2.”

Whether or not that is too heavy-handed, I don’t know; however I like that we’re in a position to do it in CSS.

The ultimate lacking piece is to declare a container on our youngsters. Let’s give the columns a basic class title, .grid-item, that we are able to override if we have to whereas setting each as a container we are able to question for the sake of updating its structure when it’s a sure measurement (versus responding to the viewport’s measurement in a media question).

:is(.fluid-grid:not(.subgrid-rows),
.repeating-grid:not(.subgrid-rows),
.repeating-flex, .fluid-flex) {
    > * {
    container: var(--grid-item-container, grid-item) / inline-size;
  }
}

That’s a wild-looking selector, however the verbosity is actually saved to a minimal because of the :is() pseudo-class, which saves us from having to write down this as a bigger chain selector. It primarily selects the direct kids of the opposite utilities with out leaking into .subgrid-rows and inadvertently deciding on its direct kids.

The container property is a shorthand that mixes container-name and container-type right into a single declaration separated by a ahead slash (/). The title of the container is about to considered one of our variables, and the sort is all the time its inline-size (i.e., width in a horizontal writing mode).

The container-type property can solely be utilized to grid containers — not grid objects. This implies we’re unable to mix it with the grid-template-rows: subgrid worth, which is why we would have liked to write down a extra advanced selector to exclude these situations.

Demo

Take a look at the next demo to see how every little thing comes collectively.

See the Pen [Grid system playground [forked]](https://codepen.io/smashingmag/pen/mdYPvLR) by utilitybend.

See the Pen Grid system playground [forked] by utilitybend.

The demo is pulling in types from one other pen that comprises the total CSS for every little thing we made collectively on this article. So, if you happen to had been to switch the .fluid-flex classname from the guardian container within the HTML with one other one of many structure utilities, the structure will replace accordingly, permitting you to match them.

These courses are the next:

  • .repeating-grid,
  • .repeating-flex,
  • .fluid-grid,
  • .fluid-flex.

And, in fact, you could have the choice of turning any grid objects into grid containers utilizing the non-obligatory .subgrid-rows class together with the .repeating-grid and .fluid-grid utilities.

Conclusion: Write As soon as And Repurpose

This was fairly a journey, wasn’t it? It’d look like plenty of data, however we made one thing that we solely want to write down as soon as and might use virtually wherever we want a sure kind of structure utilizing trendy CSS approaches. I strongly imagine these utilities can’t solely enable you to in a bunch of your work but additionally lower any reliance on CSS frameworks that you could be be utilizing merely for its structure configurations.

This can be a mixture of many strategies I’ve seen, considered one of them being a presentation Stephanie Eckles gave at CSS Day 2023. I adore it when folks handcraft trendy CSS options for issues we used to work round. Stephanie’s demonstration was clear from the beginning, which is refreshing as so many different areas of internet growth have gotten ever extra advanced.

After studying a bunch from CSS Day 2023, I performed with Subgrid alone and revealed totally different concepts from my experiments. That’s all it took for me to appreciate how extensible trendy CSS structure approaches are and impressed me to create a set of utilities I might depend on, maybe for a very long time.

Under no circumstances am I attempting to persuade you or anybody else that these utilities are good and ought to be used all over the place and even that they’re higher than . One factor that I do know for sure is that by experimenting with the concepts we coated on this article, you’ll get a stable really feel of how CSS is able to making structure work far more handy and strong than ever.

Create one thing out of this, and share it within the feedback if you happen to’re keen — I’m trying ahead to seeing some contemporary concepts!

Smashing Editorial
(gg, yk)



Supply hyperlink

LEAVE A REPLY

Please enter your comment!
Please enter your name here