聊一聊元素的宽、高的最佳实践

咱们先看手册中关于宽的描述:

语法:
width<length> | <percentage> | auto
默认值:auto
继承性:无
动画性:当值为<length> | <percentage>
计算值:指定的值

取值:
auto:
无特定宽度值,取决于其它属性值
<length>
用长度值来定义宽度。不允许负值
<percentage>
用百分比来定义宽度。百分比参照包含块宽度。不允许负值

怎么理解没有继承性?

首先我们先搞清楚什么是继承关系?什么又是参考计算关系?

尽管两个嵌套的div的宽度往往是一样的,但这不代表子元素div的宽度是继承而来的,而是子元素默认撑满它能占据的所有宽度,所以某些时候显得好似继承而来。但是如果子元素有margin、padding、border,那么子元素的width值就不会跟父元素的width值一致了,而是需要参考计算而来。

而继承是什么意思?是严格的一致,就是父元素width值为100px,子元素的width值必须是100px。现实中当然不一定是这样。

所以,子元素的宽度跟父元素的宽度是参考计算关系,不是继承关系。

这个默认值auto怎么理解?

分两种情况。

第一种情况是,元素自身设置width为auto,也仍具有自身形成的width值。一般来讲这种元素就是img元素。所以,img元素在没有设置任何width的时候,或者宽度设为auto的时候,它不参考任何父元素,它的width就是资源图片自身的width。

第二种情况是非图片元素的情况。它在没有设置任何width的时候,或者宽度设为auto的时候,它的width参考父元素的width。它的盒子宽度会充满父元素的内部空间,当然最终它的width是不是等于父元素的width,要看它有没有margin、padding、border。

width不为auto的时候,是什么情况?

width不为auto,要么是具体值,要么是百分比。其中一些长度单位是相对单位,另有一些是絶対単位。参考http://www.css88.com/book/css/values/length/index.htm

说说百分比,因为只有百分比是子元素宽度与父元素宽度相关。

比如50%,假设父元素的width是1000px,那么子元素的width就是500px。如果父元素没有设定明确的width,那么浏览器先计算出父元素的width值,然后在乘以50%。

当子元素有margin、padding、border,不影响width的计算。也因此,如果有margin、padding、border,就不要以为子元素的盒子宽度是父元素width的一半了,而是父元素width的一半加上子元素的margin、padding、border的值之和。

另外说一下margin/padding/border如果设置了50%,是参考什么计算这个50%?其实也是以父元素的width为参考来计算。所以,假如子元素打算充满父元素的width,子元素可以设置width: 50%; margin: 0 25%;,这样合起来是100%,正好充满所有空间。

到此关于宽我想说的说完了。那么高呢?你以为高跟宽同理?我只能说:Too young, too simple!

为什么这么说呢?

因为width值是一般情况下父元素影响子元素,当父元素有overflow的时候父元素不影响子元素。

而height值是恰恰相反,一般情况下子元素影响父元素,而且又分成若干种情况:

  • 如果父元素设了height:父子互不影响。

  • 如果父元素没有设height:

  • 大部分情况下,子元素的盒子把父元素撑开到多高,那么父元素的height就是多高。也就是子元素的盒子高=父元素的height值。

  • 如果子元素是inline元素,它是没有宽高的,所以也不可能撑起父元素,但媒体元素除外,比如img元素天生具有width和height值,即使它是inline元素,也一样能撑起父div。

  • 如果子元素具有float,或position值为absolute、fixed,那么它就算有高度值,也一样不能撑起父元素。

  • 如果在body里放一个子div,没任何样式,里面再放一个div,里面再再放一个div,所有div的width都是body的width,而高度都是0,尽管body是有高度的。

height的值是百分数的时候怎么计算?

刚才我说“height值一般情况下子元素影响父元素”,注意这个“一般情况下”,因为百分数情况下又不同了,是父元素影响子元素。也就是说父元素的内容高度是1000px的话,当子元素height设了50%,那么子元素的height就是500px。

最佳实践

之所以有上述这些规定原因很简单,盒子模型的重要原理之一就是盒子的宽度尽量充满空间,高度尽量扁。

现在我们在写代码的时候应该遵循什么原则?

慎用height的百分比值

因为百分比值会导致上层元素影响下层,而没有百分比值的时候下层元素影响上层元素,就好像职场里,你的领导给你施压影响你的决断,而你的下属要也影响你的决断,这事是不是就复杂化了?

