业务场景
试想,我们需要这样一种两栏布局:
两栏高度固定,中间的间距固定为20px,左栏的宽度固定为父元素宽度的100%减去20px再乘以40%;右栏的宽度固定为父元素宽度的100%减去20px再乘以60%。
我们是否真的需要这种布局呢?
答案是肯定的。就UI设计图而言,往往只针对某种分辨率做了设计,当前端还原成设计稿时,不仅需要考虑设计图所示分辨率,还需要其他分辨率的缩放情况。当 UI设计图采用以上设计思路时,就需要前端用CSS来实现该效果。
难点分析:多次运算calc不能实现
我们可以用width:calc(100% - 20px)
这样来进行简单的运算,上述需求中,不仅需要得到父元素100% - 20px
的宽度,还需要再次乘以40%
,该场景下无法胜任。(假设你实现了,可以告诉作者,以便更正。)
破局:增加容器、拆解运算
既然calc不能实现,我们只能走迂回战略,一步步拆解运算了。
- 增加一个容器,宽度等于父元素的100% - 20,该容器成为两栏新的父元素;
- 两栏的宽度为容器的40%和60%;
- 设置两栏的间距为20px。
第一步可以通过calc实现,第二步使用百分比即可,第三步则稍微麻烦,因为一旦给两栏设置margin值则比例变了,结果不正确。
因此另外一个关键点是:
间距不能占据计算的空间。
这样,我们可以想到两个额外的办法:
- 对右栏采用translateX实现偏移
- 对右栏采用position:relative和left实现偏移。
现在思路很清晰了。
完整案例:(可直接运行)
以下提供两种方法的运行案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 方法一:translateX */
.mid {
width: calc(100% - 20px);
display: flex;
}
.child {
height: 400px;
}
.child.left {
width: 40%;
background-color: red;
}
.child.right {
width: 60%;
transform: translateX(20px);
background-color: green;
}
/* 方法二:position*/
/* .mid {
width: calc(100% - 20px);
display: flex;
}
.child {
height: 400px;
}
.child.left {
width: 40%;
background-color: red;
}
.child.right {
width: 60%;
position: relative;
left: 20px;
background-color: green;
} */
</style>
</head>
<body>
<div class="parent">
<div class="mid">
<div class="child left"></div>
<div class="child right"></div>
</div>
</div>
</body>
</html>
回顾:有点绕
虽然最后看起来挺简单,但是如果不能想到增加容器,或者增加了容器不能合理处理中间的间距,就会使得这种布局难以实现,以至于误认为css无法实现,令UI同事怀疑你的水平。CSS博大精深,毕竟是“世界上最难的语言”
如果你有更好的方法,欢迎指出交流。