这篇文章发布于 2019年12月7日,星期六,23:41,归类于 CSS相关。 阅读 32520 次, 今日 6 次 6 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9116
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。
一、前言以及兼容性
前文讲了CSS minmax()函数,现在趁热打铁,介绍下CSS repeat()
函数。
repeat()
函数要想理解透彻,熟练掌握,要比minmax()
函数时间多多了。
该如何讲才能让大家更容易理解呢?琢磨了下,可以从实例入手,一步一步。
在展开一个一个实例之前,我们先看下这个函数的兼容性。
兼容性
CSS repeat()函数兼容性如下图:
Edge 16+支持,然后Firefox浏览器那里有个上标③表示Firefox浏览器暂时只支持列属性的repeat()
函数。主要你的项目不是需要兼容非常老的手机,移动端是可以放心使用的。
二、通过实例介绍CSS repeat()函数
CSS repeat()
函数只能作用在grid-template-columns
和grid-template-rows
这两个CSS属性上,由于目前Firefox浏览器只支持在grid-template-columns
属性上使用repeat()
函数,所以本文接下来所有案例都只显示列,也就是宽度的设置。
1. repeat()函数作用
先看下面代码:
.container { grid-template-columns: 40px auto 60px; }
表示我们的布局分为三列,每列的宽度分别是40px
,auto
,以及60px
。
没有任何问题,再看下面代码:
.container { grid-template-columns: 40px auto 60px 40px auto 60px; }
表示我们的布局分为六列,每列的宽度分别是40px
,auto
,60px
,40px
,auto
,60px
。
好像也没什么问题。
现在,假设我们的布局是12列的,请问,CSS代码会是怎样的?
如果按照上面写法,是不是应该写成下面这样?
.container { grid-template-columns: 40px auto 60px 40px auto 60px 40px auto 60px 40px auto 60px; }
哇,就像老太太裹脚布——又臭又长。
代码量多,看得眼花,还不好理解,维护起来也不方便。
此时,repeat()
的价值就体现了,什么,12列?小菜一碟。请看表演:
.container { grid-template-columns: repeat(4, 40px auto 60px); }
非常好理解,重复4次,每次的重复单元是40px auto 60px
这3个尺寸。
于是就有如下GIF所示的效果(点击播放,112K),是我张鑫旭最爱的深天蓝色哦:
您可以狠狠地点击这里:CSS repeat()函数基本使用demo
2. repeat()函数可以同时多个
例如,前面3列宽度都是40px
,紧跟着3列宽度是60px
,剩下1列宽度auto
,则可以这么设置:
.container { grid-template-columns: repeat(3, 40px) repeat(3, 60px) auto; }
配上我最爱的深天空蓝,效果如下GIF截屏所示:
您可以狠狠地点击这里:多个repeat()函数同时使用demo
3. repeat()函数支持对网格线命名
如果网格线的命名也是重复有规律的,则也可以用在repeat()
函数中,
例如:
.container { grid-template-columns: repeat(3, [col-start] 1fr [col-end]) auto; }
其中,[col-start]
和[col-end]
只是一个自定义的命名,没有什么特殊的含义,关键是[]
,至于里面写的内容,其实只要大家看得懂就行,这里,直接repeat(3, [列开始] 1fr [列结束])
也是一样的效果。
网格线命名主要给Grid布局中的子项使用的,具体可以参见“写给自己看的display: grid布局教程”一文。
三、其他关键字和函数
上面的案例中,repeat()
函数只演示了数值类型和auto
关键字的效果。
实际上,CSS repeat()
函数还支持其他多个关键字和函数。
1. min-content/max-content
min-content
和max-content
尺寸是根据内容来的,min-content
是最小内容尺寸,中文的最小内容单位是一个汉字,英文的最小内容单位是单词,因此min-content
最终宽度是所有这些最小内容单元最长的那个单元宽度;max-content
是最大内容宽度,可以理解为文本内容不换行时候的宽度。详细知识可以参考这篇文章。
这里,我们通过一个案例看看min-content
/max-content
在Grid布局中的效果,CSS代码如下:
.container { grid-template-columns: repeat(2, min-content auto max-content) auto; }
如下GIF录屏图片所示:
min-content
所在列的宽度就是单词content
的宽度;max-content
所在列的宽度就是整个语句不换行时候的宽度。
min-content
和max-content
在实际开发的时候是不会相对于字符进行尺寸设定的,而是相对于图片或者内联性质的容器元素,比方说容器宽度不确定同时一行最多显示一个容器(min-content
),或者所有元素在一行显示(max-content
)。
您可以狠狠地点击这里:repeat(min-content, max-content)示意demo
2. minmax()函数
minmax(min, max)
函数表示当前这个格子的尺寸范围在min
到max
之间。
例如:
.container { grid-template-columns: repeat(2, minmax(min-content, max-content) 40px) auto; }
效果如下GIF,112K,点击播放:
第1列和第3列的宽度最小是min-content
对应的宽度,最大是max-content
对应的宽度。
您可以狠狠地点击这里:CSS repeat()函数中使用minmax() demo
关于minmax()
函数更多知识与细节,请参考上一篇文章“CSS minmax()函数简介”。
2. fit-content()函数
fit-content()
函数是干什么用的呢?
一言以蔽之,尺寸适应于内容,但不超过设定的尺寸。
底层计算公式如下,源自规范文档(MDN上显示的的是错误的):
min(minimum, max(limit, max-content))
minimum
并不具体指代某一个对应的参数类型,不等于min-content
也不等于auto
。究竟是什么意思呢?经过我的研究,啥都不是!或者说,无论是W3C官方的公式还是MDN上的公式都是会有理解障碍的。
更新于2020-05-21
minimum
指的是尺寸下限,通常由最小内容尺寸决定,如果min-width
/min-height
尺寸比最小内容尺寸大,则尺寸下限由min-width
/min-height
决定。
底层计算公式是:
max(minimum, min(limit, max-content))
———- 更新 end ——–
大家请使用下面的公式进行计算吧:
fit-content(limit) = min(min(auto, limit), min(auto, max-content))
其中:
max-content
就是指max-content
对应的尺寸,而auto
就是指auto
关键字对应的尺寸。min()
就是JS中Math.min()
的意思,取小值。
只看公式会有点懵,不急,实例说话:
.container { grid-template-columns: repeat(2, fit-content(100px) 40px) auto; }
效果如下,依然是我最爱的深天蓝色:
其中,第1列和第3列应用了fit-content(100px)
。
含义分别如下:
- 第1列
3个中文,min-content
宽度为1em,14px;max-content
宽度为3em,42px。初始状态下,
auto
关键字应该显示的宽度远大于max-content
,那么auto
就用666px
代替吧。套用公式就是:fit-content(100px) = min(min(666, 100), min(666, 42)) = 42px // 最大max-content尺寸
随着容器宽度变小,
auto
关键字对应的宽度也越来越小,可以一直小到min-content
宽度,也就是14px,此时调用公式就是:fit-content(100px) = min(min(14, 100), min(14, 42)) = 14px // 小到min-content尺寸
- 第3列
这一列的中文字符特别的多,max-content
远远大于100px
,我们不妨用一个666px
代替。初始状态下,
auto
关键字对应的宽度是大于100px的,不妨用233px
代替,因此,此时fit-content(100px)
的尺寸计算值就是限定的100px
大小:fit-content(100px) = min(min(233, 100), min(233, 666)) = 100px // 限定的尺寸
随着容器宽度变小,
auto
关键字对应的宽度也越来越小,可以一直小到min-content
宽度,这里min-content
的宽度值应该是'100px'
这5个字符的宽度了,我量了一下,在我的电脑下面是38像素。于是公式用起来:
fit-content(100px) = min(min(38, 100), min(38, 666)) = 38px
得到宽度是
38px
。
当然日常平时开发啊,我们不需要套用公式计算它最终显示的值。因为公式虽然复杂,但最终的表现形式用语言描述就非常简单。
“尺寸由内容决定,内容越多尺寸越大,但不超过限定的尺寸。”
语法
fit-content( [ <length> | <percentage> ] )
只支持长度值和百分比值。
四、如果重复的数量不确定
以上所有案例展示的都是我们知道列表数目的情况下,如果我们不知道列表数目具体是多少,这个时候我们该如何使用repeat()
函数呢?
CSS中有两个关键字就是用在这种场景下的,这两个关键字分别是auto-fill
和auto-fit
。
1. auto-fill
根据Grid布局中每一个子项的尺寸自动计算需要填充的数量。
计算规则是,当前列表数量下的总尺寸不会超出Grid容器的最大正整数值。
举个例子,有如下CSS代码:
.container { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); }
表示布局究竟有多少列是不确定的,但是每一列的宽度最小是100px
。
效果如下,默认宽度很宽的情况下,最后会有匿名的格子:
随着尺寸变小,列数会跟着动态变化,同时宽度自动填充Grid容器(因为设置了1fr
)。
您可以狠狠地点击这里:CSS repeat()函数auto-fill自动填充demo
当我们使用auto-fill
自动填充的时候,repeat()
函数是不能和auto一起使用的,例如下面这种写法是无效的:
.container {
/* 无效 */
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)) auto;
}
但是可以和长度只和百分比值一起使用,例如:
.container {
/* 有效 */
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)) 20%;
}
这样,每一行最后一列的宽度都会是容器的20%大小,截图示意:
2. auto-fit
auto-fit
和auto-fill
的行为是相似的,区别在于auto-fit
会把空的匿名格子进行折叠合并,而这个合并的0px
大小格子可以认为具有单个格子轨道大小调整的功能,对了,其两侧的格子过道也会合并。
什么意思呢?
在auto-fill
自动填充的时候,如果Grid容器的尺寸特别的宽,则最后会有一些空的格子占位:
但是auto-fit
自动适应的时候,如果Grid容器的尺寸特别的宽,则最后会有一些空的格子会合并成1个,且宽度是0:
也就是auto-fit
场景下,无论Grid容器多宽,子项元素一定是尺寸一定是填满的;当Grid容器尺寸没有富余的时候,两者表现又是一样的。
眼见为实,效果对比,代码如下:
.container { grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); }
效果如下:
您可以狠狠地点击这里:CSS repeat()函数auto-fit自动适应demo (大屏下才能看出和auto-fill差异)
实际开发的时候,按照我个人经验,建议使用auto-fit
。
五、后言及实用性
这篇文章的细节要比我一开始写的时候以为的要多很多,以至于周末两天就写了这一篇文章,小说来不及更新了。
Grid布局适合方方正正纵横交错的布局,在IE10浏览器支持的那一版语法中,Grid布局的优势其实并不是很明显,其实现的东西基本上都有类似的替代方案,所以,当时我表示内心很平静,没有任何波动。
什么时候开始觉得Grid布局还挺屌的呢?
就是浏览器开始纷纷支持repeat()
,minmax()
,fit-content()
等函数和auto-fill
,auto-fit
等关键字之后,其实现的弹性布局效果是以往没有任何CSS属性能够实现的,让Grid布局的等级提升了。
然后自己也意识到一个问题,Grid布局提升并不是我一开始以为的repeat()
函数,更多的是repeat()
函数里面支持的那些关键字和函数,以及整个全新的CSS体系。
如果大家的项目对兼容性的要求还没有那么严格,不妨试试使用Grid布局的新语法新特性。
特别是那些纵横交错的布局(见下面适合使用Grid布局的示意):
行文不易,做demo也不易,GIF录屏方便大家学习理解更不易。
如果您觉得本文内容不错,欢迎微信群或朋友圈转发,就是对这些“不易”最大的支持。
本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9116
(本篇完)
- CSS minmax()函数简介 (0.903)
- CSS Grid布局中的subgrid的适用场景 (0.271)
- 理解CSS3 max/min-content及fit-content等width值 (0.246)
- 深入理解CSS的width:auto (0.246)
- 这啥?CSS calc-size和interpolate-size,真学不动了 (0.246)
- Oh My God,CSS flex-basis原来有这么多细节 (0.149)
- 了解CSS min()/max()/clamp()数学函数 (0.121)
- JS字符串补全方法padStart()和padEnd()简介 (0.097)
- 让CSS flex布局最后一行列表左对齐的N种方法 (0.097)
- JS检测CSS属性浏览器是否支持的多种方法 (0.097)
- CSS值类型文档大全 (RANDOM - 0.054)
css太强了
这种可以更简单一些的min(min(38, 100), min(38, 666))
min(min(38, 100), 666)
minmax() 的demo有误哦~貌似和min-content/max-content串了
好的,感谢反馈。
大神就是牛批~
请教大大,文中演示的 gif 是 用哪款软件做的