Checkout my Getting Started with React video course on Skillshare. It is 100% free.

Defining names for lines in CSS grid

The CSS Grid uses lines to position the elements. By default, we can use line numbers to place the elements.

But if you find notations like .header { grid-column: 1 / 3; } confusing then we can define name for these lines.

The name defining is done in the grid-template-columns (and, if needed, in the grid-template-rows):

.container {
    display: grid;
    grid-template-columns: [article-start] 2fr [picture-start] 1fr [nav-start] 80px [nav-end];
}

So now we can say:

.header {
    grid-column: article-start / nav-start;
}
.article {
    grid-column: article-start/picture-start;
}
.picture {
    grid-column: picture-start / nav-start;
}
.navigation {
    grid-column: nav-start / nav-end;
}

Check out below the full working example.

See the Pen
Using names for CSS grid lines
by JS Craft (@js-craft)
on CodePen.

Defining multiple names for the same lines

But wait, there is more! We can define more that one name for a line.

It would be cool to define our article with something like article-start to article-end.

However, the article-end will be the starting point for the picture section. This means that we will then have to write for the picture: grid-row: article-end / nav-start; instead of an ideal grid-row: picture-start / picture-end;

In most cases, the ending point for something is the starting point for something else. So, therefore, the need to have multiple names for the same line.

We can implement this by just adding an extra name in the square brackets.

.container {
  grid-template-columns: 
      [article-start] 
      2fr 
      [article-end picture-start] 
      1fr 
      [picture-end nav-start] 
      80px 
      [nav-end];
}

So that we can now say:

.picture {
    grid-row: picture-start / picture-end;
}

Check out here the codepen with multiple names for the same lines. Cheers!

How and why to use the repeat function in CSS Grid

Let's say we have a layout made of 10 equal-width columns. Then the container element will look like this:

.container {
    grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr 1fr;
}

It's a bit troublesome to write a line where you paste ten times the same 1fr. Imagine how fun it's to read this line. Luckily we have the repeat function for situations like this one.

.container {
    grid-template-columns: repeat(10, 1fr);
}

A big readability improvement. You tell the function how many times to repeat, and what to repeat.

If works for both the grid-template-columns and grid-template-rows.

We can give it also a pattern to repeat:

.container {
    grid-template-columns: repeat(3, 1fr 50px);
    // it will create 6 columns
    // 1fr 50px 1fr 50px 1fr 50px 
}

Using the CSS grid repeat function with named lines

And we can even use it with named lines.

.container {
    grid-template-columns: repeat(3, [col-start ] 1fr [col-end] );
    // it will create 3 columns
    // [cstart ] 1fr  [cend] [cstart ] 1fr  [cend]  [cstart ] 1fr  [cend] 
}

Given the fact that we will have the same name for the columns, we will need to a second parameter in the grid-column to indicate instance number of the name we want to place an element:

.my-element {
    grid-column: cstart 2 / cend 2;
}

Using the repeat function with auto-fill

But what if we want to have a layout where we want to have as many columns of 200px as they fit in the width of the container? Well, for this we can use the auto-fill:

.container {
    grid-template-columns: repeat( auto-fill , 200px );
    // it will  make as many 200px columns as possible 
    // eq: your screen is 1500px , it will make 7 columns
}

And that's all for now, folks! Have a fantastic day!

CSS Attribute selector – case insensitive option and select by multiple attributes

Some days ago I have written a short intro to the attribute selector in CSS. I have found out two new tricks for this selector that I want to share with you today.

Case-insensitive CSS attribute selectors

First, the attribute selector is case sensitive. This can be especially troublesome for the data- attributes.

Take for example the following set of tags:

<div data-status="OPEN">First widget</div>
<div data-status="open">Second widget</div>
<div data-status="open">Third widget</div>

Give the case sensitivity the following selector will target only the first div.

// will target only the first div
div[data-status="OPEN"] { color: red;} 

But, we have the i flag in the attribute selector. And with it, we can target tags no matter the capitalization.

// will target all the divs
div[data-status="OPEN" i] { color: red;} 

Pay atattion to the fact that the i flag will not work in IE.

