惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
博客园_首页
Vercel News
Vercel News
WordPress大学
WordPress大学
美团技术团队
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
Y
Y Combinator Blog
博客园 - 【当耐特】
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
The Cloudflare Blog
T
The Blog of Author Tim Ferriss
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
云风的 BLOG
云风的 BLOG
腾讯CDC
M
MIT News - Artificial intelligence
爱范儿
爱范儿
Recent Announcements
Recent Announcements
雷峰网
雷峰网
Last Week in AI
Last Week in AI
宝玉的分享
宝玉的分享
The Register - Security
The Register - Security
Jina AI
Jina AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Hugging Face - Blog
Hugging Face - Blog
P
Privacy & Cybersecurity Law Blog
Recorded Future
Recorded Future
Help Net Security
Help Net Security
N
News and Events Feed by Topic
博客园 - Franky
P
Proofpoint News Feed
L
LINUX DO - 热门话题
S
SegmentFault 最新的问题
The GitHub Blog
The GitHub Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
D
Docker
Google DeepMind News
Google DeepMind News
有赞技术团队
有赞技术团队
IT之家
IT之家
Security Latest
Security Latest
L
LangChain Blog
V
V2EX
阮一峰的网络日志
阮一峰的网络日志
J
Java Code Geeks

Ahmad Shadeed

Better fluid sizing with round() Use Cases for Field Sizing The Basics of Anchor Positioning Item Flow CSS Relative Colors Balancing Text In CSS Should masonry be part of CSS grid? CSS display contents CSS Grid Areas CSS Cap Unit An Interactive Guide to CSS Container Queries CSS :has() Interactive Guide CSS Nesting UX in DevTools CSS Nesting Future CSS: State Container Queries Rebuilding a comment component with modern CSS Conditional CSS with :has and :nth-last-child CSS Text balancing with text-wrap:balance CSS Masking Do we need CSS flex-wrap detection? My CSS Wishlist Conditional CSS CSS Style Queries Inside the mind of a frontend developer: Article layout Inside the mind of a frontend developer: Hero section CSS container queries are finally here The CSS behind Figma First Look At The CSS object-view-box Property Learn CSS Subgrid CSS :has Parent Selector Aligning Content In Different Wrappers Flexbox Dynamic Line Separator Hello, CSS Cascade Layers Building UI Components With SVG and CSS A Deep CSS Dive Into Radial And Conic Gradients Defensive CSS Building Real-life Components: Facebook Messenger Conditional Border Radius In CSS CSS Container Query Units Less Absolute Positioning With Modern CSS Aligning a Button Label Vertically Comparing Design Mockups To Code Result Using HSL Colors In CSS Custom Scrollbars In CSS Let CSS Container Queries For Designers The State of CSS Cross-Browser Development Overflow Issues In CSS Inspect Element As A Way To Increase Your Curiosity Handling Text Over Images in CSS Digging Into CSS Logical Properties Clipping Scrollable Areas On The inline-start Side Understanding Clip Path in CSS The Art of Building Real-life Components Handling Short And Long Content In CSS CSS Scroll Snap A Deep Dive Into CSS Grid minmax() CSS Variables 101 Finding The Root Cause of a CSS Bug Learn CSS centering How to detect browser support for Flexbox Gap CSS Mistakes While On Autopilot Digging Into the Flex Property Understanding CSS Multiple Backgrounds Aligning Logo Images in CSS Grid for layout, Flexbox for components Colors in CSS Thinking About The In-between Design Cases min(), max(), and clamp() CSS Functions Image Techniques On The Web Everything About Auto in CSS Learn Box Alignment Let Learn CSS Positioning Intrinsic Sizing In CSS CSS Grid Template Areas In Action Hiding Elements On The Web Creating a Variable Color Font From Scratch Building a Football Ticket With CSS and SVG Blending Modes in CSS CSS Variables With Inline Styles Implementing Dark Mode For My Website Rebuilding Apple Music Header in HTML & CSS Accessible Checkbox Layout Flickering On Browser Resize Enhancing The Clickable Area Size Custom Underlines with SVG Part 3: The Process of Implementing A UI Design From Scratch Part 2: The Process of Implementing A UI Design From Scratch Building An Old Nav Design CSS Flexbox: 5 Real World Use Cases I Used CSS Inline Flex For The First Time The Process of Implementing A UI Design From Scratch Common CSS Issues For Front-End Projects Handling Long and Unexpected Content in CSS How to Build Web Form Layouts With CSS Grid Enhancing Our Components with CSS :empty Building Resizeable Components with Relative CSS Units CSS Writing Mode The Journey of Learning Front End Web Development on a Daily Basis
Grid Layout Ah-ha Moment
Ahmad Shadeed · 2016-11-23 · via Ahmad Shadeed

