css世界 之 你所不知道的 width/height 用法

块级元素与内联元素

定义

  1. 块级元素:一个水平流上只能单独显示一个元素,多个块级元素则换行显示。
  2. 内联元素:能够和文字在一行显示,多个内联元素能够在一行显示

这里就要注意了: 块级元素和display:block不是一个概念,块级元素的display不必定是block值,也多是table,或者list-item等值,因此只要符合块级元素的基本特征,都属于块级元素的一种。php

同理,内联元素和display:inline也不是一个概念,内联元素的display不必定是inline,也多是inline-block,因此span,a,input,button,img等都属于内联元素。css

display不一样值的盒子组成

首先,咱们引入一个抽象概念,其实每一个元素都是由两层盒子组成:外在盒子与内在盒子,安全

  1. 外在盒子:负责元素是否能够在一行显示,仍是只能换行显示
  2. 内在盒子:负责元素的宽高,内容呈现等

可能还不是很理解吧,咱们来结合一个实际例子看一下:display:inline-blockbash

咱们想一想为何inline-block既能够像块级元素那样设置宽高,又能够像内联元素那样,在一行上显示呢?咱们来经过咱们的两层盒子理论来讲一下:inline-block,其实就是由一个外层inline盒子,和一个内层block盒子组成,这样外层盒子就能够在一行中显示了,同时咱们也能够对内层block盒子设置宽高。ide

类比,咱们看一下其余display属性值:布局

  1. display:block;其实等价于display:block-block,这样咱们就既能够保证换行显示,也能够设置宽高
  2. display:table; 其实等价于display: block-table, 这样能够保证表格既能够换行显示,也能够设置宽高
  3. display:inline-table; 顾名思义,能够保证表格在一行显示,不换行,也能够设置宽高。

相信你们经过这几个例子,可以真正理解这两层盒子的意思了吧,这里还有一个注意点,width/height是做用在哪一个盒子上呢? 很显然,咱们上面已经提到了,它是做用与内层盒子。优化

除了经常使用的这些display属性值,咱们这里罗列的display的全部属性值: 动画

width/height的具体做用细节

1. 深藏不露的width:auto

在实际开发过程当中,width的默认值为auto, 因此咱们可能也用的比较少,可是它实际在页面中几乎每一个页面都会或多或少用到它的特性,因此咱们更须要了解它的特性,这样才有助于咱们能更好的理解为何页面会这样渲染?为何最后出来是这样一个效果呢。spa

咱们首先来讲两个名词:外部尺寸和内部尺寸设计

  1. 外部尺寸:元素的宽度由外部元素所决定
  2. 内部尺寸:元素的宽度由内部元素所决定,简单来说就是 元素的尺寸由内部的元素决定,而非由外部的容器决定。如何快速判断一个元素使用的是否 为 “内部尺寸” 呢?很简单,假如这个元素里面没有内容,宽度就是 0,那就是应用的“内 部尺寸”。

不一样的元素在不一样的场景下,会表现为不一样的尺寸,或者换句话说,元素默认的width:auto,在不一样的场景下,也会表现为不一样的宽度。

接下来,咱们介绍一下常见的这种场景:

  1. 外部尺寸:

a. 块级元素:例如div,p等标签默认宽度是100%于它的父元素,也就是说此时div的宽度彻底依托于外部尺寸的宽度,即此时表现为外部尺寸

b. 格式化宽度:格式化宽度仅出如今“绝对定位模型”中,也就是出如今 position 属性值为 absolute 或 fixed 的元素中。在默认状况下,绝对定位元素的宽度表现是“包 裹性”,宽度由内部尺寸决定,可是,有一种状况其宽度是由外部尺寸决定的,是什么情 况呢?对于非替换元素,当 left/top 或 top/bottom 对立方位的属性值同时 存在的时候,元素的宽度表现为“格式化宽度”,其宽度大小相对于最近的具备定位特性 (position 属性值不是 static)的祖先元素计算。

  1. 内部尺寸

全部表现为内部尺寸的元素都有如下三个特性:

a. 包裹性:即元素宽度由内部元素决定,同时,它的宽度永远小于它的父元素的宽度,就好像为该元素设置了一个max-width:100%的效果相似。咱们常见的inline-block 元素,浮动元素以及绝对定位元素都具备包裹性,均有相似的智能宽度行为。

想要更深入的理解,能够参考实际案例:demo.cssworld.cn/3/2-5.php

b. 首选最小宽度

首选最小宽度是指元素最适合的最小宽度,有一个问题:假如父元素的宽度是0px,那么它的子inline-block元素宽度是多少呢?会是0吗?不会,在 CSS 世界中,图片和文字的权重要远大于布局,所以,CSS 的设计者显然是不会让图文在 width:auto 时宽度变成 0 的,此时所表现的宽度就是“首选最小宽度”。

c. 最大宽度

最大宽度就是元素能够有的最大宽度。我本身是这么理解的,“最大宽 度”实际等同于“包裹性”元素设置 white-space:nowrap 声明后的宽 度。若是内部没有块级元素或者块级元素没有设定宽度值,则“最大宽度”其实是最大的连 续内联盒子的宽度。