CSS attribute selector for multiple tags

The second trick is the ability to target tags based on multiple attributes.

For example, if we want to target all the h1 tags that have both a rel="main subject" and a title="important note":

<h1 rel="main subject" title="important note">Multiple Attributes</h1>    

Then we can write

h1[rel="main subject"][title^="important note"] { 
    color: red; 
}

Learned this one from the excellent CSS Tricks article: The Skinny on CSS Attribute Selectors.

How to style empty cells – using :empty and empty-cells

There are cases when we don't have data for all the cells in a table. If you want an easy way to make these specific cells to stand out we can use the :empty pseudo-class selector.

See the Pen
Table with empty highlighted
by JS Craft (@js-craft)
on CodePen.

And we can even chain the :empty with the the :before pseudo-class and give the user more context about what the empty cells represent:

See the Pen
mdeVNQq
by JS Craft (@js-craft)
on CodePen.

Also, the table element has a special CSS property named, you guessed it, empty-cells.

See the Pen
Hide empty cells
by JS Craft (@js-craft)
on CodePen.

The downside with this empty-cells prop is that you can only hide the cels. So for better customization of the cells the :empty may be a better fit.

Have fun, and enjoy the simple things in CSS.

The grid layout: the grid-column and grid-column properties are using line numbers

When placing elements in a CSS grid it's very important to remember that the grid is using the lines number to place the elements.

Take for example the following layout.

For the columns, we have 4 lines. So, for the footer element when we are declaring grid-column: 1/4 we are saying that the element starts from line 1 and ends at line 4.

The same is true also when using grid-column We are not referring to cells, but to the actual line numbers.

This was for me one of the aha moments when using the learning the grid layout.

Below you have the full code for this layout.

See the Pen
CSS Line Numbers
by JS Craft (@js-craft)
on CodePen.

And in the next post, we will see how we can even actually give names to both the columns and rows lines.

Making a responsive CSS grid layout with just 3 properties

What if I told you that you only need to know only 3 CSS properties to make a fully responsive CSS grid like the one below:

Let's start with the HTML layout. Just a container and the divs corresponding to the articles and header + footer:

<div class="container">
  <div class="header">Header</div>
  <div class="art first">Article 1</div>
  <div class="art second">Article 2</div>
  <div class="art third">Article 3</div>
  <div class="footer">Footer</div>
</div>

First, we will need to set up our container to grid and add a bit of gap between the cells :

.container {
  display: grid;
  grid-gap: 10px;
}

The most important part is made of defining the actual grid. If we would put this layout in an Excell table, it would look like this:

This can be translated into CSS by using the grid-template-areas property:

.container {
 grid-template-areas: 
    "h  h  h"
    "a1 a2 a3"
    "f  f  f"; 
  display: grid;
  grid-gap: 10px;
}

And now to place the HTML elements in the corresponding CSS grid cell we can use the grid-area prop:

.header { grid-area: h; }
.art.first { grid-area: a1; }
.art.second { grid-area: a2; }
.art.third { grid-area: a3; }
.footer { grid-area: f; } 

Making the CSS grid responsive

In order to make this one responsive, we can just change the table layout:

So a media query to and again grid-template-areas to the rescue.

@media only screen and (max-width: 600px) {
  .container {
    grid-template-areas: 
        "h"
        "a1"
        "a2"
        "a3"
        "f";
  }
}

We could have also used the display:block, but the idea is just to show how flexible and useful grid-template-areas can be to manage our layout configurations.

And that's all folks! Just 3 properties (grid-area, grid-gap and grid-template-areas ) to make a fully responsive CSS Grid layout.

You can see below the full working codepen for this example. Cheers!

See the Pen
Simple CSS Grid
by JS Craft (@js-craft)
on CodePen.

Fun games to learn CSS Grid and Flexbox

You may know that I like video games. Never been a gamer, but after all, I've started to code because of games.

I have discovered 3 funny games that aim to teach how to use the CSS Grid Layout and Flexbox.

The first two are focused on my favorite, the CSS Grid: cssgridgarden.com and gridcritters.com.

And the third one is aimed to flexbox, the flexboxfroggy.com.