The Layout Maestro

I spent years teaching CSS layout on this blog. I put everything I know into The Layout Maestro course: 70+ lessons and 150+ interactive examples that teach you how to think CSS layouts, not just memorize syntax.

Get the course

It’s almost the end of 2016, our needs for a robust and powerful way of laying out elements on the web is increasing everyday. We need to build a unique and art-directed layouts in the easiest way in CSS. Grid layout is here to provide us with a way to divide content into rows and columns, with the ability to move and shift them without affecting the source order.

I’m very excited about CSS Grid Layout, it will land in browsers by Q1 2017 and from then we should start using it as enhancement with CSS @supports. In this article, I will share all of what I learned about Grid in the past two weeks, with real-world examples. Let’s start.

Update: It’s now enabled by default in Chromium as per Manuel Rego on Twitter. Also, Firefox 52 will enable it by default and is expected to be released in Jan/Feb 2017.

What is CSS Grid?

A new CSS layout module that provide us with the ability to control our content in two dimensions, as rows and columns. We can control and place each child item in the grid by defining the number of columns and rows.

Getting Started

The first step is to add display: grid to the parent element. Now, every item inside this wrapper will be a grid item. The child items won’t be affected by that, at least we need to define the number of columns we want.

{% highlight css %} .wrapper { display: grid; grid-template-columns: 200px 200px 200px; }

.item { height: 100px; } {% endhighlight %}

By using grid-template-columns, we can define how many columns we want, each value is representing a column.

We have 3 columns and each one of them has a width of 200px. If we have 4 items inside our wrapper for a markup like the below, can you expect the result?

{% highlight html %}

{% endhighlight %}

Result:

As you see, we have 3 columns and so the last item is wrapped to the next row. Note that there is no space between them, the dashed line is added only for clarity.

Vertical and Horizontal Space

To add a space between the items, we can use grid-column-gap and grid-row-gap to achieve that.

{% highlight css %} .wrapper { display: grid; grid-template-columns: 200px 200px 200px; grid-column-gap: 10px; grid-row-gap: 10px; } {% endhighlight %}

Or you can use the shorthand grid-gap: 10px 10px. The values are 10px 10px for row and column respectively.

If you noticed, we only defined the columns number and width. The nice thing is that the browser will implicitly define the rows for us, since the height of each item is 100px, then we will have 2 rows. To proof that, I will inspect element and show you the computed value of grid-template-rows property.

If you noticed, we have these properties on .wrapper element:

{% highlight css %} .wrapper { grid-template-columns: 200px 200px 200px; grid-template-rows: 100px 100px; /_ implicitly added by the browser _/ } {% endhighlight %}

Example 1: News Listing Component

We have 5 news items, the first one is featured and thus its height should be as twice as the other items.

{% highlight html %}

{% endhighlight %}

{% highlight css %} .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr; grid-gap: 10px; } {% endhighlight %}

We divided the columns using fr unit. Its stand for Fraction, by using it we are using something similar to percentages in CSS. We have 3 columns, each one them has a width of 1fr.

