5.2.1 弹窗布局与样式
在讲解用法之前先看一下一般弹窗的运行效果,如图5-1所示。其中包括了3个部分:头部(包括标题和关闭符号),中间部分(主要是内容),底部(主要是放置操作按钮)。
图5-1 普通的弹窗效果
根据上述效果,我们先来了解一下弹窗HTML代码的布局定义和相关的样式。和之前的老版本不同,新版的弹窗组件使用了3层div容器元素,其分别应用了modal、modal-dialog、modal-content样式。然后在真正的内容容器modal-content内包括了弹窗的头(header)、内容(body)、尾(footer)3个部分,分别应用了3个样式:modal-header、modal-body、modal-footer。示例代码如下:
- <div class="modal show">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal"
- aria-hidden="true">×</button>
- <h4 class="modal-title">Modal标题</h4>
- </div>
- <div class="modal-body">
- <p>这里是弹窗里的具体内容………</p>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn btn-default" data-dismiss="modal">
- 关闭</button>
- <button type="button" class="btn btn-primary">保存</button>
- </div>
- </div>
- </div>
- </div>
modal样式和之前的功能有所不同,在这里只是做一个背景容器,100%充满全屏(其底部还有一个100%充满全屏的modal-backdrop样式,稍后再说)。另外还有一个功能是,当弹窗中内容很多的时候,可以在modal容器里进行滚动操作,避免了弹窗不能移动的弊端。源码如下:
- // 源码5096行
- .modal {
- position: fixed; /* 固定布局 */
- top: 0; /* 上下左右都是0,表示充满全屏 */
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 1050;/* 提升z-index,防止其他元素溢出,modal-dialog的z-index是1050 */
- display: none; /* 默认不显示 */
- overflow: auto;
- overflow-y: scroll; /* 竖向可以滚动 */
- -webkit-overflow-scrolling: touch; /* 支持移动设备上使用触摸方式进行滚动 */
- outline: 0; /* 消除虚边框 */
- }
另外在modal样式的基础上,Bootstrap还提供一个动画的功能,即在弹窗完全显示之前执行一段动画,其动画内容是:从-25%的top值位置到top:0的位置。相关代码如下:
- // 源码5109行
- .modal.fade .modal-dialog {
- -webkit-transition: -webkit-transform .3s ease-out; /*减速运行*/
- -moz-transition: -moz-transform .3s ease-out;
- -o-transition: -o-transform .3s ease-out;
- transition: transform .3s ease-out;
- -webkit-transform: translate(0, -25%); /*向下移动25%的距离,从而产生向下的动画视觉*/
- -ms-transform: translate(0, -25%);
- transform: translate(0, -25%);
- }
- .modal.in .modal-dialog { /*页面完整显示时,回归到原始位置*/
- -webkit-transform: translate(0, 0);
- -ms-transform: translate(0, 0);
- transform: translate(0, 0);
- }
在modal完全充满全屏的情况下,默认在其内部(也就是内部容器)放置了一个宽度自适应、左右水平居中的modal-dialog样式的div容器。modal-dialog样式有两段代码,其源码如下:
- // 源码5123行
- .modal-dialog { /*默认设置(包括窄屏)*/
- position: relative; /* 相对于modal元素,进行相对定位 */
- width: auto; /*宽度自适应*/
- margin: 10px; /*10像素外边距*/
- }
分辨率大于768像素时的样式设置如下:
- // 源码5188行
- @media (min-width: 768px) { /* 可视范围大于768像素的普通浏览器 */
- .modal-dialog {
- width: 600px; /* 普通宽度为600像素 */
- margin: 30px auto; /* 上下各30像素外边距,这里才是设置弹窗看起来居中的地方,
- 这不是真正居中,而是30像素的高度 */
- }
- .modal-content {
- -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
- box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
- }
- .modal-sm { width: 300px; /* 小型弹窗设置其宽度为300像素 */ }
- .modal-lg { width: 900px; /* 大型弹窗设置其宽度为900像素*/ }
- }
通过上述两段代码可以看出来,在正常的桌面浏览器(可视区域大于768像素)上,弹窗并不是上下居中,而只是设置了30像素的padding-top值而已,因为从视觉上看和上下居中区别不大;而在移动设备(小于768像素)的浏览器上,则只有10像素的外边距(看起来几乎是满屏显示了),效果如图5-2所示。
图5-2 不同尺寸浏览器下的运行效果
另外,modal-sm和modal-lg样式是两个新样式,在新版V3.1.0中才推出,用于在768像素以上的浏览器上,对弹窗进行强制缩小(宽度为300像素)和加大设置(宽度为900像素)。
对于第三层嵌套div上的modal-content样式,才是对弹窗进行设置的主要代码,主要是边框、边距、背景色、阴影的处理。源码如下:
- // 源码5128行
- .modal-content { /*默认设置(包括窄屏)*/
- position: relative; /* 相对定位 */
- background-color: #fff; /* 白色背景 */
- background-clip: padding-box; /* 背景的裁剪区域设置,从padding区域向外 */
- border: 1px solid #999; /* 边框设置 */
- border: 1px solid rgba(0, 0, 0, .2); /* 透明度为0.2 */
- border-radius: 6px; /* 圆角设置 */
- outline: none; /* 取消轮廓显示 */
- -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5); /* 阴影设置 */
- box-shadow: 0 3px 9px rgba(0, 0, 0, .5);
- }
同样,作者对于不同宽度的浏览器也进行了自适应设计,对于桌面浏览器(或可视范围大于768像素的浏览器),加大了阴影设置。
- // 源码5193行
- @media (min-width: 768px) { /* 可视范围大于768像素的普通浏览器 */
- .modal-content {
- -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
- box-shadow: 0 5px 15px rgba(0, 0, 0, .5);
- }
- }
内容区域上中下3个部分的样式,主要是用于控制3个地方的内外边距和对齐方式等。主要代码如下:
- // 源码5156行
- .modal-header { /* 弹窗头部位置设置 */
- min-height: 16.428571429px; /* 最小高度设置 */
- padding: 15px; /* 内边距 */
- border-bottom: 1px solid #e5e5e5; /* 底部设置细线,和modal-body区分 */
- }
- .modal-header .close {
- margin-top: -2px; /* 关闭按钮 */
- }
- .modal-title { /* 头部位置内的标题样式 */
- margin: 0;
- line-height: 1.428571429;
- }
- .modal-body { /* 中间内容区域 */
- position: relative; /* 相对位置 */
- padding: 20px; /* 内边距 */
- }
- .modal-footer { /* 底部区域设置 */
- padding: 19px 20px 20px; /* 内边距 */
- margin-top: 15px; /* 顶部外边距 */
- text-align: right; /* 居右对齐,因为一般都是按钮 */
- border-top: 1px solid #e5e5e5; /* 上边框设置,以便和modal-body分隔 */
- }
另外,由于底部区域一般都是放置各种按钮,所以在底部样式内,也对各种按钮进行了特殊设置。源码如下:
- // 源码5178行
- .modal-footer .btn + .btn { /* 底部区域内的按钮样式设置,如果有多个按钮,设置左部外边距 */
- margin-bottom: 0;
- margin-left: 5px;
- }
- .modal-footer .btn-group .btn + .btn {
- margin-left: -1px;/* 底部区域内的按钮组样式设置,如果按钮都在一个组内,则减小左部外边距值 */
- }
- .modal-footer .btn-block + .btn-block { /* 底部区域内的按钮块样式设置 */
- margin-left: 0; /* 取消左部外边距*/
- }
最后,关于弹窗,还有一个隐性的样式(modal-backdrop),也就是大背景,一般设置为灰色背景。除了弹窗内容以外,对于背景下面的元素的所有单击事件一律阻止。该样式是通过JavaScript代码在弹窗弹出之前附加到body元素内的,其z-index(1040)在modal(1050)之下。相关源码如下:
- // 源码5139行
- .modal-backdrop {
- position: fixed; /* 固定定位 */
- top: 0; /* 上下左右充满全屏 */
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 1040; /* 小于modal的1050,阻止鼠标单击背景下的其他元素 */
- background-color: #000; /* 默认黑色背景 */
- }
- .modal-backdrop.fade { filter: alpha(opacity=0); opacity: 0;
- /* 动画过渡之前,保持原样,即透明度为0 */}
- .modal-backdrop.in { filter: alpha(opacity=50); opacity: .5;
- /* 动画过渡之后,保持50%的透明度 */}
通过源码,我们可以想象出整个模态弹窗的盒子模型,如图5-3所示。如果大家还不理解,请再次阅读上面的源码分析。
图5-3 模态弹窗的盒子模型