当前位置: 首页 > Web前端 > HTML

(翻译)原生CSS网格布局学习笔记

时间:2023-04-03 00:39:50 HTML

注:本文是我翻译的第一篇技术文章。适合有一定CSS原生网格布局使用经验的开发者(阅读前需要先了解原生CSS网格的语法),且原生CSS网格布局(NativeCSSgrid)尚未被任何官方版本使用过浏览器到目前为止。完成。原文地址,译者博客_以下是OliverWilliams的帖子。Oliver学习原生CSS网格已经有相当长的时间了,所以在CSS网格方面可以说是有一定的发言权。在这篇文章中,他将以一种不同寻常的方式剖析自己的CSS网格布局学习之路。我同意他的想法,就是在学习一门新技术的时候,把它们拆分成更小的单元块,加上例子,一步步学习。这比学习所有关于网格布局的知识要好得多。浏览器原生CSSGrid预计在2017年初支持。在此之前,您需要在浏览器中启用此实验性功能(Firefox实验版默认启用)。ChromeCanary是目前最好的实现。同时,Firefox有一个非常好的插件CSSGridInspector,它可以显示网格的线条,它是目前唯一可以在浏览器中运行的工具。在chrome地址栏中输入chrome://flags,找到“ExperimentalWebPlatformFeatures”并启用它。IE和Edge实施当前不支持的较旧的网格标准。网格布局不是将各个部分放在一起。相信我,你很快就会掌握窍门的。网格布局只能与左侧的矩形单元块组合。它不能像右图那样由一堆散乱的多边形(像俄罗斯方块那样的方块)拼凑起来。grid布局并不是为了取代flexbox而设计的,而是flexbox的补充虽然grid布局和flexbox在某些方面有相似的功能,你会发现很多人使用flexbox来实现Grid布局,但这并不是flexbox的设计初衷为了。JakeArchibald的这篇博文值得一读_Don'tuseflexboxforoverallpagelayout。这篇博文大致意思是:Flexbox(弹性盒子)是为一维布局(行或列)而设计的。CSS网格是为二维设计的。RachelAndrews说过类似的话:Flexbox用于一维布局——即行或列。网格用于二维布局——即多行和多列。它们可以很好的结合,你可以把一个grid放在一个flex容器里,也可以给gridblock加一个flex元素看例子。我们希望将一段文本在网格项内垂直居中,但我们希望背景(图像、颜色或渐变)覆盖整个网格区域。我们可以使用align-items属性并将其值设置为居中,但这样背景就不会填满网格元素的整个区域。align-items的默认值是stretch——你不用改变它,它总是会填满整个空间。我们将网格元素设置为align-items:center并将网格项设置为弹性容器。.grid{align-items:stretch;}.griditem{display:flex;align-items:center;}给grid-column-end设置一个负值,没想到小屏有用,写一个12列的grid,所有的grid都跨12列。你可以用网格来做到这一点:/*对于小屏幕*/.span4,.span6,.spanAll{grid-column-end:span12;}/*对于大屏幕*/@media(min-width:650px){.span4{grid-column-end:span4;}.span6{grid-column-end:span6;}}这个显示效果没什么问题,在使用CSSGrid的时候,重新定义列数就很简单了。您可以通过设置grid-column-end:-1;使您的页面始终从左到右运行;/*对于小屏幕*/.span4,.span6,.spanAll{grid-column-end:-1;}在大屏幕上,你希望尽可能接近12列,但在移动设备上,一行大约是1~4列。使用媒体更改网格模板列非常容易。.grid{grid-template-columns:1fr1fr;}@media(min-width:700px){.grid{grid-template-columns:repeat(12,1fr);}}有一些元素,我们希望它贯穿整个视口,例如页眉、页脚和一些大图像。对于小屏幕,我们可以这样写:.wide{grid-column:1/3;/*startat1,endat3*/}不幸的是,当我们换成大屏幕时,每行有12列,这些元素只会占据前两列,而不是12列。我们需要定义一个新的grid-column-end,并将它的值设置为13,这种方法比较麻烦,还有一个简单的方法,grid-column:1/-1;,这样不管是什么屏幕尺寸,他们占据了整排。像这样:.wide,.hero,.header,.footer{grid-column:1/-1;}参见CodePen上CSSGRID(@cssgrid)的PenEasiermediaquerieswith-1。网格列可以命名,并使用一些隐式名称。grid-template-areas和grid-line-numbers是控制行数的两个属性,可以同时使用。您可以使用这些隐式行名称来设置您的网格。.grid{grid-template-areas:"mainmainsidebarsidebar";}这段代码,我们可以得到四个隐式名称,main-start,main-end,sidebar-start,sidebar-end。如果您想在多个网格区域或特定的分段网格区域中重叠内容,这可能非常有用。请参阅CodePen上CSSGRID(@cssgrid)的带有网格区域的Pen隐式线名。定义网格区域的另一种方法类似于命名网格线。可以使用特殊的线名来设置网格区域。语法是这样的:.grid{grid-template-areas:"headerheaderheader""mainmainsidebar""footerfooterfooter";},如果你的布局设计(列布局太多!没有列一定要命名,可能还需要空元素)有很多空的地方,这种写法有点麻烦。所以还有另一种写网格的方法。这样,不管名字是什么,只要合理利用[name-start]和[name-end],也可以达到自己的布局目标。这是一个例子:.grid{display:grid;grid-template-columns:20px100px[main-start]1fr[main-end]100px20px;grid-template-rows:100px[main-start]100px[main-end]100px;}.griditem1{background-color:red;grid-area:main;}SeethePen在CodePen上通过CSSGRID(@cssgrid)定义网格区域的另一种方法。你可能不想对整个页面使用这种方式布局,但如果你想结合grid-area来确定行数,它会很合适。Equalsizedboxlayoutusesvminunits虽然你可以在CSSgrid中使用任意大小的行或列,但如果你想要相等大小的网格和响应式,你需要使用vminunits。.grid{grid-template-columns:repeat(5,20vw);grid-template-rows:repeat(5,20vh);}这种布局在台式机和笔记本上基本可以完美显示,但是在手机上,如果高度大于宽度,内容就会溢出,产生水平滚动条.DudleyStorey写了一篇关于鲜为人知的css单元vmin的实用性的博客。该方法通过调整容器视口的百分比和内容位置来适配各种尺寸的屏幕。.gridcontainer{显示:网格;宽度:100vw;高度:100vh;证明内容:居中;对齐内容:居中;网格模板列:重复(5、20vmin);grid-template-rows:repeat(5,20vmin);}请参阅CodePen上的CSSGRID(@cssgrid)使用CSSGrid和vmin的PenBoxyLayout。绝对定位当我们对一个网格元素进行绝对定位时,元素会跑到它的容器中,我们可以使用grid-column和grid-row来定位它。在正常情况下,绝对定位使元素远离文档流。最适合希望元素重叠而不干扰其他布局元素的使用场景。除非您为每个元素声明grid-column-start和grid-row-start,否则即使使用绝对定位,元素也不会重叠。尝试删除位置:绝对;本例中的div,想想grid-column和grid-row的值,试着修改一下,你就会明白是什么意思了。请参阅CodePen上CSSGRID(@cssgrid)的Penpreservingauto-placementwithposition:absolute。如果你使用过flexbox的order属性,那么你已经对它有所了解。知识。所有网格元素的默认顺序值为0。因此,如果您设置顺序:1;对于一个网格元素,这个元素将在所有元素之后。您可以为order属性设置一个负值,使其排在所有项目的前面。在CodePen.grid中minmax()的坑上看CSSGRID(@cssgrid)的PenOrder值。您是否希望整行随着内容的宽度变宽,直到达到最大宽度?在这种情况下,您可能想尝试使用minmax():.grid{display:grid;网格模板列:重复(3,最小最大值(1fr,300px));不幸的是,像上面这样简单的东西是行不通的。如果max小于min,css将被忽略。fr不能用在minmax()中。其实这个需求很容易实现。在grid-template-columns或grid-template-rows中使用auto,这样item可以随着内容的增加而变大。请参阅CodePen上CSSGRID(@cssgrid)的PenThevalueofautovsfr。我们可以设置一个max-width:.grid{display:grid;grid-template-columns:repeat(3,auto);}.item{max-width:300px;}请参阅CodePen上CSSGRID(@cssgrid)的PenThelimitsofminmax。(译者注:没看懂Medium题目是什么。原文:我在Medium上写了一整篇文章题目是)TheOneThingIHateAboutGrid。如果给每条网格线起个名字,写布局就容易了。有多种方式供你选择。如果只想多写,可以为多行设置多个名称。.grid{grid-template-columns:[col1-start]1fr[col1-endcol2-start]1fr[col2-end];}最简单的命名约定使用网格自动编号。不写[col2],而是写成col2.griditem1{grid-column-start:col2;}和span关键字结合使用,这样我们就不用在column-start和column-end网格线是有编号的,直观很多。.grid{grid-template-columns:repeat(4,[col]100px);}.griditem1{grid-column:col2/span2;}frunit为什么那么重要,让你摆脱麻烦的计算想象一下行对于像grid-template-columns这样的四列布局使用百分比是多么容易:25%25%25%25%。但是当你想使用grid-gap属性时呢?如果设置grid-gap:10px,那么这条线上就会出现三个空隙,每一个10px,整体宽度为100%+30px,大于100%就会出现滚动条。虽然可以通过计算来解决,但是如果使用frgrid-template-columns就太容易了:1fr1fr1fr1fr请参阅CodePen上CSSGRID(@cssgrid)的Penfrunitvspercentage。网格布局中的第二个我讨厌的一点是没有办法强制自动布局算法将某些行和列留空。grid-gap允许我们设置内容之间的距离。grid-row-gap和grid-column-gap可以设置行或列之间的间距,但是如果我想让第一行和第二行之间的距离为10px,第二行和第三行之间的距离为为50px,使用现有的网格是无法实现的,除非创建一个空行。你可能见过这样写的grid-template-area::grid-template-rows:"headerheaderheader""mainmainmain""...“中学中学”“页脚页脚页脚”;应该提供一种更智能的方式让布局算法来做这件事。不幸的是,这样写也行不通。这个语法只是意味着我们不想把第三行变成一个命名的网格区域。但是grid-template-rows仍然会在那里结束。一些设计建议:您不一定需要12列(并且列的大小不需要统一)design的默认配置。Bootstrap引导大家使用12列网格,导致很多框架都是12列网格。12可以被3和4整除,让我们有更多的布局。1行12列,1行6列,1行4列,1行3列,1行2列虽然有些人喜欢总是对每个项目使用相同的网格,但你应该考虑一下你确实需要,有当不需要有更多的栏时,你应该为你的内容构建一个网格布局,而不是到处都是12列的网格。查看此示例Gridset。Gridset是一个非常有用的制作网格的工具,但是原生CSS网格不需要你使用任何工具,但是看看它是否有一些好的网格设计。查看我写的关于CSSNativeGrid是多么免费的示例:请参阅CodePen上的CSSGRID(@cssgrid)使用CSSGrid模块的Pen文本布局。