CSS3 Box-sizing的理解

box-sizingCSS3的box属性之一。一说到CSS的盒模型(Box model)我想不少人都会比较烦,特别是对于新手,然而这个Box model又是咱们CSS运用中比较重要的一个属性。那么CSS3Box-sizing跟盒模型有什么关系呢?第一句话就说了,Box-sizing是CSS3的Box属性之一,那他固然也遵循CSS的Box model原理,为了能更好的学习和理解这个Box-sizing属性,咱们有必要先了解一下CSS中Box model的原理。css

CSS中Box model是分为两种,第一种是W3C的标准模型,另外一种是IE的传统模型,他们相同之处都是对元素计算尺寸的模型,具体说就是对元素的width,height,padding,border以及元素实际尺寸的计算关系;他们不一样之处呢?二者的计算方法不一至:html

一、W3C的标准Box Model:node

  /盒尺寸计算(元素空间尺寸)
  Element空间高度 = content height + padding + border + margin
  Element 空间宽度 = content width + padding + border + margin
  /盒尺寸计算(元素大小)
  Element Height = content height + padding + border (Height为内容高度)
  Element Width = content width + padding + border (Width为内容宽度)

 

二、IE)传统下Box Model(IE6如下,不含IE6版本或“QuirksMode下IE5.5+”):css3

  /盒尺寸计算(元素空间尺寸)
  Element空间高度 = content Height + margin (Height包含了元素内容宽度,边框宽度,内距宽度)
  Element空间宽度 = content Width + margin (Width包含了元素内容宽度、边框宽度、内距宽度)
  /盒尺寸计算(元素大小)
  Element Height = content Height(Height包含了元素内容宽度,边框宽度,内距宽度)
  Element Width = content Width(Width包含了元素内容宽度、边框宽度、内距宽度)

 

其实原则上来讲Box Model是分得很细的,咱们这里主要分了两个比较明显的地方,就是外盒模型和内合模型,如上面计算公式所示(后面我将会详细介绍一下CSS中的Box Model)。这样说你们可能还不太好理解,下面咱们一块儿来看一个实际的例子,好比说如今有一个叫boxtest的Div,其具备下面一个属性web

.boxtest {    border: 20px solid;
    padding: 30px;
    margin: 30px;
    background: #ffc;
    width: 300px;
 }

 

咱们先来看一下W3C标准浏览器(Firefox,Safari,Chrome,Opera,IE6+)和传统浏览器(IE6如下版本浏览器)的Layout截图浏览器

上图中明显能够看出IE6如下版本浏览器的宽度包含了元素的padding,border值,换句话来讲在IE6如下版本其内容真正的宽度是(width-padding-boder)。用内外盒来讲的话,W3C标准浏览器的内盒宽度等于IE6如下版本浏览器的外盒宽度。这样下来咱们就须要在IE6下的版本写Hack统一其内外盒的宽度,关于如何处理这样的兼容问题,我在这里很少说,感兴趣的朋友能够点击这里。那么浏览器发展到今天,世面上用IE6如下的浏览器应该所占比例至关的少,但不排除没有人不在用。因此目前浏览器大部分元素都是基于W3C标准的Box Model上,但对于form中的有部分元素仍是基于传统的Box Model上,好比说input中的submit,reset,button和select等元素,这样若是咱们给其设置border和padding他也只会往内延伸。关于如何处理form中的这些元素,今日将会借此机会和大定一块儿探讨一下,那么如今咱们仍是先回到今天的正题上。ide

上面简单让你们对CSS的Box Model有了一个初步的概念(若是想了解更多的Box Model相关知识,能够点击W3C Box Model,另外在这里有中文版)。下面开始咱们今天的主题——CSS3的Box-sizing。布局

语法:post

  box-sizing : content-box || border-box || inherit

 

取值说明学习

一、content-box:此值为其默认值,其让元素维持W3C的标准Box Model,也就是说元素的宽度/高度(width/height)等于元素边框宽度(border)加上元素内边距(padding)加上元素内容宽度/高度(content width/height)即:Element Width/Height = border+padding+content width/height。

二、border-box:此值让元素维持IE传统的Box Model(IE6如下版本),也就是说元素的宽度/高度等于元素内容的宽度/高度。(从上面Box Model介绍可知,咱们这里的content width/height包含了元素的border,padding,内容的width/height【此处的内容宽度/高度=width/height-border-padding】)。

为了更能形像看出box-sizing中content-box和border-box二者的区别,咱们先简单来看一人示例图,以下所示:

兼容浏览器

