1 the introduction

Flex is like a functional keyboard and touch screen compared to the Grid. The control of the touch screen is a dimensional-reduction blow compared to the functional keyboard, which can only be controlled up, down, left, and right (x and Y axes), whereas the touch screen breaks the layout barrier and is directly accessible from the z axis, so that no matter how complex the internal layout of the UI is, it can be directly located by touch.

Flex is a one-dimensional layout, and we need to constantly nest divs to form complex structures, and once the layout changes, the code needs to be refacedif the existing nested structure is not “compatible with changes” to the new structure. The Grid, like a touch screen, can be laid out in two dimensions, and even if the layout is drastically changed, it can be adapted with minimal modification.

That’s why this close reading with CSS Grid is rethinking layout, understanding the changes this revolutionary layout technology brings to layout and even code logic organization.

2 an overview

Block Float Flex has three different layout modes:

  • The layout structure is described by a Div hierarchy, which makes the Div hierarchy complex and difficult to maintain when structural changes occur.
  • The customization capability is weak. Flex layouts have some out-of-control intelligence, such as child elements that are 50% wide being squeezed below 50% by their peers. This intelligence is needed in some scenarios, but is not provided as Gridminmax“, so the customization is not enough.

For example, the structure above might look something like this in Flex:

<div class="card">
  <div class="profile-sidebar">
    <img src="https://i.pravatar.cc/125? image=3" alt="" class="profile-img" />
    <ul class="social-list">
      <li>
        <a href="#" class="social-link"
          ><i class="fab fa-dribbble-square"></i
        ></a>
      </li>
      <li>
        <a href="#" class="social-link"
          ><i class="fab fa-facebook-square"></i
        ></a>
      </li>
      <li>
        <a href="#" class="social-link"
          ><i class="fab fa-twitter-square"></i
        ></a>
      </li>
    </ul>
  </div>
  <div class="profile-body">
    <h2 class="profile-name">Ramsey Harper</h2>
    <p class="profile-position">Graphic Designer</p>
    <p class="profile-info">
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Facere a tempore,
      dignissimos odit accusantium repellat quidem, sit molestias dolorum
      placeat quas debitis ipsum esse rerum?
    </p>
  </div>
</div>
Copy the code

Using HTML nesting, we split the graph vertically into two blocks, and then continue to nest the layout within each block, which is the most classic layout behavior.

In the style file, we need to describe the layout of each layer and support multi-resolution elastic layout. Some styles need to be adjusted, including the top card container:

.card {
  width: 80%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  max-width: 600px;
  background: #005e9b;
  flex-basis: 250px;
  color: white;
  padding: 2em;
  text-align: center;
}

.profile-info {
  font-weight: 300;
  opacity: 0.7;
}

.profile-sidebar {
  margin-right: 2em;
  text-align: center;
}

.profile-name {
  letter-spacing: 1px;
  font-size: 2rem;
  margin: 0.75 em 0 0;
  line-height: 1;
}

.profile-name::after {
  content: "";
  display: block;
  width: 2em;
  height: 1px;
  background: #5bcbf0;
  margin: 0.5 em auto 0.65 em;
  opacity: 0.25;
}

.profile-position {
  text-transform: uppercase;
  font-size: 0.875 rem;
  letter-spacing: 3px;
  margin: 0 0 2em;
  line-height: 1;
  color: #5bcbf0;
}

.profile-img {
  max-width: 100%;
  border-radius: 50%;
  border: 2px solid white;
}

.social-list {
  list-style: none;
  justify-content: space-evenly;
  display: flex;
  min-width: 125px;
  max-width: 175px;
  margin: 0 auto;
  padding: 0;
}

.social-link {
  color: #5bcbf0;
  opacity: 0.5;
}

.social-link:hover,
.social-link:focus {
  opacity: 1;
}

.bio {
  padding: 2em;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

@media (min-width: 450px) {
  .bio {
    text-align: left;
    max-width: 350px; }}.bio-title {
  color: #0090d1;
  font-size: 1.25 rem;
  letter-spacing: 1px;
  text-transform: uppercase;
  line-height: 1;
  margin: 0;
}

.bio-body {
  color: # 555;
}

.profile {
  display: flex;
  align-items: flex-start;
}

@media (min-width: 450px) {
  .card {
    flex-direction: row;
    text-align: left;
  }

  .profile-name::after {
    margin-left: 0; }}Copy the code

Let’s see what Grid does! The Grid has a number of apis, and we focus on the grid-template-areas attribute. With this attribute, we can describe the areas in a tiled manner, regardless of the HTML structure of the module:

<div class="card">
  <img src="https://i.pravatar.cc/125? image=3" alt="" class="profile-img" />
  <ul class="social-list">
    <li>
      <a href="#" class="social-link"><i class="fab fa-dribbble-square"></i></a>
    </li>
    <li>
      <a href="#" class="social-link"><i class="fab fa-facebook-square"></i></a>
    </li>
    <li>
      <a href="#" class="social-link"><i class="fab fa-twitter-square"></i></a>
    </li>
  </ul>
  <h2 class="profile-name">Ramsey Harper</h2>
  <p class="profile-position">Graphic Designer</p>
  <p class="profile-info">
    Lorem ipsum dolor sit amet consectetur adipisicing elit. Facere a tempore,
    dignissimos odit accusantium repellat quidem, sit molestias dolorum placeat
    quas debitis ipsum esse rerum?
  </p>
</div>
Copy the code

As you can see, using the Grid allows you to separate the UI structure from the HTML structure, which only describes the inclusion relationship; you only need to describe the specific UI structure in the style file.

The style file only captures the relevant parts of the Grid:

.card {
  width: 80%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  max-width: 600px;
  background: #005e9b;
  flex-basis: 250px;
  color: white;
  padding: 2em;
  text-align: left;

  display: grid;
  grid-template-columns: 1fr 3fr;
  grid-column-gap: 2em;
  grid-template-areas:
    "image name"
    "image position"
    "social description";
}

.profile-name {
  grid-area: name;
}
.profile-position {
  grid-area: position;
}
.profile-info {
  grid-area: description;
}
.profile-img {
  grid-area: image;
}
.social-list {
  grid-area: social;
}
Copy the code

As you can see, grid-template-Areas are further abstracted grammars that describe the page structure in intuitive text, making it easier to understand and modify.

This approach also has advantages for different resolutions, as long as you reorganize grid-template-areas:

@media (min-width: 600px) {
  .card {
    text-align: left;
    grid-template-columns: 1fr 3fr;
    grid-template-areas:
      "image name"
      "image position"
      "social description"; }}Copy the code

In the final analysis, Grid uses two-dimensional structure description to control the layout of child elements from the parent, making layout description more intuitive.

Finally, the authors mention that Flex still has usage scenarios, such as simple one-dimensional structures, or flex-only syntax such as space-between. Therefore, Grid is recommended for overall, complex two-dimensional layouts and Flex for simple one-dimensional layouts.

3 intensive reading

The Grid layout has inspired me a lot. The separation of HTML structure from UI structure helps reduce DIV hierarchy and make code look cleaner.

Some might wonder if Grid simply moves some of the HTML layout functionality to CSS, and the overall complexity should remain the same. In fact, as you can see from the Grid-template-Areas API, grid not only abstracts layout functionality into CSS, but also abstracts layout descriptions, making code more maintainable.

Abstract and abstract again

Why can the Grid abstract layouts? Because the Grid has the two-dimensional structure in its hands, it has greater layout capabilities that further abstracts structured syntax into string descriptions.

The benefits of abstraction are self-evident. Which do you think is more readable, a bunch of nested divs or the following code?

.card {
  grid-template-areas:
    "image name"
    "image position"
    "social description";
}
Copy the code

That’s the benefit of abstraction. In general, the more abstract your code is, the easier it is to read and maintain.

Let’s look at the Chrome Grid plugin, which visualizes the Grid and allows you to tweak it as a UI:

UI is a re-abstraction of text, while avoiding impossible syntax such as:

.card {
  grid-template-areas:
    "image name"
    "image position"
    "social image";
}
Copy the code

Layouts can only be extended as convex polygons, they cannot be separated, nor can they be suddenly inserted into other modules to become concave polygons. Therefore, the UI can avoid this error and simplify the UI into vertical and horizontal lines, which is obviously more efficient.

I have to say that the exploration of the Grid and graphical plug-ins is a major advance in the field of layout, and a continuous attempt at abstraction with only one problem: how to provide a more intuitive way to describe the UI.

The impact of layout on modularity

Grid will improve the layout of a dimension, will directly affect the JS modular way.

Especially in the case of JSX code, where a module equals UI + JS, nested layouts tend to divide modules from a UI perspective.

For example, with Flex layout, we might first create module X as the left container with child elements A and B, module Y as the right container with child elements C and A new container Z with child elements D and E.

If your first impression is that your code is organized this way, you have to admit that modularity is affected by how you lay it out. Although this division is correct in many cases, when the five modules are not related to each other, the containers X, Y, and Z we created lose their reuse and have to be recombined again in new composition scenarios.

In Grid syntax, however, we don’t need X, Y, and Z. Just use the CSS Grid Generator to create the following layout code by dragging and dropping:

.parent {
  display: grid;
  grid-template-columns: 3fr repeat(2.1fr);
  grid-template-rows: repeat(5.1fr);
  grid-column-gap: 0px;
  grid-row-gap: 0px;
}

.div1 {
  grid-area: 1 / 1 / 3 / 2;
}
.div2 {
  grid-area: 3 / 1 / 6 / 2;
}
.div3 {
  grid-area: 1 / 2 / 2 / 4;
}
.div4 {
  grid-area: 2 / 2 / 6 / 3;
}
.div5 {
  grid-area: 2 / 3 / 6 / 4;
}
Copy the code

Grid-template-columns grid-template-rows are more powerful than grid-template-areas, but the code is not as intuitive as grid-template-areas. But it’s pretty intuitive with some visual systems:

By taking out the layout of the five modules A ~ E, the relationship between them is even and we can see how to do modularity from A completely logical perspective.

4 summarizes

CSS Grid is essentially a two-dimensional layout syntax. Compared with one-dimensional layout schemes such as Block and Flex, one more dimension can be used to define the layout from the perspective of rows and columns at the same time. Therefore, grid-template-areas syntax can be derived, which is more cohesive, intuitive and abstract.

It’s always been a dream of the front end to separate the layout from the Dom. When developing the UI section, you only need to care about which modules the page is made of and implement them, not how the modules should be combined. When describing the composition, you can describe the structure of the layout through visual or abstract strings, and corresponding to the written module, which is much more maintainable than DIV structure description scheme.

Close reading: Rethinking layout with CSS Grid · Issue #211 · DT-fe /weekly

If you’d like to participate in the discussion, pleaseClick here to, with a new theme every week, released on weekends or Mondays. Front end Intensive Reading – Helps you filter the right content.

Pay attention to the front end of intensive reading wechat public account

Copyright Notice: Freely reproduced – Non-commercial – Non-derivative – Remain signed (Creative Commons 3.0 License)