css3的Sizing

Box-sizing是css3的box属性之一,遵循css的boxmodel原理,css中box model是分为两种,第一种是w3c的标准模型,另一种是ie的传统模型,他们相同之处都是对元素极端的模型,具体说就是对元素的width,height,padding,border以及元素实际尺寸的计算关系。

w3c的标准box model

外盒尺寸计算(元素控件尺寸)

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版本)

外盒尺寸计算(元素空间尺寸)

Element空间的高度 = content heigth +margin(height包含了元素内容宽度,边框宽度,内距宽度)

Element空间的宽度 = content Width +margin(Width包含了元素内容宽度,边框宽度,内距宽度)

内盒尺寸计算(元素大小)

Element height = content height (height包含了的元素内容高度,边框高度,内距高度)

Element Width = content width(width包含了元素内容宽度,边框宽度,内距宽度)

box-sizing属性定义盒元素尺寸的计算方法:

content-box:默认值,计算方法为width/height = content,表示指定的宽度和高度仅限内容区域,边框和内边距的宽度不包含在内

padding-box:计算方法为width/height = content+padding,表示指定的宽度和高度包含内边距和北荣区域,边框宽度不包含在内

border-box:计算方法为width/height = content+padding+border,表示指定的w/h包含边框,内边距和内容区域。

inherit:表示继承父元素中box-sizing属性的值

正常情况下offsetWidth,offsetHeight获取元素的尺寸是足够了,但是某些元素比如SVG,MathML返回尺寸出错(这里不考虑),css3增加了一个box-sizing选择盒子模型,于是jquery里面就引入了augmentWidthOrHeight这个方法来处理因为box-sizing设置导致的问题,augmentWidthOrHeight这个方法其实就是对盒子模型的一个处理,所以jquery获取一个元素的w/h都是,ele.offsetW/H+augmentHeight方法也可以。

关于augmentWidthOrHeight方法

1.8增加了对css属性box-sizing的支持,需要与1.7.2的区别了,1.7.2和以前的版本无论是否定义box-sizing:border-box返回的都是盒模型中元素内容的W/H,不包括padding和border

augmentWidthOrHeight方法是特别针对盒子模型的处理,可通过将box-sizing设置为border-box,这可以令浏览器呈现带有指定宽度和高度的框,并把边框和内边距放入框中。

尺寸获取

有三种方法能够确定浏览器的尺寸(浏览器的窗口,不包括工具栏和滚动条)

对于ie,chrome,ff,opera,safari:

窗口显示区(可视区域)的宽度和高度,包括滚动条

window.innerHeight:ie不支持该属性,ie中的body元素clientHeight属性与该属性相同,window.innerWidth,ie不支持该属性,ie中的body元素的clientWidth属性与该属性相同。

对于ie5,6,7,8

窗口显示区(可视区域)的宽度和高度,不包括滚动条区域

document.documentElement.clientHeight

document.documentElement.clientWidth

或者

document.body.clientHeight/W

对于元素宽度尺寸的获取,jquery提供了width方法

对于文档级非普通元素window,document的宽度获取

$(window).width()代表了当前浏览器可见区域的宽度

$(document).width()则代表了整个文档的宽度,可以有滚动内容

window反应的是视图窗口,没有用window.innerWidth(包括滚动条区域),而是采用window.documentElement.clientWidth(不包括滚动条区域),document是反映了实际内容区间,那么可以存在溢出滚动,所以就是

document.documentElement.scrollWidth

document.body.scrollWidth

由于兼容问题就取2者之中的最大值

1,元素的宽度可以是内联或者通过link定义,所以通过style是不可取的

2,元在隐藏状态下是不能获取任何尺寸的display:none

3,css3引入了box-sizing的设置

jquery的处理

width,height在内部最终调用的是是jquery.css(elem,type,extra)方法,jquery.css是最终的一个针对所有css处理的接口。

display:none的状态下是无法获取元素的尺寸的,所以jquery在最开始之前必须要检测下这个状态,这个处理是通过钩子jquery,cssHooks["width"].get方法调用:

^(none|table(?!-c[ea]).+)/test(jQuery.css(elem, "display")) //代码很简单通过判断得到的值

当检测到是none的情况下, 就要把display设置为block,不行这样就改变了布局的原意了,本来就是隐藏的,jquery就会对元素增加position:absolute,visiblity:hidden,这样的属性达到display的效果,因为在visibility:hidden的请款下,是可以获取值的,只是对于用户可不见而已。

获取元素的尺寸值我们有offsetWidth,与offsetHeight,大多情况下是不够用了,但是有一种情况如果元素采用boxSizing处理,所以jquery好药对BorderBox情况的检测.

尺寸设值

当调用.width方法的时候,这个value参数可以是一个字符串或者一个数字,如果这个value参数只提供一个数字,jquery会自动加上单位px,如果只提供一个字符串,人格有效的css尺寸都可以为宽度赋值(100px 50%,auto),css宽度属性不包含padding,border,margin,除非box-sizing css属性被使用

如果没有明确的给单位,那么默认情况下px会被直接添加上去

.width设置的容器宽度是根据css box-sizing属性来定的,将这个属性改成border-box将造成这个函数改变成获取这个容器的outerWidth替换原来的内容宽度,可以直接用style这个接口直接操作直接注意的就是单位的转化数字需要加上px,还有box-sizing的处理

 

偏移算法

offsetWidth = borderleftW+paddingleftW+Widht+paddingrightW+borderrightW;

offsetHeight = bordertopW+paddingTop+height+paddingBottom+borderbottomW;

不再考虑box-sizing的情况下, 也就差不多了,但是关于尺寸的接口还有:innerW,innerH,outerW,outerH等

innerW/H

用于获取匹配集合中第一个元素的当前计算的内部宽高(padding,但不包括border),或设置每一个匹配元素的内部宽高

outerW/H

获取元素集合中第一个元素的当前计算宽高值,包括padding,border和选择的margin

innerW = ele.offsetW-ele.borderRightW-ele.borderLeftW

innerH = ele.offsetH-ele.borderTopHeight-ele.borderbottomHeight

outerW = ele.offsetW+ele.marginLeft+ele.marginRight

outerH = ele.offsetH+ele.marginTop+ele.marginBottom

 

坐标算法

获取位置又offset和position两个方法

offset方法允许我们检索一个元素相对于文档document的当前位置,他和position的差别在于,,position是相对于父级元素的位移。

当通过全局操作将一个新的元素放置到另一个已经存在的元素上面时,position是相对于父级元素的位移

当通过全局操作将一个新的元素放置到另一个已经存在的元素上面时,若要取得这个新的元素的位置, 那么使用offset更合适。

jquery不支持获取隐藏元素的偏移坐标,同样的,也无法取得隐藏元素的border,margin,padding信息,位置的方法没有像width/height一样去修复了display:none的情况,所以针对offset的定义是相对文档的,传统的说用offsetLeft和offsetTop是可以的,但是兼容各种浏览器就不行了,而且效率低

top: box.top + win.pageYOffset - docElem.clientTop,
left: box.left + win.pageXOffset - docElem.clientLeft