search
HomeWeb Front-endCSS TutorialCode as Documentation: New Strategies with CSS Grid

Code as Documentation: New Strategies with CSS Grid

Supercool, a fast-growing web design company, creates custom websites for art clients and uses off-the-shelf Craft CMS systems; it features high-spec graphic design, as well as relatively demanding typography and art guidance. We have been turning to CSS Grid for the past few months. We are slowly transitioning to allow ourselves to discover new paradigms and design methods instead of simply porting old habits into new syntax.

So far, we have developed some very useful strategies to track layouts. I've written some very clever mixins, using named regions and templates, and we've found some basic conventions to create highly readable code. I think it would be very valuable to step by step into the complete production implementation of a single major component using grid, dig into some of the design issues it raises, and guide you to avoid the pitfalls we encounter. CSS Grid is a large specification with many possible ways and a lot of correct ways, but at some point you have to determine your method and get it online.

I expect you to have some knowledge of CSS, Sass, BEM and be interested in prototyping fully implemented, accessible, custom frameworks (with over 50 components) tasks with Sketch or Photoshop type documents within a tight schedule (such as a week).

First, let's identify and separate the different coding tasks in the design and plan how we will handle them:

  1. Font: The designer has defined a font system.
  2. Color: First, we build a theme model and then include it in the section.
  3. Content: What elements are included in this block? What is its variant? This is where our BEM mixin comes into play.
  4. Layout: This is how content is placed in this block. You may want to skip directly to this step.
  5. Contract: This is exactly how we chose to write all of the above. There are a lot of correct answers in CSS, so it is important that we all agree with one convention, the rules. This should indeed be ranked first, but for the sake of this article, we will summarize it at the end.

Font system

We use utility classes (such as h-text--h1, h-text--badge) to set the font style. There may be a hundred font styles in a project. We use Typex to export these styles directly from Sketch into our Patternlab. This is what another post in itself, so let's assume the font has been processed. We will not introduce fonts into our component parts.

Color usage

Themes are just adding a few tiny mixins, so ideally we won't see a lot of color rules in the section. We store them all in the _themer.scss section of the "Mixin and Model" library so we can ensure that the design system of the website is followed. That way, when someone returns to the build later, they have a key reference section to describe the design and brand rules. When building and maintaining many websites in roughly the same market – but each has different brand specifications – you have to make sure that one brand is not confused with another! So, like fonts, we abstract the color rules from the parts. Essentially, in our _header.scss file we are actually only focusing on the layout (as much as possible).

Given that we agree to always use our mixin for thematic, this is how to include it on the element:

 <code>@include var($property, $value);</code>

We will then set up a theme model that illustrates how the color works on this particular website and apply it to the components:

 <code>@include theme;</code>

Here is the sample theme model we will use with this page title. It's very simple.

We pair the color with black or white. We rely on contrast rules and flip them for emphasis, probably on events (such as hovering) or highlighted calls to action. That's all we need to do to achieve this, and now we have documentation on how colors actually work on this website. If we need to debug or extend the UI, we can access and check it.

We also want to prepare inheritance to help us, so let's identify some useful conventions:

  • Set the fill of the SVG icon to currentColor in your pipeline (by the way, the default size in CSS is width: 1em; height: 1em; font-size: inherit; ).
  • Set up at the base<a></a> for currentColor.
  • Write abbreviation, inherit borders (such as 1px solid or 1px solid currentColor ).

With this topic model, we can generate any number of topics, maybe store them as utility classes, or loop through the modifier list within the component, or just allow the user to set variables directly on blocks in the CMS. When IE 11 accounts for less than 1% of our statistics, we can do more with variables, but that's enough for our current use.

Let's not deviate from the topic. How about Grid? !

Content Components

Grid allows us to accurately describe what we have in each section in a new way. This is really a game-changer for the design agency that builds a new UI for each project, and as we explore, we are discovering new (and interesting) applications of it.

To provide context: We use Craft CMS to customize each interface for our customers and create custom fields to meet their specific needs and their content model. We have internal tools that can extract events from the ticketing API and create entries from it, which can then be edited and extended in the CMS (or created completely). Customers can fill in or edit named fields in the permanent page area and can also add the entire designed, branded block to the layout of each page as they are building them.

