系列文章
- [ 基础系列 ] - CSS 小测 01
- [ 基础系列 ] - CSS 小测 02
- [ 基础系列 ] - CSS 小测 03
- [ 基础系列 ] - CSS 小测 04
- [ 基础系列 ] - CSS 小测 05
- [ 基础系列 ] - CSS 小测 06
说在前面
本篇是张鑫旭老师的 CSS 基础测试8 的阅后笔记。
题目
先来看看题目。
请实现一个按钮相关的单行布局效果。
当只有一个按钮的时候,宽度 100%,效果如下:
左右安全距离为 1rem。
当有两个以上按钮的时候,间隙 1rem,宽度等分,效果如下:
需求:
- 尺寸间距符合题意
- 按钮 UI 符合设计稿
- 布局随着按钮个数自动适配
- 整体宽度自适应
- 代码友好
- 按钮永远一行,不换行显示
思路
这道题没有什么难度,我们就横向分析一下。
首先简单把效果实现一下。题目要求的单行布局,自适应,通常有以下几种方案:
flexgridtable
在不考虑兼容性(IE9+)的情况下,单行自适应布局,以 flex 为最优,这里先用 flex 来实现题中效果。
关键点只有一点:
flex: auto
代码如下:
<div class="btn-group">
<button class="btn">按钮</button>
</div>
<div class="btn-group">
<button class="btn">按钮</button>
<button class="btn">按钮</button>
</div>
<div class="btn-group">
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
</div>
.btn-group {
margin: 1rem 0;
display: flex;
padding: 0 1rem;
}
.btn {
margin-right: 1rem;
flex: auto;
height: 26px;
color: #ef7077;
border: 1px solid;
border-radius: 13px;
background: transparent;
}
.btn:not(:last-child) {
margin-right: 1rem;
}
效果如下:
好的,今天的总结就......( ̄ε(# ̄)☆╰╮o( ̄皿 ̄///)
就上面的代码,我们聊一聊一些平时开发不容易注意到的细节吧。
首先,题目中有要求:
- 按钮永远一行,不换行显示
那为什么代码没有设置 flex-wrap: nowrap 呢?
这是因为设置 display: flex 之后,默认就会设置 flex-wrap: nowrap。
然后可能有同学注意到我在子项中使用的是 flex: auto,而不是 flex: 1。当然这里使用 flex: 1 也能实现同样的效果,甚至 flex: 2/3/4/5/n 都行,但语意并不贴切,这里更推荐使用 flex: auto。
接下来是关于安全距离的问题,有的同学可能会这样实现:
.btn-group {
padding: 0 0.5rem;
}
.btn{
margin: 0 0.5rem;
}
看上去似乎代码更为简洁,但实际开发中并不推荐这样做。通过容器和元素共同实现安全距离的操作,逻辑不清,代码难以维护。
通常在布局的时候,边距尽量仅使用容器实现,不要影响子项。这里按钮与按钮之间的间距,通过 not 伪类实现是比较推荐的做法。
另外上面有提到,通过 grid 和 table 也能实现这个布局,下面分别来看看。
grid
事实上,grid 布局用在这里并不是很合适,grid 更适合的场景是更加偏向二纬的,比如经典的网格布局,这里就当作学习看看 grid 如何实现题目中的布局效果吧。
.btn-group {
margin: 1rem 0;
padding: 0 1rem;
display: grid;
grid-auto-flow: column;
grid-gap: 1rem;
}
效果如下:
与 flex 相比,grid 的优势是可以控制单元格的间距。
table
table 布局并没有上面两者那么直观,优势在于兼容性更强,可以用于 IE8+。
由于 table 布局需要子项为块级元素,所以这里我们需要在 button 外包裹一个 div
<div class="btn-group" data-layout="table">
<div class="btn-wrap">
<button>按钮</button>
</div>
<div class="btn-wrap">
<button>按钮</button>
</div>
<div class="btn-wrap">
<button>按钮</button>
</div>
</div>
.btn-group[data-layout="table"] {
display: table;
white-space: nowrap;
width: calc(100% - 1rem);
margin-left: auto;
}
.btn-group[data-layout="table"] > .btn-wrap {
display: table-cell;
padding-right: 1rem;
}
.btn-group[data-layout="table"] > .btn-wrap > button {
width: 100%;
height: 26px;
color: #ef7077;
border: 1px solid;
border-radius: 13px;
background: transparent;
}
效果如下:
优化
这里的优化可以从以下几点出发:
hover,focus效果- 长文本按钮
hover,focus 效果
这只是一个思路,下面简单演示一下:
.btn {
outline: none;
}
.btn:hover,
.btn:focus {
background: #ef7077;
color: #fff;
}
效果如下:
长文本按钮
这个结合 text-overflow: ellipsis 属性即可:
.btn {
flex: auto;
height: 26px;
color: #ef7077;
border: 1px solid;
border-radius: 13px;
background: transparent;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
效果如下:
结束语
涉及到键盘访问,有的同学可能会想到 tabindex,事实上这个属性不涉及到 form 表单提交的话,一般情况是不用添加的。
然后这里是 在线 demo