代码改变世界

尖刀出鞘的display常用属性及css盒模型深入研究

2014-12-13 18:49  龙恩0707  阅读(...)  评论(... 编辑 收藏

一:diplay:inline-block

     含义:指元素创建了一个行级的块级元素,该元素内部(内容)被格式化成一个块级元素,同时元素本身则被格式化成一个行内元素。更简单的说就是说inline-block后的元素具有block元素可以设置宽高特性,同时又具有inline元素默认不换行的特性。

     其实display:inline-block这个属性现在浏览器都支持,其实IE从5.5开始就已经支持了,但是IE6,7支持的还不够完善,我们可以先来做demo测试下就可以明白。为了做demo,所以我们现在需要如下HTML结构,且下面做的demo都是这个HTML结构,如下代码:

// 块级子元素li
<ul class="list">
    <li>首页</li>
    <li>鲜锋官</li>
    <li>合作商家</li>
</ul>
// 行内元素a标签
<div class="list">
    <a href="#">首页</a>
    <a href="#">先锋官</a>
    <a href="#">合作商家</a>
</div>
Reset.css贴代码如下:
body,h1,h2,h3,h4,h5,h6,hr,p,blockquote,dl,dt,dd,ul,ol,li,pre,form,fieldset,legend,button,input,textarea,th,td{margin:0;padding:0;}
ul,ol{list-style:none;}
body{font-size:12px;font-family:"Microsoft yahei";}
a{text-decoration:none;}

上面的reset.css代码不管他们,我先添加如下css样式,代码如下:

.list { width:700px; margin:100px auto 0; }

.list li{ display:inline-block; width:198px; height:30px; line-height:30px; text-align:center;border:1px solid #000; }

.list a{ display:inline-block; width:198px; height:30px; line-height:30px; text-align:center;border:1px solid #000;}

注意:如下所说的标准浏览器指:ie8+ , firefox , chrome, opera, safari等。

   1. 如下标准浏览器下,添加display:inline-block表现形式;

    

   2. IE6,7浏览器下,添加display:inline-block表现形式如下:

   

  测试表明:IE6,7下块级元素li添加了display:inline-block后,也不能使inline-block元素不换行的特性。想要块级元素在IE6,7下支持像inline-block不换行特性,可以在块级元素li下 再添加2句代码针对IE6,7的代码,如下:

         .list li{

              *display:inline;

              *zoom:1;

          }

    就可以实现display:inline-block的特性了,如下截图演示:

   

含义是:首先让块级元素转化为inline元素,强制不换行,然后通过zoom:1触发haslayout,使其可以设置宽和高。

综合以上可知:标准浏览器都支持display:inline-block; IE6,7下添加*display:inline和*zoom:1也可以表现为inline-block的形式了,代码如下:

.list li{ display:inline-block; *display:inline; width:198px; height:30px; line-height:30px; text-align:center;border:1px solid #000; *zoom:1;}

  使用display: inline-block后元素之间会产生间隙,如下所示:

 1.   在标准浏览器下,如下效果:

  

 2.   IE6,7下,如下效果:

     

可以看到都有间隙,我们有可能想到是不是空白符等影响的呢?我们继续来看,我们现在在代码中把HTML代码改成如下,去掉空白符和换行符,如下:

<ul class="list"><li>首页</li><li>鲜锋官</li><li>合作商家</li></ul>

<div class="list"><a href="#">首页</a><a href="#">先锋官</a><a href="#">合作商家</a></div>

在标准浏览下和IE6,7下预览效果如下:

由此我们得出结论:产生空隙的原因是换行符或者回车符 或者 2者组合会产生如上面的空隙,接下来我们该如何解决这个空隙呢?

3.  去掉display:inline-block之间的空隙。

      HTML中的换行符,空格符,制表符等产生了空白符,而这些归根结低都是字符,那么他们的大小有可能会受font-size来限制,我们继续做demo尝试下:

   需要在父级元素上添加font-size,为了不影响子元素的font-size,我们先在子元素.list li {font-size:12px}和 .list a{font-size:12px}来覆盖父级元素的font-size,如下:

   当我不断的改变.list的font-size大小时候,超过12px后,间隙会不段的变大,当小于12px的时候会有如上间隙,但是当font-size:0的时候,就没有间隙了,看似世界一切都变得越来越好了,但是如下:

   产生问题:

   1. Safari5不支持font-size:0

   2. IE6,7下依旧有1px的空隙,如下:

现在我们再来解决如上2个问题吧!通过查资料,我们看到letter-spacing 和 word-spacing 2个可以解决空白符的问题。

1. Letter-spacing:

    即w3c定义:letter-spacing 属性增加或减少字符间的空白(字符间距)。该属性定义了在文本字符框之间插入多少空间。由于字符字形通常比其字符框要窄,指定长度值时,会调整字母之间通常的间隔。因此,normal 就相当于值为 0。

可能的值如下:

 值  描述
 normal  默认。规定字符间没有额外的空间。
 length  定义字符间的固定空间(允许使用负值)。
 inherit  规定应该从父元素继承 letter-spacing 属性的值。

下面我们先来解决safari下不支持font-size,我们可以通过letter-spacing属性来解决,它支持负值的,但是具体值多少呢?我们通过资料及做demo得知:inline-block产生的空隙与父级元素继承或者设定的font-family,font-size有关,下面各个字体详细情况如下连接:

http://www.iyunlu.com/view/css-xhtml/58.html

我这边css样式是:body{font-size:12px;font-family:"Microsoft yahei";}

由上表得知最后一行 可以设置 -4px,但是通过我们实践得知需要-5px,可以满足我们的需求,所以我们针对safari不支持font-size:0的情况下 添加letter-spacing属性即可;如下代码:

.list li{display:inline-block;*display:inline;width:198px;height:30px;line-height:30px;font-size:12px; text-align:center;border:1px solid #000;*zoom:1;letter-spacing:normal;}
.list a{display:inline-block;width:198px;height:30px;line-height:30px;font-size:12px;text-align:center;border:1px solid #000;letter-spacing:normal;}
@media screen and (-webkit-min-device-pixel-ratio:0){
    .list{
        letter-spacing:-5px;   //Safari 等不支持字体大小为 0 的浏览器, N 根据父级字体调节
    }
}

就可以解决safari的bug了。如上在父级元素上使用 letter-spacing:-5px,为了不影响子元素需要在子元素重新设置值回默认值:即如上:

.list li {letter-spacing:normal} 和 .list a{letter-spacing:normal }

2. 使用*word-spacing:-1px; 解决IE6,7下产生的1px间隙bug,如下在父级元素多添加如下代码

.list{ *word-spacing:-1px; }

同样为了使子元素不受影响 需要添加word-spacing的默认值;如下:

.list li{ *word-spacing:normal;}  .list a { *word-spacing:normal;}

综合所有的css代码如下:

.list{

       width:700px;

       margin:100px auto 0;

       font-size:0px;

       *word-spacing:-1px;

}

.list li{

       display:inline-block;

       width:198px;

       height:30px;

       line-height:30px;

       text-align:center;

       border:1px solid #000;

       *display:inline;

       *zoom:1;

       font-size:12px;

       letter-spacing:normal;

       *word-spacing:normal;

}

.list a{

       display:inline-block;

       width:198px;

       height:30px;

       line-height:30px;

       text-align:center;

       border:1px solid #000;

       font-size:12px;

       letter-spacing:normal;

       *word-spacing:normal;

}

@media screen and (-webkit-min-device-pixel-ratio:0){

       .list{

              letter-spacing:-5px; //Safari 等不支持字体大小为 0 的浏览器, N 根据父级字体调节

       }

}

二:display:table-cell

  含义:让标签元素以表格单元格的形式呈现。类似于td标签。

  display: table-cell 目前IE8+浏览器都支持,IE6,7不支持,我们都知道单元格有一些特别的属性,比如图片垂直居中,文字垂直居中等。但是display:table-cell不能与float:left或者position:absolute属性等同用。对margin值无反应,支持padding属性。

  比如如下代码:

  HTML标签如下:

  <ul>

              <li class="table-cell">

                     <img src = "1.jpg" width = '220px' height="260px"/>

              </li>

              <li class="table-cell">

                     <img src = "1.jpg" width = '220px' height="260px"/>

              </li>

</ul>

Css代码如下:

.table-cell {

       display:table-cell;width:400px;height:400px; border:1px solid #beceeb; text-align:center; vertical-align:middle;

}

.table-cell img{vertical-align:middle;}

可以看到如下演示:

图片垂直居中了,如果上面的.table-cell 添加float:left或者 position:absolute属性后,图片就不会垂直居中了,且如果对.table-cell添加margin不会有任何反应,添加padding就可以生效,比如padding-top等。

display:table-cell与2栏自适应布局;

  比如实现如下效果:

左右侧宽度不固定,自适应大小效果如上,代码如下:

HTML代码:

<div class="box">

       <a href="#"><img border="0" src="1.jpg"/></a>

       <div class="content">

              <p>大美女一枚来自上海</p>

              <p>签名:想找个保鲜盒把你给我的那些感动都装起来。当你让我伤心的时候就拿出来回味一下。</p>

              <p>微博:坐在办公室,只听轰隆隆几声巨响,晴天也能打雷吗?原来街对面的芭莎咖啡厅被炸成了两截。这定点爆破也太失败了,也不清下场,把路过的汽车震得灰头土脸,愣在路中央不知如何是好。其次,房子只炸了一半,另一半屹立不倒,是乍药太水还是房子质量太好?</p>

      </div>

</div>

Css代码如下:

.box{width:40%; margin:60px auto 0; padding:20px; background:#f5f5f5;border:1px solid #ccc;overflow:hidden;}

a{float:left;margin-right:10px;}

.content{display:table-cell; *display:inline-block;font-size:14px;}

IE6,7不支持display:table-cell,使用*display:inline-block解决即可,原因如上介绍的display:inline-block;

三:display:inline-table

  1. 浏览器支持程度:safari,opera,chrome,firefox,IE8+浏览器支持。

    含义:使行内元素与块级元素在同一行显示。

          <span>你好</span>

          <div>kkkk</div>

          <table>

                 <tr>

                        <td>A</td>

                        <td>B</td>

                        <td>C</td>

                        <td>D</td>

                        <td>E</td>

                 </tr>

                 <tr>

                        <td>F</td>

                        <td>G</td>

                        <td>H</td>

                        <td>I</td>

                        <td>J</td>

                 </tr>

                 <tr>

                        <td>K</td>

                        <td>L</td>

                        <td>M</td>

                        <td>N</td>

                        <td>Q</td>

                 </tr>

          </table>

          <span>你好</span>

以上,由于div和table是块级元素,按道理div和table会独占一行,但是当我们给div和table分别加了 display:inline-table 值后,会在一行内显示,

CSS样式如下:

table {

      border:3px solid #00aaff;

      display: inline-table; 

}

td {

      border:2px solid #ccff00;

      padding:5px;

}

div {display: inline-table;background:red;color:#fff;}

如下图:

但是safari浏览器列外,它会如下显示:

显示在底部,所以我们需要在使用display:inline-table元素上增加一行样式,来对他们是顶部对齐还是居中或者底部对齐,如下代码:

vertical-align:top; // 顶部对齐

如下是在所有支持的浏览器上显示效果;

四:display: list-item类型

含义: 可以将多个元素作为列表来显示,同时在元素的开头加上列表的标记。

如下代码:

HTML:

<div>demo1</div>

<div>demo2</div>

<div>demo3</div>

<div>demo4</div>

CSS如下:

div {

       display: list-item;

       list-style-type:lower-latin;

       margin-left:30px;

}

在页面上显示如下:

 

其中list-style-type在css2.1可选值有如下:

五 :display:box理解

 display: box; box-flex 是css3新添加的盒子模型属性,它可以为我们解决按比列划分,水平均分,及垂直等高等。

        一:按比例划分:

            目前box-flex 属性还没有得到firefox, Opera, chrome浏览器的完全支持,但我们可以使用它们的私有属性定义firefox(-moz-),opera(-o-),chrome/safari(-webkit-)。

        box-flex属性主要让子容器针对父容器的宽度按一定的规则进行划分。

        比如代码如下:

        HTML代码:

        <div class="test">

                  <p id="p1">Hello</p>

                  <p id="p2">W3School</p>

           </div>

       CSS代码:

       .test{

                  display:-moz-box; /* Firefox */

                  display:-webkit-box; /* Safari and Chrome */

                  display:box;

                  width:300px;

           }

           #p1{

                  -moz-box-flex:1.0; /* Firefox */

                  -webkit-box-flex:1.0; /* Safari and Chrome */

                  box-flex:1;

                  border:1px solid red;sss

           }

           #p2{

                  -moz-box-flex:2.0; /* Firefox */

                  -webkit-box-flex:2.0; /* Safari and Chrome */

                  box-flex:2;

                  border:1px solid blue;

           }

   在firefox和chrome浏览器效果如下:

   

注意:

1.   必须给父容器定义 display: box, 其子元素才可以进行划分,如上给id为p1设置box-flex设置为1,给id为p2设置box-flex为2,说明分别给其设置1等分和2等分,也就是说给id为p1元素设置宽度为 300 * 1/3 = 100px; 给id为p2元素设置宽度为 300 * 2/3 = 200px;

2.   如果在父元素定义了 display: box,则说明该父元素为内联元素,如果想要让其居中对齐的话,我们可以在其父元素的最外层定义宽度 然后 margin: o auto 即可,比如代码如下:

HTML代码:

<div class="container">

       <div class="test">

              <p id="p1">Hello</p>

              <p id="p2">W3School</p>

       </div>

</div>

CSS代码:

.container {width:300px;margin:0 auto;}

上面的p1,p2的css代码还是不变。就可以居中对齐了。

3.  如果进行父容器划分的同时,他的子元素有的设置了宽度,有的要进行划分的话,那么划分的宽度 = 父容器的宽度 – 已经设置的宽度 。再进行对应的划分。

比如HTML代码还是这个;

<div class="test">

       <p id="p1">Hello</p>

       <p id="p2">W3School</p>

</div>

效果如下:

六:box属性

具体的属性如下:

  box-orient | box-direction | box-align | box-pack | box-lines

  1.  box-orient;

   box-orient 用来确定父容器里的子容器的排列方式,是水平还是垂直,可选属性如下所示:

   horizontal | vertical | inline-axis | block-axis | inherit

一:horizontal | inline-axis

给box设置 horizontal 或 inline-axis 属性效果表现一致。都可以将子元素进行水平排列,其是对父容器的宽度进行划分,但是

  1. 如果父元素定义了高度值,其子元素也设置了高度值在firefox(33.1.1)和chrome(39.0)下版本下表现不一致,如HTML代码还是上面的:

<div class="test">

        <p id="p1">Hello</p>

        <p id="p2">W3School</p>

</div>

CSS如下:

.test{

        display:-moz-box; /* Firefox */

        display:-webkit-box; /* Safari and Chrome */

        display:box;

        width:300px;

        height:200px;

        -moz-box-orient:horizontal;

        -webkit-box-orient:horizontal;

        box-orient:horizontal; /* 水平排列 */

}

#p1{

        -moz-box-flex:1.0; /* Firefox */

        -webkit-box-flex:1.0; /* Safari and Chrome */

        box-flex:1;

        height:400px;

        border:1px solid red;

       

}

#p2{

        -moz-box-flex:2.0; /* Firefox */

        -webkit-box-flex:2.0; /* Safari and Chrome */

        box-flex:2;

        height:300px;

        border:1px solid blue;

}

在firefox下如下表现效果:

但是在chrome下如下表现效果:

2. 如果父容器没有设置高度值得话,子元素分别有高度值的话,在firefox和chrome渲染的高度还是有差异的,如下css代码父容器的高度值去掉:

那么在firefox下,如下效果:

在chrome下,如下效果:

   如下对父元素的容器css代码如下:

   .test{

              display:-moz-box; /* Firefox */

              display:-webkit-box; /* Safari and Chrome */

              display:box;

              width:300px;

              height:200px;

              -moz-box-orient:vertical;

              -webkit-box-orient:vertical;

              box-orient:vertical; /* 垂直排列 */

       }

   #p1{

              -moz-box-flex:1.0; /* Firefox */

              -webkit-box-flex:1.0; /* Safari and Chrome */

              box-flex:1;

              border:1px solid red;

       }

       #p2{

              -moz-box-flex:2.0; /* Firefox */

              -webkit-box-flex:2.0; /* Safari and Chrome */

              box-flex:2;

              border:1px solid blue;

       }

   子元素都没有设置宽度的话,在firefox 和 chrome 如下:

但是

1. 如果分别给子元素设置了宽度的话,那么firefox和chrome表现效果又不一致了,如下css代码:

在firefox表现效果如下:

在chrome下 表现效果如下:

2. 如果父元素没有设置宽度的话,子元素都设置了自己的宽度的话,那么firefox和chrome表现形式还是会不一样的,如下:

在firefox表现形式如下:

在chrome下表现如下:

三:inherit

Inherit属性让子元素继承父元素的相关属性。

如下css代码:

.test{

       display:-moz-box; /* Firefox */

       display:-webkit-box; /* Safari and Chrome */

       display:box;

       height:200px;

       width:500px;

       -moz-box-orient:inherit;

       -webkit-box-orient:inherit;

        box-orient:inherit; /* 垂直排列 */

  }

  #p1{

         -moz-box-flex:1.0; /* Firefox */

         -webkit-box-flex:1.0; /* Safari and Chrome */

         box-flex:1;

         border:1px solid red;    

    }

    #p2{

         -moz-box-flex:2.0; /* Firefox */

          -webkit-box-flex:2.0; /* Safari and Chrome */

          box-flex:2;

          border:1px solid blue;

    }

   效果如下:

 

