The second iteration of CSS Grid is already in the works and the public editor’s draft was released last week! While it is by no means the final W3C recommendation, this draft is the start of discussions around big concepts many of us have been wanting to see since the first level was released, including subgrids:
In some cases it might be necessary for the contents of multiple grid items to align to each other. A grid container that is itself a grid item can defer the definition of its rows and columns to its parent grid container, making it a subgrid. In this case, the grid items of the subgrid participate in sizing the grid of the parent grid container, allowing the contents of both grids to align.
The currently defined characters of subgrid items are particularly interesting because they illustrate the differences between a subgrid and its parent grid. For example:
The subgrid is always stretched in both dimensions in its subgridded dimension(s): the align-self/justify-self properties on it are ignored, as are any specified width/height constraints.
In addition to subgrids, aspect-ratio-controlled gutters and conformance are also defined in the draft and worth a read. It’s great to see so much momentum around grids!
Something you very much want to avoid in web design is unreadable text. That can happen when the background color of an element is too close or exactly the color of the text. For instance:
Which could lead to text that’s there, but invisible.
This is … very bad.
You’d never do that on purpose of course! The trouble is it can sneak up on you. For one thing, the default background-color is transparent, so without setting any background the background of an element is probably white.
More commonly, you’re using a background-image that makes the background a different color, and you’re setting white text on top of that.
But let’s take a look at what it looks like while the website is loading over a very common „Slow 3G” internet connection:
There’s no reason our dear visitor needs to wait to discover the incredible savings awaiting them this Sunday! Fortunately, a tiny bit of CSS solves this.
The black background color will ensure the white text will be visible while the image loads (or if it never loads at all!). Getting slightly fancier, we could use a color used in the image. I like a little app called Frank DeLoupe for helping me pluck a color from anywhere on my screen. Then I’ll use that color as the fallback color using the shorthand syntax for backgrounds:
This kind of thing takes very little effort, improves your design’s resiliency and UX, and I think you’ll find becomes are part of your CSS muscle memory the more you write CSS.
Another related topic here, since we’re working with a photograph, is the idea of a „Progressive JPG.” Photoshop has the ability to save a JPG in this format. This changes how the displays as it’s coming across the network. Here’s a comparison video:
A low-res version of the image loads into place first, and it becomes higher quality as more of the image loads.
Perhaps a more desirable loading experience, but not a replacement for a fallback color.
Leveling up!
Images are one of the heaviest parts of websites, and loading techniques for them are a big topic in web performance. Here are some more related to things to think about:
A modest JavaScript framework for the HTML you already have.
This will appeal to anyone who is apprehensive about JavaScript being required to generate HTML, yet wants a modern framework to help with modern problems, like state management.
I wonder if this would be a good answer for things like WordPress or CraftCMS themes that are designed to be server side but, like any site, could benefit from client-side JavaScript enhancements. Stimulus isn’t really built to handle SPAs, but instead pair with Turbolinks. That way, you’re still changing out page content with JavaScript, but all the routing and HTML generation is server side. Kinda old school meets new school.
A clever idea from Michael Donohoe: pit websites against each other in a performance battle! Donohoe is a long-time newsroom guy, so this is specifically about article pages for major publications.
Lets state the obvious, this is an imperfect and evolving measure and the goal is to foster discussion and rivalry in making our pages better, faster, and lighter. Bear in mind this was built as an internal tool at Hearst Newspapers to track changes as we rollout our new Article template on mobile for SFGate and eventually all sites (SF Chronicle, Houston Chronicle, Times Union, etc).
Developers, designers, and product need to talk more on how to achieve this. A 1,700 word article might weigh 10KB but by the time you load HTML, JS, CSS, images, 3rd-parties, and ads, it can range between 2MB to 8MB depending on the web site. Bear in mind, the first Harry Potter ebook is 1.1MB and that includes cover art.
Forever I’ve used the macOS Command-Shift-4 screenshot utility to measure things. Pressing it gets you a little crosshairs cursor which you can click-and-drag to take a screenshot but, crucially, has little numbers that tell you the width/height of the selection in pixels. It’s crude, but ever so useful.
See those teeny-tiny numbers in the bottom-right? So useful, even if they are tough to read.
PixelSnap is one of those apps that, once you see it, you’re like OMG that’s the best idea ever. It’s the same kind of interaction (key command, then mouse around), but it’s drawing lines between obvious measurement points in any window at all. Plus it has this drag around and area and snap to edges thing that’s just as brilliant. Instant purchase for me.
The Product Hunt newsletter said:
Two teenage makers launched PixelSnap, a powerful design tool to measure every pixel on your screen. Hit #1 on Product Hunt, and over $5,000 in sales within 24 hours of their launch. 📝✨
Hey, even cooler!
A couple people pointed out xScope, which also has this feature. Fifty bucks, but also has a ton of other features. Tempting.
This is a particular design trick that never fails to catch people’s eye! I don’t know the exact history of who-thought-of-what first and all that, but I know I have seen a number of implementations of it over the years. I figured I’d round a few of them up here.
The detection here is done by tracking the mouse position on mouseover and mouseout and calculating which side was crossed. It’s a small amount of clever JavaScript, the meat of which is figuring out that direction:
var getDirection = function (ev, obj) {
var w = obj.offsetWidth,
h = obj.offsetHeight,
x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)),
y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)),
d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4;
return d;
};
Then class names are applied depending on that direction to trigger the directional CSS animations.
Fabrice uses just pure CSS here. They don’t detect the outgoing direction, but they do detect the incoming direction by way of four hidden hoverable boxes, each rotated to cover a triangle. Like this:
_getDir: function (coordinates) {
// the width and height of the current div
var w = this.$el.width(),
h = this.$el.height(),
// calculate the x and y to get an angle to the center of the div from that x and y.
// gets the x value relative to the center of the DIV and "normalize" it
x = (coordinates.x - this.$el.offset().left - (w / 2)) * (w > h ? (h / w) : 1),
y = (coordinates.y - this.$el.offset().top - (h / 2)) * (h > w ? (w / h) : 1),
// the angle and the direction from where the mouse came in/went out clockwise (TRBL=0123);
// first calculate the angle of the point,
// add 180 deg to get rid of the negative values
// divide by 90 to get the quadrant
// add 3 and do a modulo by 4 to shift the quadrants to a proper clockwise TRBL (top/right/bottom/left) **/
direction = Math.round((((Math.atan2(y, x) * (180 / Math.PI)) + 180) / 90) + 3) % 4;
return direction;
},
It’s technically CSS doing the animation though, as inline styles are applied as needed to the elements.
John leaned on Greensock to do all the detection and animation work here. Like all the examples, it has its own homegrown geometric math to calculate the direction in which the elements were hovered.
// Detect Closest Edge
function closestEdge(x,y,w,h) {
var topEdgeDist = distMetric(x,y,w/2,0);
var bottomEdgeDist = distMetric(x,y,w/2,h);
var leftEdgeDist = distMetric(x,y,0,h/2);
var rightEdgeDist = distMetric(x,y,w,h/2);
var min = Math.min(topEdgeDist,bottomEdgeDist,leftEdgeDist,rightEdgeDist);
switch (min) {
case leftEdgeDist:
return "left";
case rightEdgeDist:
return "right";
case topEdgeDist:
return "top";
case bottomEdgeDist:
return "bottom";
}
}
// Distance Formula
function distMetric(x,y,x2,y2) {
var xDiff = x - x2;
var yDiff = y - y2;
return (xDiff * xDiff) + (yDiff * yDiff);
}
Gabrielle gets it done entirely in CSS by positioning four hoverable child elements which trigger the animation on a sibling element (the cube) depending on which one was hovered. There is some tricky stuff here involving clip-path and transforms that I admit I don’t fully understand. The hoverable areas don’t appear to be triangular like you might expect, but rectangles covering half the area. It seems like they would overlap ineffectively, but they don’t seem to. I think it might be that they hang off the edges slightly giving a hover area that allows each edge full edge coverage.
Elmer is also using clip-path here, but the four hoverable elements are clipped into triangles. You can see how each of them has a point at 50% 50%, the center of the square, and has two other corner points.
Raw JavaScript powers Nigel’s demo here, which is all modernized to work with npm and modules and all that. It’s familiar calculations though:
const _getDirection = function (e, item) {
// Width and height of current item
let w = item.offsetWidth;
let h = item.offsetHeight;
let position = _getPosition(item);
// Calculate the x/y value of the pointer entering/exiting, relative to the center of the item.
let x = (e.pageX - position.x - (w / 2) * (w > h ? (h / w) : 1));
let y = (e.pageY - position.y - (h / 2) * (h > w ? (w / h) : 1));
// Calculate the angle the pointer entered/exited and convert to clockwise format (top/right/bottom/left = 0/1/2/3). See https://stackoverflow.com/a/3647634 for a full explanation.
let d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4;
// console.table([x, y, w, h, e.pageX, e.pageY, item.offsetLeft, item.offsetTop, position.x, position.y]);
return d;
};
Uri Shaked has written about his journey in AR on the web from the very early days of Google’s Project Tango to the recent A-Frame experiments from Mozilla. Front-end devs might be interested in A-Frame because of how you work with it – it’s a declarative language like HTML! I particularly like this section where Uri describes how it felt to first play around with AR:
The ability to place virtual objects in the real space, and have them stick in place even when you move around, seemed to me like we were diving down the uncanny valley, where the boundaries between the physical world and the game were beginning to blur. This was the first time I experienced AR without the need for markers or special props — it just worked out of the box, everywhere.
I have been obsessed with User Interfaces (UI) for as long as I can remember. I remember marveling at the beauty that was Compaq TabWorks while I played „The Incredible Machine” and listened to „Tears For Fears—Greatest Hits” on the family computer.
Don’t judge me—I was listening to „Mad World” way before Donny Darko and that creepy rabbit. If none of those references landed with you, it’s probably because I’m super old. In the words of George Castanza, „It’s not you, it’s me.”
That’s another super old reference you might not get. You know what—forget all that, let’s move on.
I really got into UI when I bought my own computer. I had joined the Coast Guard and saved a bunch of money during boot camp (when you can’t go shopping—you know—because of push-ups and stuff). I wanted to buy a Chevy Cavalier (sadly, that’s not a joke), but my father encouraged me to invest in a computer instead, so I bought a Compaq from Office Depot that came with Windows 98. Also you can’t buy a Cavalier with 800 bucks.
Windows 98
I spent countless hours changing the themes in Windows 98. I was mesmerized by the way windows overlapped and how the icons and fonts would change; the shapes of buttons and the different colors. The slight drop shadow each window had to layer it in space. Each theme was better than the previous theme!
Oh, The depth of the blues! The glory of fish! BREATHTAKING.
If only I had known how much better things were going to get. If only I had known, about Windows XP.
Windows XP
Does love at first sight exist? No—don’t be ridiculous. Love is an extremely complex part of the human condition that can only manifest itself over time through long periods of struggling and the dark night of the soul.
„What is love? Baby don’t hurt me. Don’t hurt me. No more.”
But love’s fickle and cruel cousin, Infatuation, does exist and it is almost exclusively available at first sight. I was absolutely infatuated with Windows XP.
The curves on the start menu. The menu animations. I could just look at it for hours. And I did. Shocking fact—I wasn’t exactly in high social demand so I had a great deal of free time to do weird things like stare at an operating system.
For those who remember, Windows XP was extremely customizable. Virtually every part of the operating system could be skinned or themed. This spawned a lot of UI hacking communities and third party tools like Window Blinds from the fine folks at Stardock. I see you Stardock; the north remembers.
I Love UI
I could go on and on about my long, boring and slightly disturbing obsession with UI. Oddly enough, I am not a designer or an artist. I can build a decent UI, but you would not hire me to design your site. Or you would but your name would be „Burke’s Mom.”
Awww. Thanks, Mom. I can do 3 images.
I can however assemble great UI if I have the building blocks. I’ve been lucky enough to work on some great UI projects in my career, including being part of the Kendo UI project when it first launched. I love buttons, dropdown lists, and dialogue windows with over the top animation. And I can assemble those parts into an application like Thomas Kinkade. I am the UI assembler of light.
But as a user, one thought has been recurring for me during the past few years: the best user experience is really no user interface at all.
UI is a Necessary Evil
The only reason that a UI even exists is so that users can interact with our systems. It’s a middle-man. It’s an abstracted layer of communication and the conversation is pre-canned. The user and the UI can communicate, but only within the specifically defined boundaries of the interface. And this is how we end up with GLORIOUS UX fails like the one that falsely notified Hawaiian residents this past weekend of an incoming ballistic missile.
This is the screen that set off the ballistic missile alert on Saturday. The operator clicked the PACOM (CDW) State Only link. The drill link is the one that was supposed to be clicked. #Hawaiipic.twitter.com/lDVnqUmyHa
We have to anticipate how the user is going to think or react and everyone is different. Well designed systems can get us close to intuitive. I am still a fan of skeumorphic design and „sorry not sorry.” If a 4 year old can pick up and use and iPad with no instruction, that’s kind of a feat of UX genius.
That said, even a perfect UI would be less than ideal. The ideal is to have no middleman at all. No translation layer. Historically speaking, this hasn’t been possible because we can’t „speak” to computers.
Until now.
Natural-Language Processing
Natural-language processing (NLP) is the field of computing that deals with language interaction between humans and machines. The most recognizable example of this would be the Amazon Echo, Siri, Cortana or Google. Or „OK Google.” Or whatever the heck you call that thing.
I firmly believe that being able to communicate with an AI via spoken language is a better user interaction than a button—every time. To make this case, I would like to give you three examples of how NLP can completely replace a UI and the result is a far better user experience.
Exhibit A: Hey Siri, Remind Me To…
Siri is not a shining example of „a better user experience,” but one thing that it does fairly well and the thing I use it for almost every day, is creating reminders.
It is a far better user experience to say „Hey Siri, remind me to email my mom tomorrow morning 9 AM” than it is to do this…
Open the app
Tap a new line
Type out the reminder
Tap the „i”
Select the date
Tap “Done”
No matter how beautiful the Reminders app is, it will never match the UX of just telling Siri to do it.
Now this comes with the disclaimer of, „when it works.” Siri frequently just goes to lunch or cuts me off halfway through which results in a nonsensical reminder with no due date. When NLP goes wrong, it tends to go WAY wrong. It’s also incredibly annoying as anyone who as EVER used Siri can attest.
This is a simple example, and one that you might already be aware of or not that impressed with. Fair enough; here’s another: Home Automation.
Exhibit B: Home Automation
I have a bunch of the GE Z-Wave switches installed in my house. I tie them all together with a Vera Controller. If you aren’t big into home automation, just know that the switches connect to the controller and the controller exposes the interface with which to control them, allowing me to turn the lights on and off with my phone.
The Vera app for controlling lights is quite nice. It’s not perfect, but the UX is decent. For instance, if I wanted to turn on the office lights, this is how I would do it using the app.
I said it was „quite nice.” Not perfect. I’m just saying I’ve seen worse.
To be honest though, when I want to turn a light on or off, I don’t want to go hunting and pecking through an app on my phone to do it. That is not awesome. I want the light on and I want it on now. Turning lights on and off via your phone is a step backward in usability when compared to, I don’t know, A LIGHT SWITCH?
What is awesome, is telling my Echo to do it.
I can, for any switch in my house, say…
“Alexa, turn on/off the office lights”
Or the bedroom, or the dining room or what have you. Vera has an Alexa skill that allows Alexa to communicate directly with the controller and because Alexa uses NLP, I don’t have to say the phrase exactly right to get it to work. It just works.
Now, there is a slight delay between the time that I finish issuing the command and the time that Alexa responds. I assume this is the latency to go out to the server, execute the skill, call back into my controller, turn off the light, go back out to the skill in the cloud and then back down into my house.
I’m going to be honest and say that I sometimes get irritated that it takes a second or two to turn the lights on. Sure—blah blah blah technical reasons, but I don’t care. I want the lights on and I want them on NOW. Like Veruca Salt.
I also have Nest thermostats which I can control with the Echo and I gotta tell you, being able to adjust your thermostat without even getting out of bed is kind of, well, it’s kind of pathetic now that I’ve said it out loud. Never mind. I never ever do that.
NLP doesn’t have to be limited to the spoken word. It turns out that interfacing with computers via text is STILL better than buttons and sliders.
For that, I give you Exhibit C.
Exhibit C: Digit
Digit is a remarkable little service that I discovered via a Twitter ad. You’ve aways wondered who clicks on Twitter ads and now you know.
I wish more people knew about Digit. The basic premise behind the service is that they save money for you automatically each month by running machine learning on your spending habits to figure out where they can save money without sending you into the red.
The most remarkable thing about Digit is that you don’t interface with it via an app. Everything is done via text; and I love it.
Digit texts me every day to give me an update on my bank account balance. This is a nice daily heads up look at my current balance.
Yes, I blurred out my balance. It’s so you don’t get depressed on my behalf.
If I want to know how much Digit has saved for me, I just ask how much is in my savings. But again, because Digit is using NLP, I can ask it however I like. I can even just use the word „savings” and it still works. It’s almost like I’m interfacing with a real person.
Now if I want to transfer some of that back into savings because I want to buy more Lego and my wife says that Lego are a „want” not a „need” and that we should be saving for our kids „college,” I can just ask Digit to transfer some money. Again, I don’t have to know exactly what to say. I can interface with Digit until I get the right result. Even If I screw up mid-transaction, Digit can handle it. This is basically me filling out a form via text without the hell that is „filling out a form.”
After using Digit via text for so long, I now want to interface with everything via text. Sometimes it’s even better than having to talk out loud, especially if you are in a situation where you can’t just yell something out to a robot, or you can’t be bothered to speak. I have days like that too.
Is UX as We Know it Dead?
No. Emphatically no. NLP is not a substitution for all user interfaces. For instance, I wouldn’t want to text my camera to tell it to take a picture. Or scroll through photos with my voice. It is, however, a new way to think about how we design our user interfaces now that we have this powerful new form of input available.
So, before you design that next form or shopping cart, ask yourself: Do I really even need this UI? There’s a good chance that thanks to NLP and AI/ML, you don’t.
How to Get Started With NLP
NLP is far easier to create and develop than you might think. We’ve come a long way in terms of developer tooling. You can check out the LUIS project from Azure which provides a GUI tool for building and training NLP models.
It’s free and seriously easy.
Here’s a video of me building an AI that can understand when I ask it to turn lights on or off by picking the light state and room location out of an interaction.
It came across as (particularly trite) commentary about Website Sameness™. I suppose it was. I was looking at lots of sites as I was putting together The Power of Serverless. I was actually finding it funny how obtuse the navigation often is on a SaaS sites. Products? Solutions? Which one is for me? Do I need to buy a product and a solution? Sometimes they make me feel dumb, like I’m not informed enough to be a customer. What’s the harm is just telling me exactly what your thing does?
But anyway, people commenting on Website Sameness™ has plenty of history onto itself. One of the most memorable stabs was from Jon Gold:
They style itself is now so mainstream that clients ask for it. It’s happened to me, more than once. I’ve created sites that follow the formula. This surely is another reason. If clients are seeing a lot of sites that are the same style, it’s causing them to ask for it.
Mary Collins says Dave’s sentiment rang true right away:
Myself, I’m not sure how much I care. If a website fails to do do what it sets out to do, that, I care about. Design is failing there. But if a website has a design that is a bit boring, but does just what everyone needs it to do, that’s just fine. All hail boring. Although I admit it’s particularly ironic when a design agency’s own site feels regurgitated.
As long as I’m playing armchair devil’s advocate, if every website was a complete and total design departure from the next, I imagine that would be worse. To have to-relearn how each new site works means not taking advantages of affordances, which make people productive out of the gate with new experiences.
It’s probably fair to say, though, that design uniqueness and affordances need not be at odds. Surely you can design a site that is aesthetically unique, yet people still know how to use the dropdown menus.
There has been a lot of scapegoats for Website Sameness™ over the years. The popularity of frameworks. Flat design as a trend. Performance holding back creativity. User expectations. Research telling us that our existing patterns work. The fact that what websites are all largely trying to do the same things. Even responsive design is a popular whipping boy. We might as throw style guides / pattern libraries on the heap.
So again, I’m not sure how much I care. Partially because of these two things:
Designers have all the tools they need to make websites as unique as they like.
There is an awful lot of money in websites, and an awful lot of people trying to get their hands on it.
If design uniqueness was a lever you could pull for increased success for any type of business, you’d better believe it would be pulled a lot more often.
You’ve heard of CSS Grid, I’m sure of that. It would be hard to miss it considering that the whole front-end developer universe has been raving about it for the past year.
Whether you’re new to Grid or have already spent some time with it, we should start this post with a short definition directly from the words of W3C:
Grid Layout is a new layout model for CSS that has powerful abilities to control the sizing and positioning of boxes and their contents. Unlike Flexible Box Layout, which is single-axis–oriented, Grid Layout is optimized for 2-dimensional layouts: those in which alignment of content is desired in both dimensions.
In my own words, CSS Grid is a mesh of invisible horizontal and vertical lines. We arrange elements in the spaces between those lines to create a desired layout. An easier, stable, and standardized way to structure contents in a web page.
Besides the graph paper foundation, CSS Grid also provides the advantage of a layout model that’s source order independent: irrespective of where a grid item is placed in the source code, it can be positioned anywhere in the grid across both the axes on screen. This is very important, not only for when you’d find it troublesome to update HTML while rearranging elements on page but also at times when you’d find certain source placements being restrictive to layouts.
Although we can always move an element to a desired coordinate on screen using other techniques like translate, position, or margin, they’re both harder to code and to update for situations like building a responsive design, compared to true layout mechanisms like CSS Grid.
In this post, we’re going to demonstrate how we can use the source order independence of CSS Grid to solve a layout issue that’s the result of a source order constraint. Specifically, we’re going to look at checkboxes and CSS Counters.
Counting With Checkboxes
If you’ve never used CSS Counters, don’t worry, the concept is pretty simple! We set a counter to count a set of elements at the same DOM level. That counter is incremented in the CSS rules of those individual elements, essentially counting them.
Here’s the code to count checked and unchecked checkboxes:
<input type="checkbox">Checkbox #1<br>
<input type="checkbox">Checkbox #2
<!-- more checkboxes, if we want them -->
<div class="total">
<span class="totalChecked"> Total Checked: </span><br>
<span class="totalUnChecked"> Total Unchecked: </span>
</div>
In the above code, two counters are set at the root element using the counter-reset property and are incremented at their respective rules, one for checked and the other for unchecked checkboxes, using counter-increment. The values of the counters are then shown as contents of two empty <span>s’ pseudo elements using counter().
Here’s a stripped-down version of what we get with this code:
This is pretty cool. We can use it in to-do lists, email inbox interfaces, survey forms, or anywhere where users toggle boxes and will appreciate being shown how many items are checked and how many are unselected. All this with just CSS! Useful, isn’t it?
But the effectiveness of counter() wanes when we realize that an element displaying the total count can only appear after all the elements to be counted in the source code. This is because the browser first needs the chance to count all the elements, before showing the total. Hence, we can’t simply change the markup to place the counters above the checkboxes like this:
<!-- This will not work! -->
<div class="total">
<span class="totalChecked"> Total Checked: </span><br>
<span class="totalUnChecked"> Total Unchecked: </span>
</div>
<input type="checkbox">Checkbox #1<br>
<input type="checkbox">Checkbox #2
Then, how else can we get the counters above the checkboxes in our layout? This is where CSS Grid and its layout-rendering powers come into play.
Adding Grid
We’re basically wrapping the previous HTML in a new <div> element that’ll serve as the grid container:
.grid {
display: grid; /* creates the grid */
grid-template-columns: repeat(2, max-content); /* creates two columns on the grid that are sized based on the content they contain */
}
.total {
grid-row: 1; /* places the counters on the first row */
grid-column: 1 / 3; /* ensures the counters span the full grid width, forcing other content below */
}
This is what we get as a result (with some additional styling):
See that? The counters are now located above the checkboxes!
We defined two columns on the grid element in the CSS, each accommodating its own content to their maximum size.
When we grid-ify an element, its contents (text including) block-ify, meaning they acquire a grid-level box (similar to block-level box) and are automatically placed in the available grid cells.
In the demo above, the counters take up both the grid cells in the first row as specified, and following that, every checkbox resides in the first column and the text after each checkbox stays in the last column.
The checkboxes are forced below the counters without changing the actual source order!
Since we didn’t change the source order, the counter works and we can see the running total count of checked and unchecked checkboxes at the top the same way we did when they were at the bottom. The functionality is left unaffected!
To be honest, there’s a staggering number of ways to code and implement a CSS Grid. You can use grid line numbers, named grid areas, among many other methods. The more you know about them, the easier it gets and the more useful they become. What we covered here is just the tip of the iceberg and you may find other approaches to create a grid that work equally well (or better).