关于bootstrap框架里btn-group-justified类的解析

前言

之前有一篇关于media类的解析,讲述bs框架的_media.scss类里media-body样式含有width:10000px的原因和寻找答案的过程。此篇是讲述寻找btn-group-justified直接子元素样式含有width:1%的原因,及寻找答案的过程。

btn-group-justified类

源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Justified button groups
// ----------------------
.btn-group-justified {
display: table;
width: 100%;
table-layout: fixed;//表格布局:列宽由表格宽度和列宽度设定。标识①
border-collapse: separate;//合并表格边框,使用该属性建议页面规定!DOCTYPE
> .btn,
> .btn-group {
float: none;
display: table-cell;
width: 1%; // 标识②
}
> .btn-group .btn {
width: 100%;
}
> .btn-group .dropdown-menu {
left: auto;
}
}

其它属性都很好理解,唯独标识②不知是何用意。遂群发求助,得线索:Understanding CSS table-cell and percentage width

单元格有无设置width时,浏览器经历了什么?

先不论bootstrap设置标识②的前后文关系,单说单元格设置width时,浏览器是如何计算的。

列宽、单元格宽计算规则:

这与表自动布局有关,列宽的总值与表宽的值是相对应的。列宽的值和单元格宽有关,单元格宽由单元格里内容的长度决定(简称块宽)。

总块宽小于表宽时,浏览器会自动计算出单元格的宽值,再相应的计算各个列宽值,其中总块宽与表宽的差值由列宽均分

总块宽大于表宽时,此时列宽不够分配,前单元格宽值会挤掉后单元格宽,所以,我们应合理的分配单元格的宽度(划重点)。

由以上我得出一个列宽公式:块宽+差值/N列=列宽值;(差值:表宽-总块宽)


举个栗子:

示例1,无width

我手上有一个宽100px的盒子(表),我在内部隔出三个等宽的空间出来(列),每个空间都内都套了塑料袋(单元格),我朝里面塞东西(块),当东西没有塞满这个空间时,这三个空间仍然均等,当其中1号空间塞满了我又继续塞,于是1号空间就挤掉2号空间一点宽度。

示例2,有width

同上,100px宽的盒子,仍然在内部隔出三个等宽的空间出来(列),每个空间都放置了一个小盒子(有width的单元格),朝里面塞东西,结果同上面一样。

这两个例子唯一不同的是,

  • 示例一:单元格宽值:单元格宽 == 块宽。
  • 示例二:单元格宽值:width值 ≤ 单元格宽 ≤ 块宽。

基于列宽、单元格宽计算规则,两个例子的列宽值如下,

  • 示例一:块宽+[(表宽-总块宽)/N列]
  • 实例二:块宽小于width时,为width值,大于width时为块宽值。块宽+[表宽-(width或块宽)/N列]

至此,width相对于表宽的计算规则已经明白其目的是为了让浏览器计算出百分比。

那么,btn-group-justified类中其直接子元素的width的值为何是1%?

回到bootstrap,说说table-layout: fixed;

w3c指设置 表格布局:列宽由表格宽度和列宽度设定。

这样设置后,列宽值 与 单元格宽值 相等,

可以这么理解。列宽 等于 表宽 除以 N个单元格;
要注意的是设置此属性之后,块宽将不能影响列宽的计算。

那么表单元的width:1%到底是干啥呢?

表单元宽值越小,差值则越大,可分配的列宽值就越多,如此方便你添加更多的列,不然可试试表单元width:50%的三列表,第三列都给你挤没咯。

话说回来,table-layout: fixed下width不起作用?

其实有一丢丢小差别的,但是微乎其微,且合理的表宽值能避免这个问题。有兴趣的可以去 bootstrap之btn-groups组件 F12一下,在两端对齐排列的按钮组的示例demo里,把其中一个块的内容去掉,彼时块宽为0,对比有无width:1%时的各列宽值吧!

总结

如上分析,我忽然发现

  • 父元素:display:table;width:100%;table-layout: fixed;
  • 子元素:display: table-cell;

以上配合能实现多列等分布局,又一css技巧~ get!