1 / 3 = 0.33 = 33%

So each one will take 33% width from the wrapper.

We need a way to tell the first item: “Hey, Please take the first two rows of the grid!”. Remember how the browser implicitly added the rows for us? We will get benefit of that in this example.

The Ah-ha Moment

When I first saw things like grid-row: 1 / 2 or grid-column: 1 / 3, I was a bit confused and got the idea that grid-row: 1 / 2 will give us the space of 2 rows. The same with grid-columns: 1 / 3, it was like taking 3 columns. I took some time to understand the idea of Grid lines, where the Ah-ha momment happened.

The grid is an intersecting set of horizontal and vertical grid lines that divides the grid container’s space into grid areas, into which grid items (representing the grid container’s content) can be placed. CSS Grid Spec

In Grid, there is the concept of Grid Lines for both columns and rows. The following image illustrates that:

Notice that we have 3 lines, starting from the top, middle and at the bottom. The featured item should take space from line 1 to line 3.

In CSS, we will use the following:

{% highlight css %} .item:first-child { grid-row-start: 1; grid-row-end: 3; } {% endhighlight %}

Or as a shorthand:

{% highlight css %} .item:first-child { grid-row: 1 / 3; } {% endhighlight %}

Also, we could make this responsive by accounting for mobile from the beginning, so each news item will take 1 column, and then 2 columns until we reach 3 per column on large screens.

{% highlight css %} .wrapper { display: grid; grid-template-columns: 1fr; /_ 1 column _/ grid-gap: 10px; }

/_ make them as 2 columns per row on viewports > 500px / @media(min-width: 500px) { .wrapper { grid-template-columns: 1fr 1fr; / 2 columns _/ } }

/_ make them as 2 columns per row on viewports > 900px / @media(min-width: 900px) { .wrapper { grid-template-columns: 1fr 1fr 1fr; / 3 columns _/ }

.item:first-child { grid-row: 1 / 3; } } {% endhighlight %}

What if we want to span the featured item in term of columns? Grid layout provide us with the ability to do that. See the below:

We want the featured item to take space from line 1 to 3. In CSS, we can write the following:

{% highlight css %} .item:first-child { grid-column-start: 1; grid-column-end: 3; } {% endhighlight %}

Or as a shorthand:

{% highlight css %} .item:first-child { grid-column: 1 / 3; } {% endhighlight %}

See the Pen Grid Layout - Featured Item by Ahmad Shadeed (@shadeed) on CodePen.

Example 2: Sign up Form

We could get benefit of CSS Grid by using it to lay out the form fields, we can create endless options with it. In our example, the end result is like the design above.

Requirments:

  • 50% width for each input.
  • 100% width for the button.
  • Horizontal and vertical space between the form fields.

{% highlight html %}

{% endhighlight %} Each form item is wrapped in a `

` element, we will use this to control some elements. At the beginning, we need to define a grid:

{% highlight css %} form { display: grid; grid-template-columns: 1fr 1fr; grid-gap: 16px; }

/_ make the button wrapper take space from line 1 to line 3 _/ form p:last-child { grid-column: 1 / 3; } {% endhighlight %}

To make the last <p> element (the button wrapper) take the full width, it should take space from line 1 to line 3. See the below image:

See the Pen Grid Layout - Form Example by Ahmad Shadeed (@shadeed) on CodePen.

Example 3: Sign up Form - 2

In the design above, we have the following requirments:

  • The label to be at the left side of the input field.
  • The button to be aligned with the input fields.

For that case, we don’t need to wrap labels and fields in a <p> element. Grid layout can align them easily for us.

{% highlight html %}

{% endhighlight %}

{% highlight css %} form { display: grid; grid-template-columns: 1fr 2fr; grid-gap: 16px; }

button { grid-column: 2 / 3; } {% endhighlight %}

1fr 2fr means that the fields width will be twice as the label. In order to align the button with the inputs, we need to let it start from line 2 to 3.