2. box-direction

  box-direction 用来确定父容器里的子容器的排列顺序,具体的属性如下代码所示:

normal | reverse | inherit

normal是默认值,按照HTML文档里的结构的先后顺序依次展示,如果box-direction 设置为 normal,则结构顺序还是 id为p1元素,id为p2元素。

reverse: 表示反转。如果设置reverse反转,则结构排列顺序为 id为p2元素,id为p1元素。如下代码:

CSS代码:

.test{

       display:-moz-box; /* Firefox */

       display:-webkit-box; /* Safari and Chrome */

       display:box;

       height:200px;

       width:500px;

       -moz-box-direction:reverse;

       -webkit-box-direction:reverse;

       -box-direction:reverse;

}

如下效果:

3. box-align:

   box-align 表示容器里面字容器的垂直对齐方式,可选参数如下表示:

   start | end | center | baseline | stretch

CSS代码如下:

.test{

        display:-moz-box; /* Firefox */

        display:-webkit-box; /* Safari and Chrome */

        display:box;

        width:500px;

        -moz-box-align:start;

        -webkit-box-align:start;

        box-align:start; /* 垂直排列 */

}

#p1{

        -moz-box-flex:1.0; /* Firefox */

        -webkit-box-flex:1.0; /* Safari and Chrome */

        box-flex:1;

        height:140px;

        border:1px solid red;   

}

