Web前端养成记—记录与总结(CSS布局、浏览器兼容问题)
@(問津書院-原创)[css布局, 常见的一些浏览器兼容问题, 总结记录]
CSS Box Model (盒子模型)
盒子模型概念
- 盒子模型 = 网页布局的基石,由四个部分组成:
- 盒子模型分为box-sizing(IE6盒子模型)与W3C盒子模型
- 文档中的每个元素被描绘为矩形盒子。
盒子的四个边界
- 外边距边界:
margin
- 边框边界:
border
- 内边距边界:
padding
- 内容边界:
content
盒子模型结构图:
图片来源:慕课网
注:各个层叠加后也就形成了我们所看到的盒子模型的平面结构图
盒子模型的计算方式
盒子的宽高计算方式
-
盒子尺寸 =
border
+margin
+padding
+content
-
盒子宽度 =
margin-left
+border-left
+padding-left
+content(width)
+padding-right
+border-right
+margin-right
-
盒子高度 =
margin-top
+border-top
+padding-top
+content(height)
+padding-bottom
+border-bottom
+margin-bottom
W3C盒子模型计算方式
- content-box:
padding
和border
不被包含在定义的width
和height
之内。对象的实际宽度等于设置的width
值和border
、padding
之和。
IE6盒子模型计算方式
- border-box:
padding
和border
被包含在定义的width
和height
之内。对象的实际宽度就等于设置的width
值。
padding/margin
按百分比设置的计算方式
- 当
margin/padding
取形式为百分比的值时,无论是left/right
,还是top/bottom
,都是以父元素的width值为参照物来计算
注:CSS3中有个box-sizing属性可以控制盒子的计算方式
padding和margin的使用技巧
-
如果为一个盒子设置了
border
,margin
或者padding
,而又不想改变整个盒子在页面当中所占的总尺寸,那么可以改变盒子的content
的大小。 -
在能用
padding
的情况下,尽量不用margin
,用margin
时尽量只设置一个方向的margin
盒子模型的3D模型立体图
第一层:border /* 边框 */
第二层: content+padding /* 内容和内填充 */
第三层: background-image /* 背景图像 */
第四层:background-color /* 背景颜色 */
最后一层:margin /* 外边距 */
负margin值
-
margin-bottom
负值不能改变当前容器的位置,但是可以在下方为相邻的容器腾出布局空间;相当于为下一个容器设置了margin-top
的负值; -
容器定宽时:
margin-right
失效;margin-top
能把容器提升,不影响父级容器 -
容器不定宽时:
margin-left
和margin-right
都起作用能把容器拉宽,单独使用时可以向对应方向拉宽容器;margin-top
,margin-top
能把容器提升,同时也会把父级容器提升
关于负margin
介绍的几篇文章:
标准文档流是啥?
标准文档流的概念:文档流也叫普通流,是指由
自上而下
,从左到右
,输出的文档内容 (就像水一样从高到低),标准文档流是由块级元素(Block Elements)和行级元素(Inline Elements)共同组成。
元素定位布局后的文档流呈现方式:
-
float
后的元素不占文档流,只是文档流会围绕浮动的东西 -
relative
的元素仍然占据文档流 ,如果定位不好它会覆盖已有的东西(设置relative/absolute
后可设置z-index
属性来进行层叠优先级。) -
absolute
的元素不占文档流,会忽略文档流的存在而浮在已有东西的上面。
一个div容器是文档流,假设里面有(2个浮动子元素div(高各占100px)),如果不加以对浮动元素影响的处理,使用overflow
处理浮动元素或其他处理方法。因为你的东西在两个浮动的div里,这时再接个主div2,那它是出现在div1的下面,而不是在100px下,在ie浏览器下会自动扩大高度,但其他浏览器不会。
HTML结构:
<div class="one">
<div class="child">child-01</div>
<div class="child">child-02</div>
</div>
<div class="two">two text.</div>
CSS代码:
* {
margin: 0;
padding: 0;
}
body {
color: #fff;
}
.one {
background: #168bc1;
}
.child {
float: left;
width: 100px;
height: 100px;
line-height: 100px;
margin-right: 5px;
text-align: center;
background: #35c4e2;
}
.two {
line-height: 100px;
height: 100px;
background: #a5bbbd;
}
截图效果显示:
如下图所示,div.one
下的两个子元素div.child
使用float:left;
后脱离了标准文档流,使得div.one
的高度无法正常扩展,div.two
挤到上面去了
解决方案
div.one
容器设置overflow: hidden;
div.one
容器固定高度,div.two
容器设置clear: both;
属性- 给
div.one
容器添加清除浮动的公共类.clearfix
关于清除浮动的样式
/* clearfix */
.clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; }
* html .clearfix { zoom: 1; } /* IE6 */
*:first-child+html .clearfix { zoom: 1; } /* IE7 */
.clear { clear:both; height:0px; line-height: 0; font-size: 0; overflow: hidden; zoom:1; }
想了解更多有关于清除浮动知识的可阅读CSS大神@一丝的文章那些年我们一起清除过的浮动
常见的一些问题与解决方案
ie浏览器下的兼容性问题
问题产生: ie浏览器在兼容模式下存在很多兼容性问题,为了不让IE低版本(6、7)在兼容模式下进行渲染需要做一些兼容处理
使用JavaScript
代码查看浏览器的UA:
在浏览器地址栏敲入:javascript:alert(navigator.userAgent);
解决方案:
在head
部分添加代码:
<!-- 防止IE以兼容模式进行渲染 -->
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
防止360安全浏览器兼容模式文档模式以IE7标准渲染
同理在head
部分添加代码:
<meta http-equiv="X-UA-Compatible" content="IE=edge">
文字排版样式
单行文本截断带省略号
overflow: hidden; /* 隐藏超出部分内容 */
text-overflow: ellipsis; /* 文本溢出时显示省略号标记 */
white-space: nowrap; /* 强制不换行 */
连续字符自动换行
overflow: hidden;
word-wrap: break-word; /* 在长单词或 URL 地址内部进行换行。 */
字、字母、字符等间距
letter-spacing /* 设置英文字母和中文字体之间的间距 */
单词间距
word-spacing /* 设置英文单词之间的间距 */
文本开头缩进距离
text-indent /* 设置开头缩进 */
行距、行高
line-height /* 设置行高、行内距 */
:first-letter
和:first-line
伪元素
:first-letter /* 设置元素中第一个字母的样式 */
:first-line /* 设置元素的首行样式 */
都只对块级元素生效
:first-letter
和:first-line
伪元素在ie6下不兼容问题
在:first-letter
/:first-line
和 {
之间留空格
代码如下:
p:first-line {
color: red;
}
p:first-letter {
font-size: 20px;
}
IE10浏览器后输入框后面的小叉
input::-ms-clear {
display: none;
}
input::ms-reveal {
display:none;
}
需求:
如何在列表项在缩小浏览器窗口比例的时,不会撑破容器的宽度,并排显示,根据浏览器窗口的比例进行缩放如下例子:
HTML 结构:
<ul class="row clearfix">
<li>
<div class="col-01">col-01</div>
</li>
<li>
<div class="col-02">col-02</div>
</li>
<li>
<div class="col-03">col-03</div>
</li>
<li>
<div class="col-04">col-04</div>
</li>
</ul>
CSS 代码:
* {
margin: 0;
padding: 0;
}
ul {
list-style: none;
}
.row {
width: 100%;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
margin-left: 10px !important;
margin-right: 10px !important;
}
.row li {
float: left;
width: 23%;
height: 250px;
line-height: 250px;
text-align: center;
color: #fff;
padding: 0 5px;
}
.col:first-child {
padding-left: 0;
}
.col-01 {
background: #3fb4d4;
}
.col-02 {
background: #b9b4d8;
}
.col-03 {
background: #24dac2;
}
.col-04 {
background: #78b2b6;
}
.clearfix:after {
display: block;
content: " ";
line-height: 0;
font-size: 0;
clear: both;
visibility: hidden;
*zoom: 1;
}
截图效果:
实现原理:
使用CSS3 box-sizing:border-box 属性
缺点:
不兼容IE8以下版本的浏览器
checkbox与radio在PC页面对齐问题
问题产生:
input[type="radio"]
和input[type="checkbox"]
在12像素大小的文字,Firefox火狐浏览器及chrome谷歌浏览器会存在对齐问题
解决方案1:
以vertical-align: middle;
为基础
input[type="radio"],
input[type="checkbox"] {
vertical-align: middle;
margin-top: -2px;
margin-bottom: 1px
}
解决方案2:
以vertical-align: bottom;
为基础
input[type="radio"],
input[type="checkbox"] {
height: 15px;
vertical-align: bottom;
margin-bottom: 3px;
margin-top: -1px;
}
select高度计算问题
问题产生:原生<select>
下拉菜单会自带box-sizing: border-box;
属性,在计算盒子的宽高时不计入padding/border的值
HTML代码:
<select class="select">
<option value="">1</option>
<option value="">2</option>
<option value="">3</option>
<option value="">4</option>
<option value="">5</option>
</select>
CSS代码:
.select {
height: 26px;
padding: 3px 5px;
border: 1px solid #a2a2a2;
}
解决方案1:
给<select>
设置box-sizing: content-box;
属性改变盒子模型,以W3C盒子模型来计算
.select {
-moz-box-sizing: content-box; /* For Firefox */
-webkit-box-sizing: content-box; /* Chrome and Safari */
box-sizing: content-box;
}
缺点:不兼容IE8以下的浏览器
解决方案2:
使用JQ插件改变<select>
下拉菜单
input[type="text"]
表单控件双magin
问题:
问题产生:
在IE7下,input
(不包含type="checkbox"
类型标签)的父元素如有加水平方向的margin
,则水平方向的margin
会成双倍显示
解决方案:
给父元素的水平
margin
改成padding
,直接避开ie6、7这个margin双倍bug
和IE6下的双margin一样,加
float: left
;*display: inline
使用img标签的背景图显示带来的border问题
问题产生: 当使用空img
标签的不使用src属性作为引入图片路径,且CSS改变img
标签的宽高情况下,始终都会有边框线存在。
产生原因: img
标签没有设置src
属性,显示的是系统的没有图片的边框标记
截图显示:
解决方案:
- 1、给img标签的src属性加一张纯透明图来遮住边框效果
- 2、使用别的标签替换掉
img
,比如:span
标签
元素position: absolute后带来的影响
问题产生:
元素position: absolute;
,父元素高度塌陷
注:(元素absolute后脱离了文档流,父元素的高度无法正常扩展)
HTML代码:
<div class="wrap">
<div class="child"></div>
</div>
CSS代码:
.child {
position: absolute;
width: 100px;
height: 100px;
top: 0;
left: 0;
background-color: #a8a8a8;
}
解决方案1:
给父元素固定height
解决方案2:
在父元素中插入img
标签来占位,通过CSS
来设置height
撑开父元素的高度,使其在不同宽度设备上保持宽高比,具体代码如下:
HTML代码:
<div class="wrap">
<div class="child"></div>
<img src="..." class="placeholder">
</div>
如何让页脚始终紧贴页面底部
问题产生: 当页面内容的高度小于浏览器高度时,视口底部就是一片尴尬的空白,如图所示:
HTML DOM结构:
div.container > div.header + div.content + div.footer
如下图:
解决方案1:
- 给
html
和body
标签中将高度(height
)设置为“100%” - 同时需要将
html,body
的margin
和padding
都移除,既html,body
的margin
和padding
都为0 div#container
容器必须设置一个最小高度(min-height
)为100%;主要使他在内容很少(或没有内容)情况下,能保持100%的高度- 在IE6下是不支持
min-height
的,需要做兼容处理添加height: auto important!;
height: 100%;
或阅读文章Min-Height Fast Hack - 还需在
div#container
容器中设置一个position:relative
以便于里面的元素进行绝对定位后不会跑了div#container
容器 div#content
这个容器有一个很关键的设置,需要在这个容器上设置一个padding-bottom
值,而且这个值要等于(或略大于)页脚div#footer
的高度(height
)值div#footer
容器必须设置一个固定高度,单位可以是px
(或em
)。div#footer
还需要进行绝对定位,并且设置bottom:0;
让div#footer
固定在容器div#container
的底部,这样就可以实现我们前面所说的效果,当内容只有一点时,div#footer
固定在屏幕的底部(因为div#container
设置了一个min-height:100%
),当内容高度超过屏幕的高度,div#footer
也固定在div#container
底部,也就是固定在页面的底部。你也可以给div#footer
加设一个”width:100%
“,让他在整个页面上得到延伸。
具体代码如下:
HTML代码:
<div class="container">
<div class="header">Header Section</div>
<div class="content">Test test test test...</div>
<div class="footer">Footer Section</div>
</div>
CSS 代码:
* {
padding: 0;
margin: 0;
}
html,body {
height: 100%;
}
body {
font-size: 1.25em;
color: #fff;
}
.container {
position: relative;
min-height: 100%;
height: auto !important;
height: 100%; /* For IE 6 */
}
.header {
padding: 1em 0;
background: #1671b3;
}
.content {
color: #000;
padding-bottom: 290px;
}
.footer {
position: absolute;
width: 100%;
height: 250px;
bottom: 0;
background: #363636;
}
截图效果:
浏览器兼容性:
经测试在IE6/7/8
、FF
、Chrome
、Safari
、Opera
浏览器下均能友好的兼容
优缺点:
-
优点: 浏览器兼容性好,结构简单清晰,无需
js
和任何hack
都能实现 -
缺点: 必须固定
footer
部分的高度(高度可以根据需求进行设置)和使用绝对定位
,而且还需要将div#content
容器的padding-bottom
设置大小等于(或略大于)div#footer
的高度,才能正常运行。
参考文章:
display: inline-block; 布局带来的问题
问题产生:
block
元素display: inline-block;
后在IE7下无效:可以设置宽高,但还是换行显示
解决方案:
给IE7 加上这两句代码: *display: inline;
*zoom: 1;
问题产生:
display-inline-block;
后带来的间距问题,
给父元素设置font-size: 0;
去除空格
Chrome、Opera、FireFox下没问题
IE8以上font-size: 0;
没问题,但在IE6、7 下inline
元素inline-block
后设置 font-size:0
始终有 1px
的空隙
Safari 5.0 不支持 font-size:0
最终解决方案
.selector {
font-size: 0; /* 所有浏览器 */
letter-spacing: -5px; /* Safari 等不支持字体大小为 0 的浏览器 */
*letter-spacing: normal;
word-spacing: -1px; /* IE6、7 */
}
HTML 代码:
<ul class="nav-lists">
<li><a href="#x">1</a></li>
<li><a href="#x">2</a></li>
<li><a href="#x">3</a></li>
<li><a href="#x">4</a></li>
<li><a href="#x">5</a></li>
</ul>
CSS代码:
* {
margin: 0;
padding: 0;
}
body {
text-align: center;
}
.nav-lists {
padding-top: 50px;
display: inline-block;
list-style: none;
}
.nav-lists {
*display: inline; /* For IE 6/7 */
*zoom: 1; /* For IE 6/7 */
*word-spacing:-1px; /* For IE 6/7 */
font-size: 0; /* All Browser */
}
.nav-lists li {
display: inline-block;
background-color: #a8a8a8;
}
.nav-lists li {
*display: inline; /* For IE 6/7 */
*zoom: 1; /* For IE 6/7 */
}
.nav-lists li a {
display: block;
padding: 2px 5px;
color: #fff;
font-size: 12px;
text-decoration: none;
}
效果截图:
(注:有关于display: inline-block;布局的更多知识可移步淘宝UED的文章 display: inline-block的前世今生 )
CSS背景透明,文字不透明的兼容方法
问题产生::
使用CSS3
做背景透明,文字不透明时在IE6,7,8下存在兼容问题
解决方案:
HTML代码:
<div class="demo">
<p>背景透明,文字不透明</p>
</div>
CSS代码:
* {
padding: 0;
margin: 0;
}
body {
padding: 50px;
background: url(../img/body_bg.png) repeat 0 0;
}
.demo {
padding: 25px;
text-align: center;
background: rgba(000,000,000,0.5); /* IE9、标准浏览器、IE6和部分IE7内核的浏览器(如QQ浏览器)会读懂 */
}
.demo p {
color: #fff;
}
@media \0screen,screen\9 { /* 只支持IE6、7、8 */
.demo {
position: static; /* IE6、7、8只能设置position: static;(默认属性),否则会导致子元素继承Alpha值 */
background-color: #000;
filter: Alpha(opacity=50);
*zoom: 1; /* 激活IE6、7的haslayout属性,让它读懂Alpha */
}
.demo p {
position: relative; /* 设置子元素为相对定位,可让子元素不继承Alpha值 */
}
}
【display: none;
和visibility:hidden;
之间的区别】
-
display: none; —— 是将元素设置为无,在网页中不占据任何位置
-
visibility: hidden;—— 将元素隐藏,在网页中还占据了原来的位置。
使用rem单位带来的问题
rem单位在chrome浏览器下的line-height问题
问题产生:在PC端使用rem作为单位在chrome浏览器下,给根元素(html
)设置了font-size: 62.5%;
(10px),当计算font-size: 1rem;
是10px没问题,但是line-height
还是基于chrome的最小字号12px来计算的,也就是line-height=1rem=24px
解决方案:
1.给
html
元素设置font-size: 100px;
body
设置font-size: 12px;
计算rem单位的百分比时:number px/100px
(html
元素的大小)=rem值
2.PC端改用px、em作为常用单位不推荐使用rem作为常用单位(一是PC端存在兼容性问题,第二是PC端大部分是固定宽度的页面,不需要做大小适配,用rem计算。会产生很多小数点的东西,移动端下推荐使用)
HTML代码:
<body>
<p>rem单位在chrome浏览器下的line-height问题<p>
</body>
CSS代码:
* {
margin: 0;
padding: 0;
}
html {
font-size: 100px;
}
body {
font-size: 12px;
}
p {
font-size: 12px;
font-size: 0.12rem; /* 0.12rem = 12px/100px */
line-height: 0.2rem; /* 0.2rem = 20px/ 100px */
}
截图效果:
关于我
一个前端爱好者,一个誓死不脱离低级趣味的人,一個庸俗的人,偶尔会装逼。
欢迎各路看官一起深(tan)入(xiao)交(feng)流(sheng)。
联系邮箱: moldy_bread@foxmail.com
特别鸣谢
在这里特别感谢下问津书院的两位领导@校董大人 @院长大人的极力帮助,对本人提出的问题进行耐心解答,并给出了不同的优秀解决方案,在两位大神的带领下涨了好多姿势。
本文PDF下载:Web前端养成记—记录与总结(CSS布局、浏览器兼容问题)