2. 实际代码中如何应用width属性

首先咱们再强调一下box-sizing的做用细节:display: content-box/padding-box/border-box,默认状况下,咱们所设置的width都是针对content-box而言的,若是想设置其余宽度,须要手动更改box-sizing的值,这点你们基本都知道了,

这里咱们重点说一下如何在实际代码中设置宽度呢?

  1. 记住“无宽度”这条准则,

也就是说咱们在实际代码中,尽可能不要设置width,由于一旦设置了定宽,那么自己的流式布局特性就消失了,因此咱们能不用就不用,

可是,在某些场景下,确实须要咱们设置一个定宽,那么在这样的场景下,咱们要遵循另一个原则:宽度分离原则

  1. 宽度分离原则

即css中的width属性不与影响宽度的padding/border,有的时候也包含margin一块儿使用,

也就是说下面这样的代码尽可能不要写

box { width: 100px; border: 1px solid; }
.box { width: 100px; padding: 20px; }
复制代码

那有什么替代方案呢?咱们能够再包一层父节点

.father {width:100px}
.father .box {border: 1px solid 100px; padding: 20px}
复制代码

或者,咱们手动修改box-sizing的值

.box{
    box-sizing: border-box;
    width: 100px;
    border: 1px solid;
    padding: 20px
}
复制代码

3. 替换与非替换元素的宽度表现

对于非替换元素,若是咱们将display设置为block,那么它则会具备流动性,即宽度是由外部元素决定,可是替换元素就不同了,替换元素不管display是inline仍是block, 它的宽度是有内部元素所决定的,它不受display的影响。

例如

input {
    display:block;
}
复制代码

这个时候,咱们将一个替换元素的display手动变成了block,那么它的宽度会变成100%于它的父元素吗?哈哈,很显然不会,它仍是原来的尺寸,咱们要记住替换元素的这个特性。

这个时候,如何让一个替换元素的宽度撑满水平方向呢?有人可能想到,直接width:100%啊,可是有个问题,就是input自己是有padding和border的,若是咱们直接设置width:100%,实际效果可能光标就直接紧贴两边了,那么,如何优化呢?把box-sizing改为border-box啊,

是的,这也是box-sizing:border-box最经常使用的一个应用场景:即解决替换元素的宽度自适应问题,因此咱们在实际开发中,没有必要设置 * {box-sizing:border-box}, 即没有必要将全部元素的box-sizing属性值都变成border-box, 只须要将替换元素的box-sizing重置,即

input, textarea, img, video, object { 
    box-sizing: border-box; 
}
复制代码

4. height:auto 与 height:100%

height:auto 即元素的高度是由内容的高度所决定的,固然,对于绝对定位元素来讲,也会存在格式化高度的效果,格式化高度和格式化宽度相似,参考咱们以前讲的便可。

height 和 width 还有一个比较明显的区别就是对百分比单位的支持。对于 width 属性, 就算父元素 width 为 auto,其百分比值也是支持的;可是,对于 height 属性,若是父元素height 为 auto,只要子元素在文档流中,其百分比值彻底就被忽略了。

那么,如何让height:100%生效呢?

    1. 给父元素设置显式的高度
.parent {
    height: 300px;
    padding: 20px;
}
.child {
    height: 100%;// 此时子元素高度为300px;
}
复制代码
    1. 给本身使用绝对定位
.parent {
    height: 300px;
    padding: 20px;
    position: relative;
}
.child {
    height: 100%;//此时子元素的高度是 340px
    position: absolute;
}
复制代码

咱们看到上面两种方式的效果还不同,为何呢?

这是由于绝对定位元素的百分比计算和非绝对定位元素的百分比计算是有区别的,区别 在于绝对定位的宽高百分比计算是相对于 padding box 的,也就是说会把 padding 大小值计算 在内,可是,非绝对定位元素则是相对于 content box 计算的。

这里,咱们引入一个实际开发中常见的一个效果?任意高度元素的展开收起动画技术

固然,可能有至关一部分人,直接控制display的属性在none和其余值之间切换便可,可是这种方式虽然能够实现,可是效果略显生硬,如何在收起和展开时有一个过分效果呢?

可能第一反应是,收起时height设置为0,展开时height设置为auto,这样看着好像是能够的,可是实际这样实现是有问题的,由于auto 是个关键字值,并不是数值,正如 height:100%的 100%没法和 auto 相计 算同样,从 0px 到 auto 也是没法计算的,所以没法造成过渡或动画效果。

那么还有更好的方法吗?不妨试试max-height便可

.element { 
    max-height: 0; 
    overflow: hidden; 
    transition: max-height .25s; 
} 
.element.active { 
    max-height: 666px; /* 一个足够大的最大高度值 */ 
}
复制代码

这样咱们就能够为该元素添加动画效果了,不过此方法有一个注意点,咱们说设置一个足够大的最大高度值,并不意味着咱们要设置的无限大,若是设置的无限大,颇有可能动画带来延迟,因此在实际开发中,咱们只须要设置一个足够安全的max-height便可,这样即便收起时有延迟,时间也会很短,用户很难发现,也会不会影响用户体验。

相关文章
相关标签/搜索