所以,虽然width用百分比是一个非常棒的主意,但是height用百分比是很糟糕的主意,除非你明确地要把一个div垂直分成两半。

顶级div

1、width应该由最顶级的一、两级div来定,再下级的div应该根据顶级的div来计算width。这是栅格结构解决的问题。

2、顶级div可以考虑写height,当然也可以不写。因为顶级div相当于大骨架,设定height等于是“圈地”,有助于视觉上划分大板块。当然你也可以不设height,只要你能保证下级div能把顶级div撑起到满意的高度,就可以不设。

中级div

1、中级div通常不要设width,除非同一行有多个块级元素。

2、中级div到底写不写height要根据情况而定,最佳实践是:先不写height,直接去写后代元素,一直写到最底层的div,然后从最底层div元素开始设置height,由底层div来撑起各级祖先元素。除非底层div一级级撑起来之后,中级div高度让你不满意,那么你就可以给中级div专设一个height。永远记住:给中级div设定height等于给自己设定枷锁,应当尽量避免。

底层div

1、底层div的width依然是尽量别写width,除非同一行有多个块级元素。

2、底层div的高度一定要写,因为祖先元素就是靠底层div一级级撑起来的。

3、各级元素中间的间距是margin、padding解决的事情,尽量不要用height来解决。道理很简单,做网页就像是搭积木,空中楼阁是不稳定的。比如父元素的height是1000px,子元素的height加起来是800px,虽然看起来暂时没问题,但是一旦增加一个400px高的新子元素,那么子元素的height之和就是1200px,就会产生溢出问题。然后这时候你又后悔写死了1000px,想把1000px改成1200px,这时候又要去找到底哪一级div写死了height,这不是自己给自己找病么?

一句话概括就是顶层div一定要width,底层div一定要height,其他看情况。

底层inline元素和inline-block元素

  • 很简单的常识,给inline元素设置宽高是没有任何意义的(图片除外)。所以应当给它的上级block元素设置宽高。

  • 给一组inline-block元素设置相同的高度,有助于减少不必要的麻烦。

不要依赖不确定的height

虽然我说过,上层div要依靠下层div来撑起来,前提是下层div必须是确定的height值。比如:

  • 如果最下层是img,那么img要设固定宽高,然后这个img的height才可以认为是确定值。因为img是引入的资源,宽高不确定,你不能让一个超高的图片把你页面毁了。一千字的设计、运营规范,不如几个字符的样式声明来的高效。

*如果最下层是一个p段落,一定要设置p的line-height,因为同样是14px的两种字体,默认字高也可能是不一致的。而且,你要确认文字行数是定值。如果你无法确定它行数是定值,那么它就可能撑高或者塌陷容器,那么就必须给p段落的父元素(通常是div)设定高度值。

最后说说margin和padding

margin是有叠加效应的,只有垂直方向的margin才会折叠,也就是说,水平方向的margin不会发生折叠的现象。所以,margin尽量不要设置margin-top,而是尽量永远只设定margin-bottom。

如果你不打算让子元素贴着父元素的上沿,那么也不要给子元素设margin-top,你可以给父元素设padding-top,也可以给子元素设padding-top,具体用哪个,应该视情况而定:比如,如果子元素有border,那么毫无疑问是要给父元素设padding-top,然后子元素的border才不会贴着父元素的上沿。

再如果,有两个子元素横向浮动,我希望两个子元素的内容高低不一样,那么这时候,就不能给父元素设padding-top,而是给两个子元素分别设不同的padding-top。

所以,看情况而定。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问答题47 /72 常见浏览器兼容性问题与解决方案? 参考答案 (1)浏览器兼容问题一:不同浏览器的标签默认的外补...
    _Yfling阅读 13,816评论 1 92
  • 一 外部式css样式 (也可称为外联式)就是把css代码写一个单独的外部文件中,这个css样式文件以“.css...
    KunMitnic阅读 974评论 0 1
  • Window和document对象的区别 window对象window对象表示浏览器中打开的窗口window对象是...
    FConfidence阅读 2,259评论 0 5
  • 选择qi:是表达式 标签选择器 类选择器 属性选择器 继承属性: color,font,text-align,li...
    wzhiq896阅读 1,810评论 0 2
  • 『马可波罗传奇』,无论灯光,场景,服装,编舞,美轮美奂,确实令人叹为观止。虽情节与史实不符,加入太多浪漫情调,但...
    东榆阅读 1,450评论 0 0