box-sizing现代浏览器都支持,但IE家族只有IE8版本以上才支持,虽然现代浏览器支持box-sizing,但有些浏览器仍是须要加上本身的前缀,Mozilla须要加上-moz-,Webkit内核须要加上-webkit-,Presto内核-o-,IE8-ms-,因此box-sizing兼容浏览器时须要加上各自的前缀:

 /*Content box*/
  Element {
     -moz-box-sizing: content-box;  /*Firefox3.5+*/
     -webkit-box-sizing: content-box; /*Safari3.2+*/
     -o-box-sizing: content-box; /*Opera9.6*/
     -ms-box-sizing: content-box; /*IE8*/
     box-sizing: content-box; /*W3C标准(IE9+,Safari5.1+,Chrome10.0+,Opera10.6+都符合box-sizing的w3c标准语法)*/
  }
        
  /*Border box*/
  Element {
     -moz-box-sizing: border-box;  /*Firefox3.5+*/
     -webkit-box-sizing: border-box; /*Safari3.2+*/
     -o-box-sizing: border-box; /*Opera9.6*/
     -ms-box-sizing: border-box; /*IE8*/
     box-sizing: border-box; /*W3C标准(IE9+,Safari5.1+,Chrome10.0+,Opera10.6+都符合box-sizing的w3c标准语法)*/
  }

上面主要介绍了box-sizing的理论知识,咱们仍是理论和实践结合吧,下面就一块儿先来看一个简单点的例子:

HTML Code:

 <div class="imgBox" id="contentBox"><img src="/images/header.jpeg" alt="" /></div>
 <div class="imgBox" id="borderBox"><img src="/images/header.jpeg" alt="" /></div>

CSS Code:

 .imgBox img{
     width: 140px;
     height: 140px;
     padding: 20px;
     border: 20px solid orange;
     margin: 10px;
  }
  #contentBox img{
     -moz-box-sizing: content-box;
     -webkit-box-sizing: content-box;
     -o-box-sizing: content-box;
     -ms-box-sizing: content-box;
     box-sizing: content-box; 
  }
  #borderBox img{
     -moz-box-sizing: border-box;
     -webkit-box-sizing: border-box;
     -o-box-sizing: border-box;
     -ms-box-sizing: border-box;
     box-sizing: border-box;
  }

效果:

上面效果图让你们很明显的区分开了content-box和border-box的区别了,为了更好的理解,我截了一份他们在Firebug下的一layout分析图:

Layout分析图再次证实了box-sizing:content-box是维持了W3C的标准Box Model,而box-sizing:border-box是维持了IE传统(IE怪异模式)下的Box Model。其二者区别我在这就很少说了,由于前面说的很清楚了,若是还有不清楚的同窗,只要仔细看一下上面那张Layout分析图,我想你会恍惚大悟的。那么box-sizing主要运用在哪些方面呢?我总结了一下,第一点就是咱们布局上,第二点就是表单元素上。为何呢?我想你们在平时布局中都有碰到当两个块元素的宽度恰好是其父元素总宽度时咱们布局不会有任何问题,但当你在其中一个块加上padding或border时(哪怕是1px)整个布局就会彻底打乱,由于其总宽度超过了父元素的宽度。第二点表单元素,前面我提到过,form有不少元素仍是使用的IE传统Box Model,针对这两点,box-sizing将在其身上发挥强大的做用,下面咱们分别来看看box-sizing在这两方面的运用:

1、box-sizing拯救咱们的布局

为了能更好的说明问题,咱们先来模仿一个两栏布局,先来看其HTML Code:

 <div class="layoutDemo">
    <div id="header" class="innerPadding border">Header Content</div>
    <div id="content" class="clearfix">
        <div id="left" class="aside innerPadding border">Left Sidebar</div>;
        <div id="main-content" class="article innerPadding border">Main Content</div>
    </div>
    <div id="footer" class="innerPadding border"> Footer Content</div>
  </div>

 简单的分析一下,这里把LayoutDemo的div看成咱们页中的body,而div#header是页面头部,div#left是页面左边栏,div#main-content是页面主内容,div#footer是页面的页脚,下面咱们来模仿一个960的布局(比例缩小一半),咱们加上平时布局的样式上去:

  .layoutDemo {
    width: 960px;
    background: #000;     
  }
        
  #header {
    width: 100%;
    background: orange;
  }
        
  #left {
    width: 220px;
    float: left;
    margin-right: 20px
    background: green;
  }
        
  #main-content {
    width: 720px;
    float: left;
    background: gray;
  }
        
  #footer {
    width: 100%;
    background: red;
  }

效果:

