Future Friendly College

問津書院

Web前端养成记 记录与总结(css布局、浏览器兼容问题)

Web前端养成记—记录与总结(CSS布局、浏览器兼容问题)

@(問津書院-原创)[css布局, 常见的一些浏览器兼容问题, 总结记录]

CSS Box Model (盒子模型)

盒子模型概念

盒子的四个边界

  • 外边距边界:margin
  • 边框边界:border
  • 内边距边界:padding
  • 内容边界:content

盒子模型结构图:

Web前端养成记

图片来源:慕课网

注:各个层叠加后也就形成了我们所看到的盒子模型的平面结构图

盒子模型的计算方式

盒子的宽高计算方式

  • 盒子尺寸 = 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-boxpaddingborder不被包含在定义的widthheight之内。对象的实际宽度等于设置的width值和borderpadding之和。

IE6盒子模型计算方式

  • border-box:paddingborder被包含在定义的widthheight之内。对象的实际宽度就等于设置的width值。

padding/margin按百分比设置的计算方式

  • margin/padding取形式为百分比的值时,无论是left/right,还是top/bottom,都是以父元素的width值为参照物来计算

注:CSS3中有个box-sizing属性可以控制盒子的计算方式

padding和margin的使用技巧

  • 如果为一个盒子设置了bordermargin或者padding,而又不想改变整个盒子在页面当中所占的总尺寸,那么可以改变盒子的content的大小。

  • 在能用padding的情况下,尽量不用margin,用margin时尽量只设置一个方向的margin

盒子模型的3D模型立体图

第一层:border                   /*  边框 */
第二层: content+padding        /* 内容和内填充 */
第三层: background-image      /* 背景图像 */
第四层:background-color      /* 背景颜色 */
最后一层:margin             /* 外边距 */

Web前端养成记

负margin值

  • margin-bottom负值不能改变当前容器的位置,但是可以在下方为相邻的容器腾出布局空间;相当于为下一个容器设置了margin-top的负值;

  • 容器定宽时:margin-right失效;margin-top能把容器提升,不影响父级容器

  • 容器不定宽时:margin-leftmargin-right都起作用能把容器拉宽,单独使用时可以向对应方向拉宽容器;margin-topmargin-top能把容器提升,同时也会把父级容器提升

关于负margin介绍的几篇文章:


标准文档流是啥?

标准文档流的概念:文档流也叫普通流,是指由自上而下从左到右,输出的文档内容 (就像水一样从高到低),标准文档流是由块级元素(Block Elements)行级元素(Inline Elements)共同组成。

元素定位布局后的文档流呈现方式:

  • float后的元素不占文档流,只是文档流会围绕浮动的东西

  • relative的元素仍然占据文档流 ,如果定位不好它会覆盖已有的东西(设置relative/absolute后可设置z-index属性来进行层叠优先级。)

  • absolute的元素不占文档流,会忽略文档流的存在而浮在已有东西的上面。

Web前端养成记

一个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挤到上面去了

解决方案

  1. div.one 容器设置 overflow: hidden;
  2. div.one容器固定高度,div.two 容器设置clear: both;属性
  3. 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;
}

截图效果:

Web前端养成记

实现原理:

使用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,直接避开ie67这个margin双倍bug

IE6下的双margin一样,加float: left; *display: inline


使用img标签的背景图显示带来的border问题

问题产生: 当使用空img标签的不使用src属性作为引入图片路径,且CSS改变img标签的宽高情况下,始终都会有边框线存在。

产生原因: img标签没有设置src属性,显示的是系统的没有图片的边框标记

截图显示:

Web前端养成记

解决方案:

  • 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

如下图:

Web前端养成记

解决方案1:

  • htmlbody标签中将高度(height)设置为“100%
  • 同时需要将html,bodymarginpadding都移除,既html,bodymarginpadding都为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;
}

截图效果:

Web前端养成记

浏览器兼容性

经测试在IE6/7/8FFChromeSafariOpera浏览器下均能友好的兼容

优缺点:

  • 优点: 浏览器兼容性好,结构简单清晰,无需js和任何hack都能实现

  • 缺点: 必须固定footer部分的高度(高度可以根据需求进行设置)和使用绝对定位,而且还需要将div#content容器的padding-bottom设置大小等于(或略大于)div#footer的高度,才能正常运行。

参考文章:

  1. [译]如何将页脚固定在页面底部

  2. [原文]如何将页脚固定在页面底部


display: inline-block; 布局带来的问题

问题产生:

block元素display: inline-block;后在IE7下无效:可以设置宽高,但还是换行显示

解决方案:

IE7 加上这两句代码: *display: inline; *zoom: 1;

问题产生:

display-inline-block;后带来的间距问题,

给父元素设置font-size: 0; 去除空格

ChromeOperaFireFox下没问题

IE8以上font-size: 0;没问题,但在IE67inline元素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;
}

效果截图:

Web前端养成记

(注:有关于display: inline-block;布局的更多知识可移步淘宝UED的文章 display: inline-block的前世今生


CSS背景透明,文字不透明的兼容方法

问题产生:

使用CSS3做背景透明,文字不透明时在IE678下存在兼容问题

解决方案:

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端改用pxem作为常用单位不推荐使用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 */
}

截图效果:

Web前端养成记


关于我

一个前端爱好者,一个誓死不脱离低级趣味的人,一個庸俗的人,偶尔会装逼。

欢迎各路看官一起深(tan)入(xiao)交(feng)流(sheng)。

联系邮箱: moldy_bread@foxmail.com

特别鸣谢

在这里特别感谢下问津书院的两位领导@校董大人 @院长大人的极力帮助,对本人提出的问题进行耐心解答,并给出了不同的优秀解决方案,在两位大神的带领下涨了好多姿势。

本文PDF下载:Web前端养成记—记录与总结(CSS布局、浏览器兼容问题)

微信公眾號

Wechat QRcode

Github: futurefriendly

Twitter: futurefriendly

3290454918@qq.com

Future Friendly & 問津書院