#p2{

        -moz-box-flex:2.0; /* Firefox */

        -webkit-box-flex:2.0; /* Safari and Chrome */

        box-flex:2;

        height:120px;

        border:1px solid blue;

}

P1 高度为140px p2 为120px;

对齐方式 start:表示居顶对齐,如下:

如果改为end的话,那么就是 居低对齐了,如下:

center表示居中对齐,如下:

Stretch  在box-align表示拉伸,拉伸与其父容器等高。如下代码:

在firefox下 和父容器下等高,满足条件,如下:

在chrome下不满足条件;如下:

4. box-pack

box-pack表示父容器里面子容器的水平对齐方式,可选参数如下表示:

start | end | center | justify

HTML代码如下:

<div class="test">

        <p id="p1">Hello</p>

        <p id="p2">W3School</p>

</div>

CSS代码如下:

.test{

        display:-moz-box; /* Firefox */

        display:-webkit-box; /* Safari and Chrome */

        display:box;

        width:600px;

        height:108px;

        border:1px solid #333;

        padding:10px;

        -moz-box-pack:end;

        -webkit-box-pack:end;

        box-pack:end;

}

#p1{

        width:100px;

        height:108px;

        border:1px solid red;  

}

#p2{

        width:100px;

        height:108px;

        border:1px solid blue;

}