到目前布局来讲一点问题都没有,那是由于咱们子元素宽度加起来恰好与元素的是相等,那么咱们如今来变更一下,若是根据设计须要,每一个块中内容都离边缘有10px的距离,那么咱们先来看看基header,left,main-content,footer这几个块加一个padding:10px,看看有什么变化:

.innerPadding {    padding: 10px;
  }

 

效果:

上图清晰告诉咱们,加了一个padding,恶梦就开始来了,header,footer撑破容器伸出去了,main-content也被掉到left的下面了。跟刚才当初的效果但是彻底不同的呀,有人可能会问,若是我不使用padding我只使用border什么怎么样呢?你们猜猜会怎么样?不用猜了,立刻换个代码给你们看看,咱们只要把刚才的padding注掉换成border,以下所示:

.border {     border: 10px solid yellow;
  }

 

效果:

上图是去掉了padding只加了10px的边框,一样把布局给打乱了。接着把padding和border同时加进去,反正都撑破了布局,就破罐子破摔。加上的效果以下:

不上我说,你们都知道上图是由于加上了padding和border把布局给打乱了,下面主要看如何用box-sizing来修复这个撑破的布局,前面介绍了,上图中box-sizing是取了其默认值content-box,其Box Model彻底符合W3C的标准,为了修复这样的布局,咱们须要把Box Model改用IE传统下的解析,这样一加,咱们给他加上下面box-sizing属性:

.box-sizing {    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    -o-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
  }

 

效果:


经过box-sizing:border-box改变了Box Model后,布局神奇般的好了,记得之前为了处理这样的问题,咱们须要改变box的宽度或者在box里面在嵌套一个div,在里面的div中增长padding和border来达到这样的效果。从今天开始,咱们不须要那样作了,咱们只要经过box-sizing:border-box来改变Box Model回到IE的传统模式下,就能够实现了,只是有一点遗憾的是,咱们IE6和IE7不支持,若是为了达到一致的效果,在加上你知道CSS Hack如何写,这样也并不难,你只要让IE6和IE7的宽度改变一下,也能达到效果:

   #left {
    *width:180px; 
  }
  #right {
    *width: 680px;
  }

 经过上面的hack,咱们在IE6和IE7下也能正常显示咱们的布局需求。可是你们说讨厌CSS Hack,不想写,那么你们在项目中运用时不得不要考虑一下,但对于咱们学习CSS3的box-sizing来讲是没有大碍的。

2、Box-sizing统一form元素风格

前面简单提到form有些input仍是支持IE传统下的Box Model标准,好比说【type="submit"】、【type="reset"】、button、select等,然在搜索box-sizing属性使用时偶尔发现Roger Johansson早在2004年就发表了一篇关于表单元素样式测试的文章《Styling form controls》。他告诉咱们若是用样式来控制表单元素在各浏览器下的显示效果是很难,若是还要兼容各系统下的效果更是难上加难。除非使用UI去制做。那么今天咱们就要来看看用box-sizing如何来让他们达到一致效果:今天咱们只要来测试一下submit,reset,button,section,input[type="text"]几个元素,下面咱们先来看其默认状态下的效果(模式是在<!DOCTYPE HTML>):

Html Code:

<form action="#" method="post">
    <div class="form-field">
 <input type="submit" value="submit" class="submit" />
    </div>
    <div class="form-field">
        <input type="reset" value="reset" class="reset" />
    </div>
    <div class="form-field">
 <button class="button">button</button>
    </div>
    <div class="form-field">
 <input type="text" value="text" class="text" />
    </div>
    <div class="form-field">
 <select name="select" id="select" class="select">
           <option value="1">1980</option>
 </select>
    </div>
    <div class="form-field"><input type="checkbox" class="checkbox" />checkbox</div>
    <div class="form-field"><input type="radio" class="radio" />radio</div>
    <div class="form-field"><textarea name="textarea" id="" cols="30" rows="3" class="textarea"></textarea></div>
  </form>

 

CSS Code