See the Pen Grid Layout - Form 2 by Ahmad Shadeed (@shadeed) on CodePen.

Grid Areas

I like to imagine grid areas as table cells, each cell is surrounded by four lines from each side (left, right, top, left). Grid areas are exactly the same.

The nice thing is that we can name our areas and use the names to layout different elements. By using grid-template-areas property, this is possible. We will work on layout like the below:

The first step is to define the grid and number of columns.

{% highlight html %}

Header
<main> .... </main>

<aside>Aside</aside>

<footer>Footer</footer>

{% endhighlight %}

{% highlight css %} .wrapper { display: grid; grid-template-columns: 8fr 4fr; /_ main element will take 8 and 4 cols, respectively. _/ } {% endhighlight %}

To use grid areas, we should assign a name of our choice for each element in the page (header, main, aside and footer).

{% highlight css %} header { grid-area: header; }

footer { grid-area: footer; }

main { grid-area: main; }

aside { grid-area: aside; } {% endhighlight %}

Once we have a name for each element, we will get back to .wrapper and use them there.

{% highlight css %} .wrapper { display: grid; grid-template-columns: 8fr 4fr; grid-template-areas: “header header” “main aside” “footer footer”; } {% endhighlight %}

As you noticed, we added an array of different values, the first one header header, we are setting the header to take the space of the 2 columns we have. The main element will only take the first column (with 8fr width) and the aside will take 4fr. Lastly, the footer will take the space of the 2 columns.

See the Pen Grid Layout - Areas by Ahmad Shadeed (@shadeed) on CodePen.

Repeat Keyword

When we have a certain columns number to repeat, we can use a handy expression that make it easier for us. See the below example:

{% highlight css %} .wrapper { display: grid; grid-template-columns: 100px 100px 100px 100px 100px; } {% endhighlight %}

Notice that we repeated 100px 5 times. At some point, if we decided to change that value, then it might be a bit boring to change them all. By using repeat, this issue will be solved.

{% highlight css %} .wrapper { display: grid; grid-template-columns: repeat(5, 100px); } {% endhighlight %}

Cards Layout

Our goal is to create a responsive cards layout by using repeat expression. Without media queries, we can use minmax() to help us in that.

{% highlight css %} .wrapper { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); } {% endhighlight %}

  • auto-fill, the number of times we want to repeat columns. By adding auto-fill, the value will be calculated automatically by the browser.
  • minmax(250px, 1fr): the minimum width for a card is 250px and the max is 1fr which is 100% of width.

See the Pen Grid Layout - Cards by Ahmad Shadeed (@shadeed) on CodePen.

In this example, we will change the visual order of the image and center it.

{% highlight html %}

  • About
  • Works
  • Projects
  • Contact

{% endhighlight %}

In order to move the avatar to the center, we need to determine the start and end of the column lines.

{% highlight css %} ul { display: grid; grid-template-columns: repeat(5, 1fr); /_ 1fr 1fr 1fr 1fr 1fr _/ }

li { align-self: center; /_ center the links vertically _/ }

li:first-child { grid-column: 3 / 4; } {% endhighlight %}

See the Pen Grid Layout - Header by Ahmad Shadeed (@shadeed) on CodePen.

Using Grid Today

Once the support is there, we can use it as an enhancement to our layouts. By using @supports in CSS, this will become possible and in case no support, it’s fine, we are using it as an enhancement. ;)

{% highlight css %} @supports (display: grid) { .wrapper { display: grid; grid-template-columns: 1fr 1fr 1fr; }

.featured-item { grid-column: 1 / 3; } } {% endhighlight %}

Accessibility

With grid, we can reorder our layouts in many ways. When those changes have focusable elements like controls and links, it might provide a bad experience for people using the keyboard. When the visual order is different than the source one, it might work for element that the user don’t need to click or interact with. But for interactive elements, please think twice before re-ordering content with grid.

Further reading and resources