4.3.5 垂直分组
有些特殊情况下,需要显示垂直分组的按钮效果,如图4-15所示。
图4-15 垂直分组运行效果
使用的时候只需要将基础用法里的.btn-group样式替换为.btn-group-vertical样式即可。示例如下:
- <div class="btn-group-vertical">
- <button class="btn btn-default" type="button">首页</button>
- <button class="btn btn-default" type="button">个人简介</button>
- <button class="btn btn-default" type="button">作品</button>
- </div>
注意
按钮分组样式.btn-group的设计思想和普通的按钮样式.btn的设计思想不太一样,普通和垂直分组是通过直接替换成不同的class样式实现的,而不是在现有.btn-group样式的基础上,再附加一个新样式实现的(比如:class="btn-group btn-group-vertical")。
复杂的垂直分组按钮和普通按钮组在实现方法上基本一样:不同点如下:
❑垂直按钮组的宽度是自适应的,所以有些情况需要控制父容器的宽度。
❑普通分组的圆角是第一个按钮的左上角和左下角,最后一个按钮的右上角和右下角。
❑垂直分组的圆角是第一个按钮的左上角和右上角,最后一个按钮的左下角和右下角。
复杂的垂直分组按钮和普通按钮组的效果比较如图4-16所示。
图4-16 复杂的垂直分组按钮
图4-16所示是两个比较复杂的垂直按钮组,尤其是第二个。下面结合该图一步一步分析其实现源码。
- // 源码3243行
- .btn-group-vertical > .btn,
- .btn-group-vertical > .btn-group,
- .btn-group-vertical > .btn-group > .btn {/* 该样式在V3.1.0 版才更新,下面会叙述相关的bug */
- display: block; /* 作为块级元素显示 */
- float: none;
- width: 100%; /* 100%显示,如果图片过大,需要控制父元素的大小 */
- max-width: 100%;
- }
- .btn-group-vertical > .btn-group > .btn {
- float: none; /* 如果有嵌套的btn-group组,将其内部按钮的浮动清除 */
- }
- .btn-group-vertical > .btn + .btn,
- .btn-group-vertical > .btn + .btn-group,
- .btn-group-vertical > .btn-group + .btn,
- .btn-group-vertical > .btn-group + .btn-group {
- margin-top: -1px; /* 消除2个按钮上下之间的1像素细节引起的冲突 */
- margin-left: 0; /* 消除2个按钮之间外左边距 */
- }
- .btn-group-vertical > .btn:not(:first-child):not(:last-child) {
- border-radius: 0; /* 除第一个按钮、最后一个按钮外,其他btn样式的按钮不设置圆角 */
- }
- .btn-group-vertical > .btn:first-child:not(:last-child) {
- border-top-right-radius: 4px; /* 第一个按钮(并且不是最后一个按钮)的左下角和右下角不设置圆角 */
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- }
- .btn-group-vertical > .btn:last-child:not(:first-child) {
- border-top-left-radius: 0; /* 最后一个按钮(并且不是第一个按钮)的左上角和右上角不设置圆角 */
- border-top-right-radius: 0;
- border-bottom-left-radius: 4px;
- }
- .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
- border-radius: 0;/* 如果有嵌套的btn-group组,将其内部按钮(除第一个和最后一个以外)的圆角清除*/
- /* 如图4-17中的嵌套2按钮 */
- }
- .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
- .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
- /* 如果有嵌套的btn-group组,将第一组(且不是最后一组)的最后一个按钮或者下拉菜单的左下角和右下
- 角的圆角清除*/
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;/* 以便和下一组的按钮平衡,比如按钮“嵌套3”和按钮“嵌套6”
- 之间没有圆角 */
- }
- .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
- /* 如果有嵌套的btn-group组,将最后一组(但不是第一组)的第一个按钮的左上角和右上角的圆角清除*/
- border-top-left-radius: 0;
- border-top-right-radius: 0;
- }
对于最新的V3.1.0版,对这个功能的使用一般都没有问题,但在V3.1.0之前的版本,使用的过程中,在两个特殊的场景下会产生bug,如图4-17所示。第一个bug是将第一张图里的“图书作品”下拉按钮修改成“图书”按钮就会显现出来了(下拉菜单和普通按钮没对齐)。第二个bug通过如下示例代码即可发现(按钮“嵌套6”的右上角的圆角没有消除)。
- <div class="btn-group btn-group-vertical">
- <button class="btn btn-default" type="button">首页</button>
- <button class="btn btn-default" type="button">个人简介</button>
- <button class="btn btn-default" type="button">作品</button>
- <div class="btn-group">
- <button class="btn btn-default" type="button">嵌套1</button>
- <button class="btn btn-default" type="button">嵌套2</button>
- <button class="btn btn-default" type="button">嵌套3</button>
- </div>
- <div class="btn-group">
- <button class="btn btn-default" type="button">嵌套4</button>
- <button class="btn btn-default" type="button">嵌套5</button>
- <button class="btn btn-default" type="button">嵌套6 </button>
- </div>
- </div>
图4-17 出现bug的效果
第一个Bug产生的原因在3424行,作者为相关的元素设置了100%的宽度,但只考虑了以下两种情况:
❑.btn-group-vertical样式的直接子按钮(带有.btn样式的按钮)
❑.btn-group-vertical样式中的分组(带有.btn-group样式的分组)
该样式没有考虑第三种情况,也就是分组中的按钮的宽度设置。所以,如果想让“图书”按钮也和上面的按钮对齐的话,则也要设置其宽度为100%,选择符是.btn-group-vertical > .btn-groupl > .btn,将该选择符和上述两个选择符放在一起即可(目前最新的V3.1.0已经解决了该bug)。
第二个Bug产生的原因在于V3.1.0之前的代码(如V3.0.3),作者只消除了第一组.btn-group按钮的最后一个按钮(“嵌套3”)的圆角,和最后一组.btn-group按钮的第一个按钮(“嵌套4”)的圆角,但是没有消除最后一组.btn-group按钮的最后一个按钮(“嵌套6”)的右上角的圆角。原来的代码如下:
- .btn-group-vertical > .btn-group:first-child > .btn:last-child,
- .btn-group-vertical > .btn-group:first-child > .dropdown-toggle {
- border-bottom-right-radius: 0;
- border-bottom-left-radius: 0;
- }
- .btn-group-vertical > .btn-group:last-child > .btn:first-child {
- border-top-right-radius: 0;
- border-top-left-radius: 0;
- }
而新版的V3.1.0中的代码则很巧妙地利用了两个伪类not来限制选择符,比如:.btn-group: first-child: not(: last-child)和.btn-group: last-child: not(: first-child)。