There are many UIs. Customers have a lot of control over the content, and we have a lot of control over HTML, so we can ensure that there is high-quality accessible semantic code on the page. We jointly develop content models during the discovery process and then let them create content freely. They add what they want and we make sure it works and always looks right. Better than right! super . (Sorry! :P)

So as a developer I have to weigh competing priorities:

  • Accessibility, availability
  • Branding and graphic design
  • performance
  • Maintenance and codebase health

Let's look at them one by one:

Accessibility

Accessible, logical HTML is my favorite. At the very least, my project needs to get a green accessibility score in the Lighthouse score. (I'm kidding, I want that delicious 100!) Core paths and pages are tested using some screen readers (keyboard tabs, keyboard navigation), low vision simulator, Dasher, voice access and binary switches. (I also work for Robots and Cake, so it's a big part of my development work.) I've added huge clickable phone numbers and email addresses to the page over and over again. I just want people to get where they want to go.

I've been worried about how the content can be reordered by grid (and flexbox). Now that I have done several builds, I actually think grid can help us solve this problem. With CSS Grid, there is no reason to move HTML for layout. We can go back to linear sequences that treat the entire document as logic as our primary concern.

Brand and performance and maintenance

Art venues require high-standard graphic designs, unified on prints and the web, and require constantly changing materials (such as programs, manuals, tickets, posters, micro-websites, etc.) to distribute to their audiences, including contract marketing obligations that must be met. As you can imagine, we have a lot of high-quality large images that need priority processing and often come with a strong printing-led brand. This means we may need to provide the page with about fifteen custom fonts (including thickness variations, display fonts, etc.) as well as complex CSS. We have to keep ourselves as streamlined as possible. We are currently sending about 20 KB nano Gzipped CSS, but I'm working on reducing it further.

However, we do keep the full length of the grid region name by setting the reduce identifier to false in the PostCSS task. Having the available layout diagrams in DevTools is more useful than saving those small amounts of bytes. For the sake of maintaining, self-documenting and your future self-debugging of this website without repo access on a delayed train in Sowerby Bridge: Keep the map.

Code Health

The way to balance all these competing needs is to articulate and make an agreement so that less content needs to be fixed in the test and that the resolved issues remain resolved . We check all the components we build and make sure they always start with the title, links point to the location, buttons trigger actions, countable objects delivered as lists and prefixed with landmark titles, navigation is<nav></nav> , time is<time></time> , div soup is breakfast - basics.

With CSS Grid, there is no reason to move HTML for layout . Your content can always flow logically, while layout changes occur in CSS. And, since there is no need for margins or padding to create spacing, you can simply declare:

 <code>.o-grid .o-grid { width:100%; }</code>

… to ensure that any number of nested groups visually occupy the same page grid. HTML can guide things more clearly: closer to documents.

There is a lot to manage between the title and the action, and my challenge is to keep track of all these fields in all these components while making sure I faithfully execute the design specifications so that they are traversable, scanable, linearizable and easy to read in some logical, understandable way.

