盒模型是 CSS 的基石之一, 它指定元素如何显示以及 (在某种程度上) 如何交互. 页面上每一个元素都被看做一个矩形框, 框由元素的内容, 内边距 (padding), 边框 (border)和外边距 (margin)组成, 如下图所示.
内边距出现在内容区域周围, 若给元素上添加背景, 背景将会应用于由内容和内边距组成的区域. 添加边框, 会在内边距的区域外加一条线, 这些线有多种样式, 后面会有所介绍. 在边框外边是外边距, 外边距是透明的, 一般使用它控制元素之间的间隔.
CSS2.1 还包含 outline 属性, 绘制在元素框之上, 不影响元素的大小或定位. 大多数现代浏览器 (包括 IE8) 都支持 outline, 但 IE7 和更低版本不支持.
内边距, 边框, 外边距都是可选的, 默认值为零. 但许多元素将由用户代理样式表设置外边距和内边距, 所以将元素的 margin 和 padding 设置为零, 对写整个样式有帮助, 这项工作一般由全局 reset 进行.
1. IE 和盒模型
IE 的早期版本, 包括 IE6, 在混杂模式中使用自己的非标准盒模型. 浏览器的 width 属性不是内容的宽度, 而是内容, 内边距和边框的总和. 添加的内边距越多, 给内容预留的空间就越少.
在 CSS3 中, 可通过 box-sizing 属性定义使用哪种盒模型, 但除了一些非常特殊的场合很少使用该属性.
目前最好的解决方案是回避这个问题. 也就是, 不给元素添加指定宽度的内边距, 而是尝试将内边距或外边距添加到父元素或子元素.
2. box-sizing
box-sizing 属于 CSS3 内容, 属性值包括: content-box, border-box, inherit. 该属性用于更改预设的 CSS 盒模型宽度和高度的计算方式, 可使用该属性模拟不正确支持 CSS 盒模型规范的浏览器行为.
content-box
根据 CSS 标准的起始值和预设值(标准盒模型, 现在浏览器默认支持该属性).width 和 height 只包括内容本身的宽度和高度. 元素框的大小 = width/height+padding+border+margin
border-box
该属性值下, width 和 height 属性包括内容 (content), 内边距(padding) 和边框(border).
inherit. 指定 box-sizing 属性的值, 应该从父元素继承
浏览器支持: IE8 及以上, Chrome 10.0 以上, Firefox 29.0 以上, Safari 5.1 以上, Opera 9.5 以上.
示例:
- div {
- box-sizing:border-box;
- -moz-box-sizing:border-box; /* Firefox */
- -webkit-box-sizing:border-box; /* Opera */
- width:50%;
- float:left;
- }
- 3. margin
margin 属性用于设置外边距, 下面我们将讲述 margin 一些比较有意思的知识点
3.1 margin 与容器尺寸
在标准盒模型中, border-box 部分, 即包括 border,padding,content 的方框代表可视尺寸(clientWidth). 外边距加上可视尺寸则是 "占据尺寸"(张鑫旭大神自命名).
在一些前提下, 通过设置 margin 属性可以改变可视尺寸和 "占据尺寸" 的大小.
1. margin 改变可视尺寸
适用范围:
适用于没有设定 width/height 的普通 block 水平元素(float,absolute/fixed,inline 水平, table cell 元素...)
只适用于水平方向尺寸
可利用该特性实现一侧定宽自适应布局和两端对齐布局效果.
2. margin 改变 "占据尺寸"
适用范围:
block/inline-block 水平元素均适用
与有无设定 width/height 值无关
适用于水平方向和垂直方向
可利用该效果实现滚动容器上下留白及等高布局效果.
3.2 margin 与百分比单位
普通元素的百分比 margin 都是相对于容器 (父级元素) 的宽度计算.
绝对定位元素的百分比 margin 都是相对于第一个定义祖先元素 (relative/absolute/fixed) 的计算宽度
在 IE 中, 绝对定位元素的百分比 margin 是相对于第一个定义祖先元素的宽度计算
在 Chrome/Firefox/Opera 中, 绝对定位元素的百分比 margin 是相对于第一个定义祖先元素的 border-box 的宽度计算的. Opera 浏览器由于作者是 Windows 系统, 安装的 Windows 版本, 感觉表现得很奇怪. 没有显示出数值, 不方便得出结论, 希望有读者能够测试了在评论区反映一下, 共同探讨之, 谢谢!
3.3 margin 重叠
margin 重叠, 即外边距叠加, 是一个比较简单的概念. 但是, 在实践中对网页进行布局时, 它会造成很多混淆. 简单地说, 当两个或更多垂直外边距相遇时, 它们将形成一个外边距. 这个外边距的高度等于两个发生重叠的外边距的高度中的较大值.
1.3. 1 margin 重叠特性
只有普通文档流中的块框的垂直外边距才会发生外边距叠加(不包括 float 框和 absolute 框以及行内框)
不考虑 writing-mode, 只发生在垂直方向(margin-top/margin-bottom)
1.3.2 margin 重叠的 3 种情境
margin 重叠 3 种情境:
相邻的兄弟元素
父级和第一个 / 最后一个子元素
margin-top 重叠其他条件
父元素非块状格式化上下文元素
父元素没有 border-top/padding-top 设置
父元素和第一个子元素之间没有 inline 元素分隔
margin-bottom 重叠其他条件
父元素非块状格式化上下文元素
父元素没有 border-bottom/padding-bottom 值
父元素和最后一个子元素之间没有 inline 元素分隔
父元素没有 height,min-height 限制
干掉 margin-top 重叠
在父元素加属性, overflow:hidden;
父元素设置 border-top/padding-top 值
父元素与第一个子元素之间插入 inline 元素, 如空格
干掉 margin-bottom 重叠
在父元素加属性, overflow:hidden;
父元素设置 border-bottom/padding-bottom 值
设置 height 相关声明(min-height 以及 height.max-height 不起作用)
空的 block 元素(自己的上下外边距叠加)
重叠其他条件
元素不能有 border/padding 值
里面没有 inline 元素
没有 height, 或者 min-height
1.3.3 margin 重叠计算规则
正正取大值
正负值相加
负负最负值
1.3.4 margin 重叠的意义
连续段落或列表之类, 如果没有 margin 重叠, 首尾项间距会和其他兄弟标签 1:2 关系, 排版不自然
Web 种任何地方嵌套或直接放入任何裸 div, 都不会影响原来的布局
遗落的空任意多个 p 元素, 不会影响原来的阅读排版
1.4 margin auto
作用机制: 自动填充元素占据空间的剩余空间, 可利用其实现水平居中:
- div{
- width:300px;
- margin:0 auto;
- }
注意: margin 实现居中, 必须计算后的距离不能是负值.
margin 如何实现垂直布局?
改变流(但水品不再居中)
- .father{
- height:200px; width:100%; writing-mode:vertical-lr;
- }
- .son {
- height:100px; width:500px; margin:auto;
- }
2. 绝对元素的 margin:auto 居中(IE8+)
- .father{ height:200px; position:relative;}
- .son{ position:absolute; top:0; right: 0; bottom:0; left:0;
- width:500px; height:100px; margin:auto;}
1.6 CSS margin 失效情形
1.inline 水平元素的垂直 margin 无效
前提:
非替换元素(如 img)
正常书写模式
2.margin 重叠
3.display:table-cell 与 margin
margin 可应用于所有元素, 除了 diplay 为 table 相关类型 (不包括 table-caption,table 以及 inline-table) 的所有. 甚至可应用于::first-letter
4. 绝对定位元素非定位方向的 margin 值 "无效"
绝对定位元素的 margin 值一直有效, 但由于设置了绝对定位, 脱离了文档流, 所以看不出效果.
5. 鞭长莫及导致 margin 无效, 一些情况下, 如浮动时, margin 无效可能是不够大.
6. 内联特性导致 margin 无效, 例如对于图片, 使用 margin 的负值定位, 不会出现在容器之外.
1.7 了解 margin-start/margin-end 属性
Chrome/Firefox 目前支持该属性, IE 不支持
margin-start
正常流向 margin-start 与 margin-left 等效, 两者重叠不累加.
如果水平流是从右往左, margin-start 等同于 margin-right;
在垂直流下(writing-mode:vertical-*),margin-start 等同于 margin-top;
margin-end
正常流向 margin-end 与 margin-right 等效, 两者重叠不累加.
如果水平流是从右往左, margin-end 等同于 margin-left;
在垂直流下(writing-mode:vertical-*),margin-end 等同于 margin-bottom;
4. border
4.1 border-width 不支持百分比
盒子模型种, padding,margin 都支持百分比, 但是 border, 即边框宽度不支持百分比; 来自张鑫旭大神的理解: border-width 不支持百分比是由于其语义限制, 因为可以看到平板和手机两个不同显示大小的边框大小并不根据元素长宽变化而变化.
4.2 了解各种 border-style 类型
- solid (实线)
- dashed (虚线)
在 Chrome/Firefox 中, 虚线边框的宽高为 3:1,IE 为 2:1.
dotted(点线)
在 Chrome/Firefox 中, 点的形状为方形, IE 为圆形.
double(双实线)
双线宽度相等, 中间空白间隔 $\pm$1
inset(内凹)
4.3 border-color 与 color
border-color 默认继承自 color, 即未指定 color 时 border-color 与 color 一样. 类似的还有 box-shadow,text-shadow,outline.
5. padding
5.1 padding 与容器尺寸
当 width auto 或者 box-sizing 为 border-box, 但是 padding 大小超过宽高时, padding 会影响元素尺寸.
对于 block 元素:
padding 值暴走, 一定会影响尺寸
width 非 auto,padding 影响尺寸
witdh 为 auto 或 box-sizing 为 border-box 时, 同时 padding 值未暴走, 不影响元素尺寸.
对于内联元素:
水平 padding 影响尺寸, 垂直 padding 不影响尺寸. 但会影响背景色.
5.2 padding 负值与百分比值
padding 不支持任何负值, padding 的百分比相对于宽度计算.
inline 元素的百分比值
同样相对于宽度计算
padding 会断行
默认的高度宽度细节差异
空 inline 元素 + padding 高端也不等. 是由于 inline 元素的垂直 padding 会让 "幽灵空白节点" 显现, 也就是规范中的 "strut" 出现. 这时通过设置 font-size:0 规避
span{padding:50%;font-size:0;}
5.3 标签元素内置 padding
button 表单按钮设置 padding:0,Chrome 是 ok 的, 但是在 Firefox 中左右依然会有 padding, 通过设置属性 - moz-focus-inner 规避; IE 浏览器中, IE7 文字越多左右 padding 逐渐变大, 通过 overflow 属性设置规避.
- button::-moz-focus-inner {
- padding:0;
- }
- button{padding:0;overflow:visible;}
对于 button,padding 与高度计算不兼容, 所以一般通过 label 标签实现 button, 而 button 通过绝对定位到页面之外或者 z-index 隐藏在页面下方.
- <button id="btn"></button>
- <label for="btn">按钮</label>
- label{
- display:inline-block;
- line-height:20px;
- padding:10px;
- }
来源: https://www.cnblogs.com/rainbowly/p/12843543.html