我不会写CSS之width:auto

286 阅读5分钟
原文链接: zhuanlan.zhihu.com
auto是width的默认属性,会CSS的同学都知道,那么当width是auto的时候具有哪些表现呢?于我,完全不知道,捂脸逃走~

深藏不露的width:auto至少包含下面这4种表现

1.充分利用空间,比如<div>,<p>,<h1>~<h6>宽度默认为父级元素的100%,fill-available.(备注1:不仅仅是简单的100%)

2.收缩和包裹,比如浮动,绝对定位,还有inline-block的元素是由内容把宽度撑开,宽度收缩到合适,fit-content.(备注2:不仅仅是合适)

3.收缩到最小,这个我还真不知道怎么解释,如果父元素的宽度有限,当前元素内容换行的原则是中文每一个字都可以换行,英文不可以随意换行,根据前面两条规则来换行使得内容能够完全填充,这种行为即收缩到最小,min-content.换行的目的是为了不超过父级元素.

如果父元素的宽度是0,那么又存在下面两种情况(跑偏了,跑偏了)

<div style="width: 0;">
    <p>中文中文中文中文中文English中文中文</p>  //<p>元素的width为0
</div>

<div style="width: 0;">
    <a>中文中文中文中文中文English中文中文</a>  //<a>元素的width为English占据的宽度
</div>

4.超出容器限制,上面三种情况的元素都不会主动超过父级元素的宽度(备注:特别是第三点收缩到最小,目的也是为了不超过父级元素的宽度),除非是很长的英文,或者设置了样式white-space:nowrap;的元素.

推荐阅读张大大的文章

深入理解CSS的width:auto " 张鑫旭-鑫空间-鑫生活www.zhangxinxu.com图标
备注1:fill-available,不简单的完全填充

前面有提到fill-available的宽度是100%填充父级元素,但不仅仅是100%,因为这里涉及到margin/border/padding/content自动分配机制.

每个元素都有四层结构,margin, border, padding, content, 如果在元素上设置100%,默认情况下(不设置box-sizing)这个100%作用在content层面上,那么如果在这个元素上也同时设置margin, border, padding的话,绝对超出父级元素,微笑脸.

所以说width:auto使得元素的宽度100%填充父级元素不简单,毕竟这个完全填充帮你把margin, border, padding, content都规划得好好的,你只需要关注内容就可以了.

不过CSS3中有个优秀的属性也是来帮我们解决完全填充问题的,box-sizing,说到box-sizing又不得不提标准盒模型和怪异盒模型,事实上box-sizing的各个值对应了元素的四层结构,margin-box, border-box, padding-box, content-box,这四个值指元素宽度设置100%时的作用域.不过margin-box没有应用场景,padding-box的应用场景渐弱,只有Firefox 50之前支持,后面的版本不再支持,现在可以设置的属性值是unset, initial, inherit, content-box, border-box.

  • content-box对应的是标准盒模型,width:100%作用在content层,也就是我们在开发时采用的默认模式.
  • border-box对应的是怪异盒模型,也叫做IE盒模型,width:100%作用在border层.

box-sizing请参考

box-sizingdeveloper.mozilla.org图标


备注2:fit-content,内容再怎么多,宽度也不能比父元素大,体现包裹性

又是前面提到的,对于inline-block的元素,宽度由内容撑开,但总是比父元素的宽度小,小于等于父元素的宽度.

//这是一个会换行的button
//<input type="button">不会换行,它默认white-space:pre,设置为white-space:normal即可
<div style="width:30px">
    <button>我很西瓜的瓜我很西瓜的瓜我很西瓜的瓜我很西瓜的瓜<button>
</div>

这种特性很有意思,在《CSS世界》一书中有介绍.比如这种场景,元素的内容不定,内容少的时候居中显示,内容多的时候左对齐.

//我会居中
<div style="width:300px; text-align:center;">     
    <button style="text-align:left;">我很西瓜的瓜<button> 
</div>

//我会左对齐
<div style="width:300px; text-align:center;">     
    <button style="text-align:left;">我很西瓜的瓜我很西瓜的瓜我很西瓜的瓜我很西瓜的瓜我很西瓜的瓜我很西瓜的瓜<button> 
</div>


来自《CSS世界》的一个彩蛋

box-sizing可以改变width:100%的作用域,那在没有box-sizing属性的那个时代,设置了width:100%同时又需要设置border和padding,怎么办,怎么办~

宽度分离原则

width独占一层标签,margin, border, padding占一层标签.在标准盒模型下,遵循这样的原则同样可以让元素流动起来.

<div style="width:100%;">
    <div style="border:1px solid #ccc; padding:5px;">content...</div>
</div>

说起来,下面这种真是邪恶的操作

//假如父级元素是100px
<div style="width:88px; padding:5px; border:1px solid #ccc;">
    content...
</div>

//假如我不知道父元素的宽度,那么我也没辙啦,二哈脸