赞
踩
CSS中gap并不是新的属性,在CSS3新特性中多列布局为其添加了一个新能力。间隙属性除了运用在CSS栅格之外,CSS3新特性中弹性布局同样可以使用。由于CSS属性较多,且实际运用比我们看起来更复杂,这让我想同大家分享一下今天的主题---运用间隙。
我们先回顾一下与.css相关的所有CSS属性gap。一共有六个,分别为:
相关grid属性包括:
上面属性中,我们已经可以忽略前三个属性。这些grid-*属性是在起草CSS Grid规范时早期添加的,后来在gap变得更加普遍时被弃用。浏览器目前仍然支持这些已弃用的grid-*属性,并且将它们前缀视为不存在。因此,grid-gap与gap相同。我们只需要知道row-gap和column-gap是做什么的。
注意:CSS栅格布局起初是用grid-gap属性来定义的,目前逐渐被gap替代。
gap接受一或两个值:
gap接受以下值:
当间隙维度中容器的大小确定时,gap根据任何布局类型中容器内容框的大小解析百分比。
换句话说,当浏览器知道容器的大小时,它可以计算gap。例如,当容器的高度为100px,把gap设置为10%时,浏览器知道间隙为10px。
但是,当浏览器不知道容器大小时,它会想知道,10%是什么?在这种情况下,gap行为会因布局类型而异。
在栅格布局中,布局框解析元素内容时,百分比内在大小解析为零,这就意味着它的空间存在于项目之间,但空间不会影响容器的大小。Demo
在flex布局中,百分比在所有情况下都解析为零,这意味着当浏览器不知道容器的大小时,间隙将不适用。Demo2
以前的CSS规范,都是整在一起的。按照版本发展,也就是说,CSS想要发布新版必须所有属性全部通过。这样带来的问题是,CSS规范非常难产,只要有一个属性争议,就无法达成一致,那么这个版本的CSS规范就无法发布。这也是为什么CSS2 --- CSS3中间经历了差不多有十年的时间。
于是后来,CSS3规范之后,就开始做了调整,新的CSS特性再也不按照一个大的版本进行迭代,而是按照一个一个具体的模块进行制定。
于是大家可以发现,在很短的时间内,各种各样的CSS新特性都出现了。浏览器支持这些特性,不需要等待一个完整的发版过程,只需要浏览器厂商觉得这个模块里这个东西很合适,那就去支持它,哪怕它现在还不稳定,还在实验阶段。典型的案例就是:env()环境变量,以及黑暗模式的媒体特性支持@media (prefers-color-scheme: dark)。
这样一个CSS规范策略确实繁荣了CSS,但是也带了模块化缺陷。就是由于各个模块独立发展,导致原本很多类似的属性并没有大统一,带来了无谓的学习成本。典型的例子就是对齐属性:
Flex布局中的对齐和Grid对齐明明属性和作用是一样的,但是属性值却不一样。比如,Flex布局中justify-content属性支持的是flex-start和flex-end(交叉轴上对齐属性),不支持start和end;Grid布局中justify-content属性支持start和end,同时也支持flex-start和flex-end。就是因为Flex布局模块和Grid布局模块是两个独立的CSS模块。
其实一开始的时候是没有gap属性的。最开始出现的类似的属性是在栅格布局中,那个时候叫做grid-gap,是CSS grid-row-gap和grid-column-gap属性的缩写。CSS中column-gap属性是第一个间隙属性,在Grid布局那边,由于一开始过分看重独立性,模块化。于是,出现了grid-column-gap属性。没过多久,意识到grid-column-gap和column-gap对于开发者的学习而言不友好。
很快,grid-gap属性从Grid规范中去除了。虽然Grid布局依旧支持grid-gap属性,gap、row-gap和column-gap这才是新的标准。
同时,Multi-column、Flex布局中各个间隙也可以使用gap属性。
栅格布局中常常使用间隙,在Flexbox以及多列布局中同样可以使用。让我们来分别看看下面案例。
所有浏览器都支持栅格布局中的间隙。
我们来创建一个包含三列两行的栅格:
.container {
display: grid;
grid-template-columns: 200px 100px 300px;
grid-template-rows: 100px 100px;
}
打开调试器可以看到的线条为栅格线,它们分隔栅格的轨道(行和列)。这些线实际上并不存在于栅格中,不可见的,没有粗细。
我们继续向栅格添加间隙,这些栅格线开始像获得厚度一样。
gap: 20px;
设置栅格线尺寸后,栅格尺寸也随之扩大。
我们再看看Flexbox布局中的差异,相对栅格布局相对会复杂一些。
.container {
display: flex;
column-gap: 10px;
}
再让flex-direction切换column,从上到下垂直堆叠。
flex-direction: column;
这时候间隙消失了,当容器在row方向时,即使存在column-gap,它也不在column方向上渲染。这时我们用row-gap试试,也可以直接使用gap。
gap: 10px;
可以得知,colum-gap总是垂直工作的,row-gap总是水平工作的,不依赖于容器flex方向。
直接改变块的宽度,并不能自动换行,我们设置flex-wrap属性可以规定Flexbox是单行还是多行,同时横轴的方向决定了新行堆叠的方向。
flex-wrap: wrap;
注意:如果元素不是Flexbox对象的元素,则flex-warp属性不起作用。
Flexbox和栅格布局之间有一个小区别,就是列间隙不一定跨柔性线对齐。我们用水平居中,将容器居中放置在它们的弹性线中。这样,我们可以看到每条弹性线都是一个单独的布局,其中间隙是独立于其他线应用。
justify-content: center;
多列是一种布局,可以很容易地在多列之间自动流动内容,就像传统报纸文章中那样。
多列布局中的间隙与栅格或Flexbox的工作方式不同。存在下面三个显著差异:
让我们分别说说。首先,row-gap没有影响。在多列布局中,没有任何要分隔的行,意味着只与column-gap相关。
其次,与grid和Flexbox不同的是column-gap,在1em多列布局中具有默认值(而不是0)。因此,即使根本没有指定间隙,内容列仍然在视觉上分开。默认间隙是可以被覆盖的,这个默认设置还是很不错的。
.container {
column-count: 3;
column-gap: 12px;
column-rule: 4px dotted red;
padding: 12px;
}
其中,column-rule属性指定列之间的规则,包括:宽度、样式、颜色。
上面dotted是来源于border-style边框样式属性,作用为定义点状边框。
gap得到了全面的支持,我们看下caniuse。"gap" | Can I use... Support tables for HTML5, CSS3, etc
总结一下:
总体而言,gap属性得到了很好的支持,并且在大多数情况下,不需要考虑兼容性解决办法。
实现gap样式设计是非常有用的。大体设计思路是:给栅格容器一个背景颜色,然后给项目一个不同的颜色,最后设置间隙来显示容器的颜色。
间隙在容器级别定义的,这意味着我们为整个布局定义一次它们,能够在容器中一致地应用。使用边距需要对每个项目进行声明。当项目性质不同或来自不同的可重用组件时,这会变得复杂。
最重要的是,默认情况下,gap只需要一行代码就可以做正确的事情。例如:我们在弹性布局中对项目之间而不是周围引入一些空间。边距则不同了,如下。
margin: 0 20px;
gap: 40px;
margin: 20px;
gap: 40px;
间隙与边距并没有排他性,可以很好地协同工作,可以将一个项目的布局分散得很远。gap属性只是布局容器中框之间创建的空白空间的一部分。margin,padding,和alignment all可能会增加gap已定义内容之上的空白空间。
让我们考虑一个例子,我们构建一个简单的flex布局,具有给定的宽度、一些间隙、一些内容分布(使用justify-content)以及一些边距和填充。
.container {
display: flex;
gap: 40px;
width: 900px;
justify-content: space-around;
}
.item {
padding: 20px;
margin: 0 20px;
}
上图可见,两个连续的弹性项目之间有四种不同类型的空白空间:
对于间隙,我们有两个比较常见的调试方法。
除非我们拼写错误gap或者提供了无效值,否则该属性将始终应用于页面。
.xxx {
display: block;
gap: 3em;
}
它不会做任何事情,但它是有效的CSS,浏览器不介意gap不适用于块布局。然而,Firefox有一个名为Inactive CSS的功能,它可以做到检查有效CSS。
在浏览器的调试工具中操作。
CSS3的一个强大功能:Grid。以往CSS框架中的grid布局一般是通过float和百分比宽度实现的,这种实现有几种缺点:
当然grid也可以利用flex实现,但是并不会比用float简单多少,而且flex擅长的是一维空间布局,而对grid这种二维空间并不擅长。
Grid作为一个二维的栅格系统,由若干列(column)和行(row)构成。实际运用例如:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。