<style type="text/css">
     body { font-size: 12px;     }
     form { width: 200px; margin: 20px auto; padding: 10px; border: 1px solid #ccc;     }
		
     .form-field { margin-bottom: 5px; background: #cdcdcd; padding: 2px;     }
		
    .submit,    .reset,    .button,    .text,    .select,    .textarea { width: 80px; border-color: red;    }
			
    .textarea { resize: none;    }
  </style>

 

咱们来看其效果,我在效果截图中附上各个部分在firebug下的layout图:

DOM元素的Layout图明显告诉咱们:

一、【type="submit"】、【type="reset"】、button、【type="text"】、select、textarea默认状况下都带有2px的border;

二、【type="submit"】、【type="reset"】、button默认状况下会有6px的左右padding;height在mac系统下会比在winxp win7系统下少1px,只有16px,(12px的字体时高度为17px);

三、【type="text"】默认状况下会有1px的上下padding;WinXP和Win7下高度为15px,Mac系统下为14px

四、【type="checkbox"】默认状况下会有margin:3px 3px 3px 4px,而且宽/高度默认为13px(IE6,IE7默认大约是15px,Mac系统下只有9px)

五、【type="radio"】默认状况下会有margin: 3px 3px 0 5px的外边,而且宽/高度默认为13px(IE6,IE7默认大约是15px,Mac系统下只有9px)

六、textarea默认状况带有1px的上下margin;

最后要说的一点是,上面那些经常使用的form元素只有【type="text"】和textarea二者是遵循W3C的标准Box Model,而其余几个都是仍是遵循IE传统下的Box Model。下面咱们在把CSS修改一下,咱们把margin、padding和border都统一一下。

 .submit,
  .reset,
  .button,
  .text,
  .select,
  .textarea,
  .checkbox,
  .radio {
     margin: 0;
     padding: 0;
     border-width: 1px;
   }

 

一样咱们来看看其各元素在firebug下的Layout分析图:

Layout图告诉咱们,其margin,border,padding如今都统一了,宽度只有【type="checkbox"】和【type="radio"】在不一样的系统和浏览器会解析不同,最明显的上面也说过了,这两个表单元素在IE6和IE7下的宽、高度都是15px,而在Mac系统下是9px,但在WinXP/Win7的Firefox下又是13px,这样给咱们在线上的显示效果彻底带来了不同的风格,这也是你们头痛的一个地方;另外还有一点须要说明的一点是,别然在上面的Layout中分析【type="submit"】、【type="reset"】、button的宽度同样,可是在IE6-7之中会随着内容显示不一样而宽度不一样,关于这个问题你们能够参考前面我写的另外一篇文章《input 按钮在IE下兼容问题》。然而最让咱们头痛的是表单元素的高度问题,前面也提到过了,在Mac系统下各类表单元素的高度都会比Win系列下少1px,这样给咱们也带来很大的烦恼。我在网站搜索,看到nwind写了一篇《如何更好地控制input输入框的高度》,做者拿了【type="text"】作了很仔细的分析,另外Roger Johansson的《Controlling width with CSS3 box-sizing》一文也作过详细的分析。从这两篇文章得知解决这样的兼容问题咱们可使用CSS3的box-sizing的border-box属性。下面我截取【type="text"】的解决高度不一到致的方法,运用到表单元素上来

  .submit,
   .reset,
   .button,
   .text,
   .select,
   .textarea,
   .checkbox,
   .radio {
 margin: 0;
 padding: 0;
 border-width: 1px;
 height: 17px;
 -moz-box-sizing: border-box;
 -webkit-box-sizing: border-box;
 -o-box-sizing: border-box;
 -ms-box-sizing: border-box;
 box-sizing: border-box;
   }
    
   .checkbox,
   .radio {
 width: 13px;
 height: 13px;
 -moz-box-sizing: border-box;
 -webkit-box-sizing: border-box;
 -o-box-sizing: border-box;
 -ms-box-sizing: border-box;
 box-sizing: border-box;
   }

 

咱们来看看加上了box-sizing:border-box的layout分析图:

从Layout图明显的能够看出,如今元素的参数都统一了,可是IE6和IE7是不支持box-sizing的属性,因此为了兼容咱们还须要为他们写一个hack:

.submit,
  .reset,
  .button,
  .text,
  .select,
  .textarea,
  .checkbox,
  .radio {
     margin: 0;
     padding: 0;
     border-width: 1px;
     height: 17px;
     -moz-box-sizing: border-box;
     -webkit-box-sizing: border-box;
     -o-box-sizing: border-box;
     -ms-box-sizing: border-box;
     box-sizing: border-box;
     /*这里须要减去border的值,若是padding的值不是0还须要减去padding的值,*/
     *height:15px; 
     *width: 15px;
   }

 

上面详细介绍了form元素如何使用box-sizing来解决浏览器兼容问题。须要提醒你们一点的是,若是你在样式中没有对border进行设置的话,那么表单中除了checkbox和radio外默认都是2px的border,这样一来你的宽度和高度在都要相应的减去4px。

说到这里,有关于box-sizing相关方面的知识就介绍完了,本文只介绍了他在布局和form上的运用,固然他可能还有别的地方运用更好,有待于咱们去发掘,若是大家发现有关于这方面更好的知识,记得一块儿分享

如需转载烦请注明出处:W3CPLUS

相关文章
相关标签/搜索