Let's introduce my first, surprisingly useful grid mix.

 <code>@mixin template($elements...) { @each $element in $elements { &__#{$element} { grid-area: $element; } } }</code>

Using this mixin anywhere means:

  1. Each component section now starts with its list of all possible elements, which is a very handy documentation, especially when Twigging actually front-end components.
  2. The mixin is responsible for allocating grid areas.
  3. Element and component names remain consistent in Sketch, CSS, and HTML, and any inconsistencies will be very obvious because the layout will fail. I am firm, but fair.
  4. BEM naming is automatically enforced, but doesn't mess things up in the section.

Now, in the section, we will declare only grid-template-areas, using plain English words, giving us a series of layout maps that also match the database fields. Super easy to read!

Here is an example of how to use this mixin:

We decided to stick with named regions for internal grids because I read a great article on this site explaining how Autoprefixer handles IE 11's grid if you stick with the listed supported properties - and it does in most cases. If you view this test case using super useful debug mode with Autoprefixer applied in your browser test, you will see it working.

But there are traps! You have to set the inline elements as blocks to make sure they are always operating as grid units in IE 11. Comment out the marker line in the example to see what else would happen:

Ouch! Be careful of those pieces. You may find that some versions of IE 11 won't even pick up this fix, in which case you might try to just use normal<div> Tags…sigh.<p> I didn't include <code>display: grid in this mixin because in some cases the actual grid is set on the internal container, for example, but we still want grid-areas to match the correct BEM class.

so:

 <code>.c-header{ @include template(title, pretitle, posttitle, producer, venue, credit, quote, nav, infobar, search); }</code>

Let's lay out these things.

layout

Let's identify some extra rules to ensure this component can easily slide into the page layout. At the time of writing, there are no sub-grids available (but there will be!), so this component doesn't know the parent grid it's on. This happens to match the BEM component approach well - because each component is flat and isolated to limit inheritance. I'm not advocating BEM here (or the BEM- ish we obviously use) - I'm just saying that if you're already using it, that's an added bonus.

In this example, the designer sets up a page layout with 12 columns of grids and 20px (1.25rem) spacing, with no offset parts within the entire site. Our component is a page area that will occupy all 12 grid columns. During this transition period, we are still using this type of setup grid because we have many systems that still based on this idea that need to be integrated with. Therefore, this is the convention under this condition: for full width areas, delete the grid gap and write the grid template to a fractional unit (fr) of 12.

Doing so means:

  1. The sight of this inner grid roughly follows the grid where it resides;
  2. Easily view the underlying design rules in the code; and
  3. It is easy to align things accurately if needed.

Quick Notes on Alignment

Wait... What do I mean by "exact alignment"? Isn't it already accurately aligned?

Well, no. The fractional unit method divides the space perfectly, so you end up in the spacing. Two even columns will put you in the middle of the spacing. Two columns whose one column is 2/3 and the other 1/3 will be divided at 1/3 of that spacing, and so on.

Fixing alignment is not difficult because we know the width of the page grid spacing. For example, on uniform segmentation, we can include grid gaps.

However, we cannot do this with any other segmentation. What we can do is add that gap as a margin—whatever the box size you set, the margin will be added internally. In this example, we have three columns (two named areas and one empty space) that divide our spacing into three parts:

This is how to calculate these margins: make sure the sum of the fr units is 12. Divide the grid gap by the number of columns in the parent grid and multiply it like this:

The right margin multiplier of n is equal to the sum of the fr units on the right side of n. The left margin of n is equal to the sum of the fr units on the left side of n.

Therefore, for grid-template-columns value is 2fr 3fr 2fr 4fr 1fr :

<code> 2 3 2 4 1 0/10 2/7 5/5 7/1 11/0</code>

If you find yourself writing calc() frequently, you can even write it as a mixin. For example, here is how to align the inner grid with the parent grid:

...and here is how to automatically calculate margins when the name is specified internally but the number is specified outside the grid:

I believe you can think of other solutions like switching to named rows, or adding extra fixed-width columns, or even writing all maps with 12 named areas per row. There are many ways to deal with this, but I think many methods eliminate the advantages of named regions. The area provides us with a readable layout diagram containing what our future self needs to know. It is code as documentation.

To be clear, the design problem I'm leading us to solve is not the alignment problem. With grid, alignment is easy. The problem is not to solve the direct, trivial layout problem, but to solve it in a way that supports our goal, i.e., be able to understand in six months:

  1. What elements are included in the component.
  2. How they are laid out.
  3. Why is the code written this way.

The grid specification is huge and can easily get lost in the options. Perhaps a better plan would be to reset to a 12-column grid and use a numeric specification when absolute alignment is needed (i.e. explicitly linking to our page grid, which uses a numeric specification) – but I do feel there is a smarter, simpler solution to be discovered. For this website, we ended up writing a page grid object and adding nested internal grid cells to it using the class: .o-page-grid\_\_sidebar .

What do you think? I definitely foresee a different view on this. ?‍♀️

Real grid!

We can use it to create a common page title:

Alternatively, we can create a variation of the homepage:

So, what about a hero title that goes beyond our container? certainly! Or we can provide it outside the container:

What's next? A theme event title with a full width information bar (paste) and an internal button that aligns with the sidebar on the parent grid? That's right. I will include a parent grid so that it is easier to view:

So what about searches with centered alignment? Let's use the folding column technique:

Here is a demonstration of all these variations as a single section. Yes, it's a map! It's a packaging!

Agree

Wow, we cover a lot! But you can see how flexible and self-documented a system like this is, right?

  1. Fonts are processed by separate font systems.
  2. Colors are processed by a theme section that describes the underlying color rules of the design rather than simply shading elements temporarily.
  3. Elements are called what they are, in English, and are included with the template mixin at the top of the section. This list can be included as a reference in Twig or in a template.
  4. Always use the correct HTML and nesting does not break the grid. This means you can apply any number of nested grids to the same layout space by setting conventions.
  5. Precise alignment is done in the numeric specification, not the name specification (but note that you can use the name specification for alignment).
  6. Supports IE 11.

I also have a quick description and another example of components built using named regions. In this example, the card is not an area, but a component placed in the grid, so there is no reason to use the fr convention of 12. The media object section you can expect is as follows:

 <code>.c-card { &--news { align-content: start; grid-template-areas: "image" "datetime" "title"; } &--search { justify-content: start; grid-template-columns: 1fr 3fr; grid-template-areas: "image page" "image title" "image summary"; } &--merchandise { grid-gap: 0; grid-template-columns: $b 1fr 1fr $b; grid-template-areas: "image image image image" ". title title ." ". summary summary ." ". price action ."; } &--donations { // donations thanks button is too long and must take up more space than input grid-gap: 0; grid-template-columns: $b 1fr 2fr $b; grid-template-areas: "image image image image" ". title title ." ". summary summary ." ". input action ."; } } // ...</code>

The above is the detailed content of Code as Documentation: New Strategies with CSS Grid. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Simulating Mouse MovementSimulating Mouse MovementApr 22, 2025 am 11:45 AM

If you've ever had to display an interactive animation during a live talk or a class, then you may know that it's not always easy to interact with your slides

Powering Search With Astro Actions and Fuse.jsPowering Search With Astro Actions and Fuse.jsApr 22, 2025 am 11:41 AM

With Astro, we can generate most of our site during our build, but have a small bit of server-side code that can handle search functionality using something like Fuse.js. In this demo, we’ll use Fuse to search through a set of personal “bookmarks” th

Undefined: The Third Boolean ValueUndefined: The Third Boolean ValueApr 22, 2025 am 11:38 AM

I wanted to implement a notification message in one of my projects, similar to what you’d see in Google Docs while a document is saving. In other words, a

In Defense of the Ternary StatementIn Defense of the Ternary StatementApr 22, 2025 am 11:25 AM

Some months ago I was on Hacker News (as one does) and I ran across a (now deleted) article about not using if statements. If you’re new to this idea (like I

Using the Web Speech API for Multilingual TranslationsUsing the Web Speech API for Multilingual TranslationsApr 22, 2025 am 11:23 AM

Since the early days of science fiction, we have fantasized about machines that talk to us. Today it is commonplace. Even so, the technology for making

Jetpack Gutenberg BlocksJetpack Gutenberg BlocksApr 22, 2025 am 11:20 AM

I remember when Gutenberg was released into core, because I was at WordCamp US that day. A number of months have gone by now, so I imagine more and more of us

Creating a Reusable Pagination Component in VueCreating a Reusable Pagination Component in VueApr 22, 2025 am 11:17 AM

The idea behind most of web applications is to fetch data from the database and present it to the user in the best possible way. When we deal with data there

Using 'box shadows' and clip-path togetherUsing 'box shadows' and clip-path togetherApr 22, 2025 am 11:13 AM

Let's do a little step-by-step of a situation where you can't quite do what seems to make sense, but you can still get it done with CSS trickery. In this

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!

Atom editor mac version download

Atom editor mac version download

The most popular open source editor