The games can help a lot to teach and strengthen the basic concepts of CSS Grid and Flexbox. But, you will need to put them into practice. So get yourself a nice code editor and start messing around!

For example try to replicate the login page of sites like https://www.facebook.com/, https://www.instagram.com/. Or whatever site you like the most and it's simple enough to replicate.

A CSS tricky situation- the order of the CSS class names in the HTML tags

Let's say we have the following set of rules in a CSS file:

.red {
    color: red;
}

.blue {
    color: blue;
}

.green {
    color: green;
}

And the following tags in our HTML:

<div class="red green blue"> First div.</div>
<div class="blue red green"> Second div.</div>
<div class="green blue red"> Third div.</div>

The question is: what color will we have for these divs? Stop for a few seconds and try to answer the question.

The correct answer: they’re all green.

The order of the class names in HTML tags has no importance on the styles. The lines class="red green blue", class="blue red green" or class="green blue red" are the same thing.

All 3 selectors have the same specificity (just a simple class selector). And given that .green comes later in the stylesheet, it will override the .red and .blue selectors.

Therefore all the divs will have the color green. Cascading wins again.

By the way, this can make a great CSS interview question 🙂

CSS logical properties: using the margin-block and margin-inline instead of the default margin

Take the following example. We have a link, followed by a few words. And we want a 20px margin space between the link and the text.

.container {
    border: 1px solid black;
    display: float;
    padding: 5px;
}

a {
    margin-right: 20px; 
    background-color: yellow;
}
A link

some text

In this content adding a margin-right: 20px; makes perfect sense.

But what if the flex-direction of the container changes in reverse? Or the user is using a translation extension? Arabic is read right to left.

Then our element will look like this:

A link

some text

The margin will still be on the right side, and we will have to add some more lines of code to make it work again.

Meet the CSS logical properties. We can replace the plain old margin with margin-inline-start: 20px;.

a {
    margin-inline-start: 20px; 
}

What it does is instead of saying "add a margin to the right”, we will have “regardless of direction, put a margin on the starting side”. It does not matter if the starting side is on the left or the right.

A link

some text

Pretty cool, no? 🙂

If we want to replace some other margins, we can use the following table of correspondence:

margin-top      -> margin-block-start
margin-left     -> margin-inline-start
margin-right        -> margin-inline-end
margin-bottom   -> margin-block-end

And it works also with border and padding.

How CSS resolves conflicts: Cascading

In CSS if we have multiple rules, with the same specificity, competing for the same elements then the last declaration always wins.

This is the C, the Cascading, from the CSS acronym.

Cascading rules in the same CSS file

For example, if we have:

p { color: red };
/// other CSS rules
p { color: blue};

Then our paragraphs will be blue.

Cascading rules when importing different CSS files

This is also available when importing CSS files. If the stylesheets have conflicting rules for the same elements, the last imported rule will be applied.

// red.css
p { color: red };
// blue.css
p { color: blue };

And if we import both of these files in the same document

// index.html
<link rel="stylesheet" type="text/css" href="red.css">
<link rel="stylesheet" type="text/css" href="blue.css">

Then our paragraphs will be blue given the order of the files.

It does not matter even if we have the decoration of the CSS in the head of the HTML document. The last imported rule will win.

// index.html
<html>
    <head>
        <style>
            p {color: red;}
        </style>
        <link rel="stylesheet" type="text/css" href="blue.css">
    </head>
    <body>
        <p>This will be a blue paragraph.</p>
    </body>
</html>>

Cascading rules in the same declaration block

Finally, this also applies to the actual declarations blocks of the properties. Take for example the following code:

Like in the previous examples, the paragraphs will still be blue.

p {
    color: red;
    font-size: 16px;
    line-height: 32px;
    background-color: #eee;
    border: none;
    color: blue;
}

By the way, because of situations like this one, it may be a good practice to have the properties declared in alphabetical order and avoid just dropping a new declaration at the end of the block.

p {
    background-color: #eee;
    border: none;
    // conflicts are easyer to track 
    color: red;
    color: blue;
    font-size: 16px;
    line-height: 32px;
}