box-pack:start;  表示水平居左对齐,如下:

box-pack:end 表示水平居右对齐;如下:

box-pack: center 表示水平居中对齐;如下:

Justify:

在box-pack表示水平等分父容器宽度(唯一遗憾的是,firefox与opera暂时不支持,只有safari、chrome支持)

如下:

七:理解盒模型。

    什么是css盒模型?css盒模型包括如下属性:内容(content),填充(padding),边框(border),边界(margin).

这些东西我们可以拿日常生活中的列子来打比方,比如我现在在京东买了一台显示器,那么就会以盒子打包过来,那么显示器就是我们说的内容(content),而填充(padding)就是怕盒子里面的显示器损坏而添加的泡沫或者其他坑震的辅料,边框(border)就是盒子本身了,至于边界(margin)则是盒子摆放的时候不能全部堆在一起,要留一定的空隙保持通风。比如如下:

标准浏览器下的盒子模型如下:

由上可知:W3C盒子模型包括:margin,border,padding,content.

2. IE浏览器下的盒子模型如下:

IE盒子模型由上可知:盒子模型的范围也包括 margin,padding,border,content。但是和W3C不同的是,ie9以下的盒子模型中的content包括padding和border。

比如:一个盒子的margin:10px, width:100px; height:100px; padding:20px; border:1px solid red; 如下代码:

<div class="test">test</div>

<style>

    .test {width:100px;height:100px;padding:20px;border:1px solid red;margin:10px;}

</style>

  1. 标准浏览器盒子模型的宽度 = width + padding-left + padding-right + border-left + border-right + margin-left + margin-right = 100 + 20 + 20 + 1 + 1 + 10 + 10 = 162px;

盒子的实际大小为(width) = width + padding-left + padding-right + border-left + border-right = 100 + 20 + 20 + 1 + 1 = 142px

当然高度与之对应。

     2. IE浏览器(6-8)盒子模型的宽度 = width + margin-left + margin-right = 100 + 10 + 10 = 120px;

盒子的实际大小(width) = 100px;

当然高度与之对应。

   既然标准浏览器下和IE浏览器(6-8)下有这样的区别,那么我们在实际开发中肯定要按照标准浏览器下来计算了,所以就是在网页的顶部加上 doctype 声明。假如不加 doctype 声明,那么各个浏览器会根据自己的行为去理解网页,即 ie 浏览器会采用 ie 盒子模型去解释你的盒子,而 ff 会采用标准 w3c 盒子模型解释你的盒子,所以网页在不同的浏览器中就显示的不一样了。反之,假如加上了 doctype 声明,那么所有浏览器都会采用标准 w3c 盒子模型去解释你的盒子,网页就能在各个浏览器中显示一致了。

比如我们可以做个demo试试看,如下:

声明:在此使用的框架是jquery。

在头部顶部加上 doctype html 如下代码:

<!doctype html>

<html>

 <head>

  <meta charset="UTF-8">

  <title>Document</title>

  <script src="jquery-1.7.1.js"></script>

  <style>

        .test {width:100px;height:100px;padding:20px;border:1px solid red;margin:10px;}

  </style>

 </head>

 <body>

       <div class="test">test</div>

       <script>

              if($.browser.msie) {

                     // 此浏览器为 IE

                     alert($('.test').outerWidth());

              } else {

                     // 非 IE

                     alert($('.test').outerWidth());

              }

       </script>

 </body>

</html>

在所有的浏览器下 弹出142px,但是如果去掉doctype声明的话,那么在标准浏览器下会弹出142,在IE浏览器(6-8)会弹出100. 因此可得知。

八:理解line-height

行高的含义:两行文字 “基线”之间的垂直距离。如下: