css grid
Anyone who has even dabbled a little in creating websites knows that <div>
s are an essential building block for controlling our layouts.
甚至涉足创建网站的任何人都知道<div>
是控制我们的布局的重要组成部分。
HTML5 introduced new semantic elements to help, and while they are a fantastic addition to the language, they’re a little bit like the garnish on our <div>
soup.
HTML5引入了新的语义元素来提供帮助,尽管它们是该语言的绝妙补充,但它们有点像<div>
汤中的装饰。
With grid, we no longer have to rely on <div>
s to create the structure of our page, or even a more complex component. The structure is literally defined by the parent and not how the content is organized within in.
使用grid,我们不再需要依靠<div>
来创建页面的结构,甚至是更复杂的组件。 该结构实际上是由父级定义的,而不是内部内容的组织方式。
This means we can have nice, simple markup that sticks to the content itself without a reliance on organizing it through the use of <div>
s.
这意味着我们可以拥有一个漂亮,简单的标记,该标记可以粘贴在内容本身上,而无需依赖通过使用<div>
进行组织。
I’ve heard a lot of people complain that grid is too complicated and that flexbox gets the job done. I’d argue that they are comfortable with flexbox and don’t want to bother learning grid because of that.
我听说很多人抱怨网格太复杂了,而flexbox可以完成工作。 我认为他们对flexbox很满意,因此不想打扰学习网格 。
At the end of the day, Grid does introduce a boatload of new properties and values, so yes, there is a learning curve. But flexbox is plenty complicated as well.
归根结底,Grid确实引入了许多新的属性和值,所以是的,这是一条学习曲线。 但是flexbox也非常复杂。
Can you tell me the benefits of flex-basis over setting a width? Or really, how flexbox calculates the widths of flex items if we haven’t explicitly set them?
您能告诉我flex-basis设置宽度的好处吗? 还是真的,如果我们没有明确设置flexbox的宽度,flexbox如何计算它们的宽度?
For example, if you showed the below example to someone who had never used flexbox, how do you explain the fact that it’s the same markup and the same CSS for both sets of columns? To make it even worse the second column in both has a width: 50%. Clearly that width of 50% isn’t really setting it to 50%.
例如,如果您向从未使用过flexbox的人展示了以下示例,那么您如何解释两组列都具有相同的标记和相同CSS的事实? 更糟糕的是,两者的第二列都具有50%的宽度。 显然,宽度为50%并没有真正将其设置为50%。
“Well, it starts off with flex items shrinking if there isn’t enough room, so even though we set the width to 50%, it doesn’t have the space, so it shrinks down to squeeze in because the other div requires more space. The 50% is more of its ideal size than what it will actually be.
“好吧,如果没有足够的空间,它会从弹性项目开始收缩,所以即使我们将宽度设置为50%,它也没有空间,所以它会收缩以压缩,因为另一个div需要更多空间空间。 50%比理想尺寸大得多。
“So in the top example, the first div’s content being so long is causing a problem because, as a flex item, by default, it wants to shrink to fit its content. In this case that item has a lot of content so…”
“因此,在最上面的示例中,第一个div的内容太长会引起问题,因为默认情况下,作为flex项,它希望收缩以适合其内容。 在这种情况下,该项目具有很多内容,所以……”
So yes, flexbox is awesome and does a great job at creating layouts, but please don’t tell me that it’s simple. As soon as you get out of perfect examples, it’s often far from intuitive and sometimes it can be downright strange.
所以是的,flexbox非常棒,并且在创建布局方面做得很好,但是请不要告诉我它很简单 。 一旦您找到了完美的例子,它通常就远非直觉,有时可能是彻头彻尾的奇怪。
Grid is complicated in that there are a lot of new properties and values, but they gives us a lot more control than flexbox does.
网格很复杂,因为有许多新的属性和值,但它们比flexbox赋予我们更多的控制权。
In this article I’d like to look at how that extra layer of control helps simplify our markup and let us write less code, and that’s without even learning how to use a bunch of its fancy features.
在本文中,我想研究一下额外的控制层如何帮助简化我们的标记并使我们编写更少的代码,而这甚至没有学习如何使用它的许多精美功能。
Even if we take a simple component and build it with flexbox, because it only acts in 1-dimension at a time (the flex items are either rows or columns, they cannot be both), we’re left with a lot of divs to break things up into rows, which can then be split into columns.
即使我们采用一个简单的组件并使用flexbox进行构建,因为它一次只能以一维的方式起作用(flex项既可以是行也可以是列,但不能同时是两者),我们还有很多div可以将事情分解成几行,然后再分解成几列。
For example, if we’re working on a card that looks like this:
例如,如果我们正在处理如下所示的卡:
It’s not a complicated layout but we still need to organize our content in a pretty specific way to get it to work.
这不是一个复杂的布局,但是我们仍然需要以一种非常特定的方式来组织我们的内容以使其正常工作。
The yellow and orange boxes there are needed, so that when we place a display: flex; on the .card itself (the red box), it will create two columns. So to structure everything, we get markup that looks something like this:
这里需要黄色和橙色框,以便在我们放置显示时:flex; 在.card本身(红色框)上,它将创建两列。 因此,要构建所有内容,我们将获得如下所示的标记:
<div class="card">
<div class="profile-sidebar">
<!-- profile image and social list here -->
</div>
<div class="profile-body">
<!-- name, position, description here -->
</div>
</div>
It’s not overly complicated by any means, and once you understand how flexbox works, it relatively straight forward.
无论如何,它并不过分复杂,一旦您了解了flexbox的工作原理,它就相对简单了。
When we put a display: flex
on the .card
, we'll get our two columns, and then we need to go into those and start styling them up.
当在.card
上放置display: flex
时,我们将得到两列,然后我们需要进入其中并开始对其进行样式设置。
Here is a working example with all the styling on it:
这是一个具有所有样式的工作示例:
The thing is, by having to create columns of content, we’re getting a little more complicated in the markup, and we’re also limiting ourselves as we’ve forced different pieces of content to be grouped together.
问题是, 由于必须创建内容列,因此标记变得有些复杂,并且由于将不同的内容片段组合在一起,我们也受到限制 。
Because grid is 2-dimensional, meaning that it allows us to create rows and columns at the same time, that means that our grid container (where we declare display: grid) has full control over the layout inside of it.
因为grid是二维的,这意味着它允许我们同时创建行和列,这意味着我们的网格容器(我们在其中声明display:grid)可以完全控制其内部布局。
We used to require <div>s to do that, like in the above example with flexbox. With grid, we can remove the <div> s completely.
过去,我们需要 <div>来执行此操作,就像在上例中使用flexbox一样。 使用grid,我们可以完全删除<div>。
<div class="card"> <img src="https://i.pravatar.cc/125?image=3" alt="" class="profile-img">
<ul class="social-list"> ... </ul>
<h2 class="profile-name">Ramsey Harper</h2>
<p class="profile-position">Graphic Designer</p>
<p class="profile-info">Lorem ipsum ...</p>
</div>
From a markup point-of-view, doesn’t this make a lot more sense?
从标记的角度来看,这是否更有意义?
We have a .card
and then we place the content of that component in there. We don’t need to worry about breaking down how it will be structured, we just place the content that we need and move on from there.
我们有一个.card
,然后将那个组件的内容放在那里。 我们不必担心会分解其结构,只需要放置所需的内容并从那里继续前进即可。
Just like when we used flexbox for this, we still need to break the layout down, though because of how grid works, it looks a little different.
就像当我们使用flexbox一样,我们仍然需要分解布局,尽管由于网格的工作原理,它看起来有些不同。
This is one place where people might argue grid is more complicated, but really I'm just drawing boxes around each peices of content, and then extending those lines.
这是人们可能会争论网格更复杂的地方,但实际上我只是在围绕每个内容的顶点绘制框,然后延伸这些线。
With flexbox, we created two divs that would act as our columns. When using grid, we instead set up the entire grid on the parent itself, and then we can tell the children where they belong on that grid.
使用flexbox,我们创建了两个div作为列。 使用网格时,我们改为在父级自身上设置整个网格,然后我们可以告诉孩子它们在该网格上的位置。
To set up the grid, we can do something like this:
要设置网格,我们可以执行以下操作:
.card {
display: grid;
grid-template-columns: 1fr 3fr;
}
The fr
unit is unique to grid, and is a fraction of the available space. Using it like this is very much like setting the two columns up in flexbox and giving them widths of 25%
and 75%
respectively.
fr
单位是网格所独有的,并且仅占可用空间的一小部分。 像这样使用它非常像在flexbox中设置两列并分别为其设置25%
和75%
宽度。
Maybe it’s because I used floats to create layouts for years, but it always feels like a little bit of magic when the different elements just end up where we want them to be!
也许是因为我使用浮动工具创建布局多年了,但是当不同的元素最终出现在我们想要的位置时,总感觉有些神奇!
We could use grid-row
and grid-column
on each element to place it where we want, but the more and more I use grid, the more I fall in love with taking the time to set up grid-template-areas
and place my items into those areas.
我们可以在每个元素上使用grid-row
和grid-column
将其放置在我们想要的位置,但是我使用网格的次数越多,我对花时间设置grid-template-areas
并将其放置在位置上的喜爱就越大。物品进入那些区域。
The setup is a little bit longer, but the payoff really hits home when we make things responsive (we’ll get there soon).
设置需要更长的时间,但是当我们使事情变得敏感时,回报就真正到了(我们很快就会到达那里)。
So first, on the .card
we need to setup the grid-template-areas
and then we can assign all the children onto those areas:
因此,首先,在.card
上,我们需要设置grid-template-areas
,然后将所有子代分配到这些区域:
.card {
...
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; }
Check it out here if you’d like to see it all in action:
如果要查看所有操作,请在此处查看:
One of the things I love about using grid-template-areas
are that it’s so easy for someone else to look at this code and immediately understand what is going on.
其中一个我喜欢使用的东西grid-template-areas
是,它是如此容易被别人看这个代码,并立即明白什么是要去。
If someone shows you something that’s been setup using grid-row
and grid-column
using the numbers and spans, it’s easy enough to count things and figure out where they’ll end up. For simple layouts or for a quick span 3 here and there I think it’s fine to use them, but it’s so nice to look at only the CSS of a parent element and immediately understand what that entire layout is going to look like.
如果有人使用数字和跨度向您显示使用grid-row
和grid-column
设置的内容,则很容易计算事物并弄清楚它们将在哪里结束。 对于简单的布局或此处的快速跨度3,我认为可以使用它们, 但是仅查看父元素CSS并立即了解整个布局将是什么样子真是太好了 。
In that very first example where we set the width of one of the flex items to 50%, it wasn’t really 50%. If you understand why that is, that’s great, but it can still be annoying at times. It’s easy enough to get around, but when using grid, it’s much less of an issue.
在第一个示例中,我们将其中一个伸缩项的宽度设置为50%,实际上并不是50%。 如果您知道为什么会这样,那太好了,但是有时还是会很烦人。 它很容易解决,但是使用网格时,问题就少得多了。
Because we are defining the complete layout, we’re also defining exactly how much space we want items to take up.
因为我们要定义完整的布局,所以我们还要确切地定义我们希望项目占用多少空间。
And sure, we get minmax()
and fr
which muddy the water a little as they allow for more flexible sizing (like we are using in our above example), but even then, we still have full control over that flexibity, and it’s all being controlled by the parent rather than having to set some things on the parent and others on the children.
并且可以肯定的是,我们得到了minmax()
和fr
,它们使水有些混浊,因为它们允许更灵活地调整大小(就像我们在上面的示例中使用的一样),但是即使那样,我们仍然可以完全控制该灵活性,这就是全部由父母控制,而不必在父母身上设置某些东西,而在孩子身上设置其他东西。
Looking at our above example, we can’t change that layout to look like this without changing the markup:
在上面的示例中,如果不更改标记就无法将布局更改为如下所示:
We’ve constrained ourselves because of how we had to group things together in <div>
s. We had to use those <div>
s in order to get the layout to work, but we’re stuck now.
我们之所以受到束缚,是因为我们不得不在<div>
中将事物分组在一起。 为了使布局正常工作,我们不得不使用这些<div>
,但是现在我们陷入了困境。
With the flat markup of our grid, anything is possible! And as an added bonus, because we set everything up using grid-template-areas, making these changes is super easy!
使用我们网格的平坦标记,一切皆有可能 ! 另外,由于我们使用网格模板区域设置了所有内容,因此进行这些更改非常容易!
.card {
/* old layout
grid-template-areas:
"image name"
"image position"
"social description"; */
/* updated layout */
grid-template-areas:
"image name"
"image position"
"image social"
". description";
}
By playing with the grid-template-areas
like this, it shifts the social icons to where we want them to be so quickly and easily (the .
in the last part indicates and empty cell).
通过与玩grid-template-areas
尚且如此,它改变了社会图标的地方,我们希望他们能够如此快速,轻松地(的.
在最后部分表示和空单元格)。
As I mentioned a few times now, one of the places where this pays off. We can completely control our layout with with our parent:
正如我现在几次提到的,这是值得回报的地方之一。 我们可以和父母一起完全控制布局:
.card {
/* setup for small screens */
display: grid;
grid-template-columns: 1fr;
grid-column-gap: 2em;
grid-template-areas:
"name"
"image"
"social"
"position"
"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; }
/* rearanging the layout for large screens */
@media (min-width: 600px) {
.card {
text-align: left;
grid-template-columns: 1fr 3fr;
grid-template-areas:
"image name"
"image position"
"social description";
}
.profile-name::after {
margin-left: 0;
}
}
The below pen has the entire thing styled up. Dive in there, play with the grid-areas, and see how easy it is to completely change the layout!
下面的笔具有完整的样式。 潜入那里,玩网格区域,看看完全改变布局有多容易!
I do find myself turning to grid more and more, but I do think that flexbox still has its place. If I have a logo and navigation next to one another, it’s nice to simply do something like this and know that they are where I want them to be:.header { display: flex; justify-content: space-between;}
我确实发现自己越来越多地使用网格,但是我确实认为flexbox仍然占有一席之地。 如果我的徽标和导航彼此相邻,那么只需做这样的事情,并知道它们就是我想要的位置就.header { display: flex; justify-content: space-between;}
.header { display: flex; justify-content: space-between;}
The same for the <ul>
we use for a navigation to simply get the items next to one another, or as you might have noticed in the card example we were looking at, it’s perfect for the .social-list
.
导航时使用的<ul>
相同,只是将项目彼此相邻,或者就像您在我们看过的卡片示例中可能注意到的那样,它非常适合.social-list
。
For simple components where we don’t need a more complex layout, it works really well. But I find myself moving more and more toward grid, sometimes because of really needing it, other times because I want to use minmax()
or use fr
units.
对于不需要我们更复杂布局的简单组件,它确实很好用。 但是我发现自己越来越趋向于网格,有时是因为确实需要网格,有时是因为我想使用minmax()
或使用fr
单位。
But at the end of the day, I think the best thing about the grid is how we can simplify our markup so much.
但归根结底,我认为关于网格的最好的事情就是我们如何尽可能简化标记。
We still need to use the humble <div>
, but thanks to grid, we don’t have to rely on filling up our markup with them anymore.
我们仍然需要使用不起眼的<div>
,但是由于有了grid,我们不再需要依靠它们来填充标记了。
As great as flexbox is, it’s not simpler than grid. It does certain things really well, but grid allows us, when working on more complex layouts, to have much more control. That control is amplified when dealing with responsive design when making changes in media queries.
就像flexbox一样,它并不比grid更简单。 它确实可以很好地完成某些事情,但是当使用更复杂的布局时,网格使我们可以拥有更多的控制权。 在媒体查询中进行更改时,在处理响应式设计时会放大该控件。
With flexbox, our one big change is changing the flex-direction. With grid, we can completely redesign a component quickly and easily.
使用flexbox,我们的一大变化就是改变了flex-direction。 使用网格,我们可以快速,轻松地完全重新设计组件。
There is a lot more to both flexbox and grid. Each one has its purpose, but if you feel like you’re not sure which one to pick, or if you’re struggling to figure out responsive design in general, I’ve recently released a course that dives into responsive design over on Scrimba called The Responsive Web Design Bootcamp.
flexbox和grid还有很多其他功能。 每个人都有其目的,但是如果您不确定自己该选择哪个,或者如果您总体上想弄清楚响应式设计,我最近发布了一门课程,将在Scrimba上深入探讨响应式设计。称为响应式Web设计训练营 。
It includes a deep dive into both Grid and Flexbox, as well as a full module devoted to how to start thinking responsively as well. In all, it has over 170 lessons, with 15+ hours of content, organized across 6 modules. So if you’d like to keep diving into the responsive world of CSS, you can check it out here.
它包括对Grid和Flexbox的深入研究,以及致力于如何开始响应式思考的完整模块。 总共有170多个课程,其中15个小时以上的内容,由6个模块组成。 因此,如果您想继续深入研究CSS的响应世界,可以在此处查看 。
翻译自: https://www.freecodecamp.org/news/css-grid-changes-how-we-can-think-about-structuring-our-content/
css grid