CSS 自定义属性 进阶(二)
模块化CSS
通常,为了实现可复用可定制的模块,我希望将某个实现抽象化。例如,下面这段CSS代码:
.grid { display: flex; flex-direction: row; flex-wrap: wrap; padding: calc(var(--margin) / 2); } .grid > .cell { display: block; width: calc(100% / var(--columns) - var(--margin)); margin: calc(var(--margin) / 2); }
那么,要怎么抽象出这段代码呢?
- 抽象封装
首先,作为一个模块需要沙盒机制,所以先给它们都加上命名空间,取名有很多种方式,比如 BEM 还有 SMACSS。不过简洁起见。在本文里我们暂时用 my- 作为前缀。再补充上变量定义和一些注释:
.my-grid { /* CSS 变量定义 网格的列数 网格边距 列与列的间距 */ --my-grid-columns: 1; --my-grid-margin: 16px; display: flex; flex-direction: row; flex-wrap: wrap; /* 兼容代码 */ padding: 8px; padding: calc(var(--my-grid-margin) / 2); }
- 使用
<link rel="stylesheet" href="my-grid.css">
引入样式表之后,根据样式覆盖原则,在默认样式的之后对 CSS 变量赋上新值:
<style> .my-grid { --my-grid-columns: 2; } </style>
也可以在其他的选择器中对变量赋值;还能通过媒体查询,在不同的场景下使用不同的值:
.my-app .my-grid { --my-grid-columns: 1; --my-grid-margin: 8px; } @media (min-size: 600px) { .my-app .my-grid { --my-grid-columns: 3; --my-grid-margin: 16px; } } @media (min-size: 1024px) { .my-app .my-grid { --my-grid-columns: 6; --my-grid-margin: 16px; } }
应用:保持图片长宽比
假如你正在搭建自己的博客,你想给图片元素设置 max-width,防止它超出容器的范围:
.my-content { max-width:600px; }
如果一开始图片没有占位,那么在图片加载的时候页面内容会不断往下移动,所以一开始就要为图片占好位。在 img 标签中直接定义了宽高的话:
<img src="demo.jpg" height="1024" width="768">
图片在自适应窗口宽度的时候,浏览器是不会保证它的横纵比的,它只能保证图片的高度是 768px 同时让图片的宽度不要超过 600px(CSS 中的定义),结果我们会得到一张变形的图片:
那么你要怎么保证图片在任何场景下都不变形?使用 padding 保证图片的长宽比应该是最广为人知的方式
,如果要实现 16:9 的比例,你可以这么做:
.aspect-ratio-16-9 { position: relative; } .aspect-ratio-16-9::before { display: block; padding-top: 56.25%; /* 9 / 16 * 100% */ content: ""; } .aspect-ratio-16-9-content { position: absolute; top: 0; right: 0; bottom: 0; left: 0; }
HTML 结构如下:
<div class="aspect-ratio-16-9"> <div class="aspect-ratio-16-9-content"> This box will have a 16:9 aspect ratio. </div> </div>
如果只有几种横纵比还好,但你要做的是网格布局的图片流,就会遇到各种各样尺寸的图片,这个方法明显不能解决问题。
- 使用自定义属性
.my-image-wrapper { /* 自定义属性 * 长宽比 */ --my-image-wrapper-w: 1; --my-image-wrapper-h: 1; position: relative; } .my-image-wrapper::before { display: block; padding-top: calc(var(--my-image-wrapper-h, 1) / var(--my-image-wrapper-w, 1) * 100%);//缺省值为1 content: ""; } .my-image-wrapper > img { position: absolute; top: 0; right: 0; bottom: 0; left: 0; height: 100%; width: 100%; }
—my-image-wrapper-w 和 —my-image-wrapper-h 就是模块化的 CSS 接口
,使用起来很灵活:
<h3>原图尺寸:1024*768,故图片的宽高比是 4:3</h3> <div class="my-content my-image-wrapper" style="width:768px; --my-image-wrapper-w:4; --my-image-wrapper-h:3;"> <img src="demo.jpg"> </div>
现在可以正常显示了:
OK ,关于CSS自定义属性系列的文章,暂时介绍到这里。在博客中还有其他与CSS相关的文章【在这里】。