在上一期我们学习了数学函数和选择器的使用,现在我们换一个思维,将知识点搬到实际的应用元素中,了解 2023 年应该使用的新属性,本期依然采用截止到 2023 年前的兼容性良好的属性,请各位放心“食用”。
元素比例属性
在以前我们将一个元素按照自定义的比例展现在 html 面前时,例如我想嵌入一个 iframe 框架的视频,并且以 16:9 的形式展现出来。我们以 B 站举例,这时通常会使用两种方式,如下:
<iframe id="bilibili" src="https://player.bilibili.com/player.html"></iframe>
方式一 JS 处理
document.getElementById("bilibili").style.height=document.getElementById("bilibili").scrollWidth*0.56+"px";
获取元素高度并对并且设置宽度×0.56,为什么是 0.56 呢?因为 9/16 = 0.56
方式二 CSS 处理
我们首先对 iframe 外部嵌套一个父元素 div
<div>
<iframe></iframe>
</div>
然后设定下述 CSS 属性
div {
position: relative;
width: 100%;
height: 0;
padding-bottom: 56%;
}
iframe {
position: absolute;
width: 100%;
height: 100%;
}
这样操作的意思是对父元素的高度做空,然后设定 padding 撑起高度,因为 padding 会随着宽度自动增大 56%的高度,这样就始终保持着 16:9 的样子。然后,让子元素通过定位的方式在父元素展开即可。
上述的两种方式都可以实现出我们想要的结果,但无论是更改 html 结构还是使用大量的 JS 和 CSS,使用起来都很复杂。而现在aspect-ratio
的出现,为我们只需要一行 CSS 就可以实现。
<iframe id="bilibili" src="https://player.bilibili.com/player.html"></iframe>
新方式 CSS 处理
iframe {
width: 100%;
aspect-ratio: 16 / 9;
}
书写方式
它的书写规则十分简单,例如:
aspect-ratio: auto; // 保持原有的纵横比
aspect-ratio: 16 / 9; // 纵横比为 16:9
aspect-ratio: 5 / 4; // 纵横比为 5:4
"/" 和后面的高度比可以省略,默认为 1 :
aspect-ratio: 1; // 纵横比为 1:1
aspect-ratio: 4; // 纵横比为 4:1
aspect-ratio 兼容性
框距简写属性
在以前我们对一些边边框框的属性都会使用上右下左的方式去书写,例如:
border-top border-right border-bottom border-left
margin-top margin-right margin-bottom margin-left
padding-top padding-right padding-bottom padding-left
然后会使用 CSS2 就有的简写属性,遵循上右下左的规则。
border: top right bottom left
margin: top right bottom left
padding: top right bottom left
inline 和 block
上述使用同一个属性,对上右下左同时定义固然方便,尤其在 4 个属性相同时的情况。但如果不影响其他方向的属性时,就比较麻烦了。例如有一个 img 标签:
img {
margin-top: 1rem;
margin-right: 2rem;
margin-bottom: 3rem;
margin-left: 2rem;
// 简写为 margin: 1rem 2rem 3rem 2rem;
// 或写为 margin: 1rem 2rem 3rem;
}
这时,我想让 class 为 tree 的 img 左右边距为 0,并且不影响上下边距。那么我们通常会有两种处理方式:
方式 1:
img.tree {
margin-right: 0;
margin-left: 0;
}
方式 2:
img.tree {
margin: 1rem 0 3rem;
}
上述方式看似比较理解,但都有弊端。方式 1,会增加代码量。方式 2,虽然代码简短,但将 margin 四个方向锁死,如果更改 img 统一属性时,那么则不会像方式 1 同步过来。所以这时*-inline
和*-block
诞生出来,只需要一行margin-inline
省略了margin-right
和margin-left
。同理margin-block
省略了margin-top
和margin-bottom
。
新方式
img.tree {
margin-inline: 0;
}
含义如下(默认顺序)
*-block = *-top 和 *-bottom
*-inline = *-left 和 *-right
* 表示可适用于 margin、padding、border 和 inset
它们的命名方式也十分容易理解,inline 即为行,block 即为竖(虽然它的直译是块)。换句话说,inline 默认是从左往右水平排列,block 默认是从上往下垂直排列。
inset
在定位布局下的 left top right bottom 也有简写方式,如下:
div {
position: fixed;
left: 0; top: 0; right: 0; bottom: 0;
// 简写为 inset: 0;
top: 0; bottom: 0;
// 简写为 inset-block: 0;
left: 0; right: 0;
// 简写为 inset-inline: 0;
}
单独定义
inline 和 block 规则可以单独定义上右下左。它以*-start
和*-end
来区分方向,例如
就表示内联元素排列方向的起始位置,既左侧。*-
inline-start
就表示内联元素排列方向的终止位置,既右侧。但有不同的情况发生不同的含义,例如:*-
inline-end
- 如果我们设置
direction:rtl
(水平文档流方向从右往左),此时 start 对应的就是右侧,end 对应的就是左侧。 - 如果我们设置
writing-mode:vertical-rl
(文档流改为垂直且从右往左排列),此时内联元素是从上往下排列的,inline 就变成了垂直方向,block 则为水平方向。
div {
top: 0; bottom: 0; left: 0; right: 0;
// 简写为 inset: 0;
// 此时我想 top 为 1rem
inset-block-start: 1rem;
}
含义如下(默认顺序)
*-block-start = *-top
*-block-end = *-bottom
*-inline-start = *-left
*-inline-end = *-right
* 表示可适用于 margin、padding、border 和 inset
上述方式虽然增加了更多的定义,但我认为在中文环境下的默认顺序里意义不大,可直接使用原有属性。
简写兼容性
结语
愉快的第三期结束了,快去简化你的 CSS 吧。下期我们一起将视角转到文字和段落上,CSS 关于文字和段落的处理更加有趣,众多的属性已经不是一个 font 就可以解决的了。下面插一个本期学习的实例:
在以前居中一个 fixed 布局有两种设置方式:
方式 1
div {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
方式 2
div {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
新方式
div {
position: fixed;
inset: 0;
margin: auto;
}
注:上述 div 在已规定 width 和 height 情况下才可适用。