css世界中的流、元素和基本尺寸

206 阅读8分钟

欢迎来到css世界

1 何为流

流是css世界中一种基本的定位和布局机制

css世界构建的基石是HTML,而HTML最具两个基石:

  • div(块级元素) 相当于容器中的水
  • span(内联元素) 相当于水里的木头,水平的依次排列,不足则换行

2 流如何影响整个css世界

  1. 擒贼先擒王

css世界基石是HTML,只要让HTML符合流,则整个css世界可以被流统治

  1. 特殊布局和流的破坏

可以通过破坏流实现特殊布局

  1. 流向的改变

3 块级元素,内联元素

css影响了整个css世界,是因为影响了css世界的基石HTML

html常见的标签有 div li table span img 虽然种类繁多,但可以两类:

  • 块级元素 div li table
  • 内联元素 span img

块级元素 与 display: block 不是一回事

  • div display: block
  • li display: list-item
  • table display: table

项目中使用最多的是block 与 table,而不使用list-item。原因有3:

  • list-item字符多,其他的只有5个字符
  • list-item会出现项目符号.
  • IE浏览器不支持伪元素display:list-item

3.1 为什么list-item会出现项目符号

创造css世界原来的想法很简单,这个世界只有块状盒子内联盒子。但是list-item除了块状盒子还有一个附加盒子,学名“标记盒子”,专门放一些圆点、数字这些项目符号。IE不支持list-item是因为无法创建标记盒子导致

4 display:inline-block

  • 内联盒子(外在)
  • 块级容器盒子(内在)

display:inline-block 既能和图文一行显示,又可以设置width/height。有两个盒子 外在盒子是inline级别,里面的盒子是block级别。

所以display:block可以脑补成display:block-block。

display:table可以脑补成display:block-table

5 display:inline-table盒子

  • 内联盒子(外在)
  • table盒子(内在)

可以得到一个和文字在一行显示的表格

.inline-table{
  display: inline-table;
  width128px;
  margin-left10px;
  border1px solid red;
}

6 width/height作用哪个盒子

当然是在内在盒子上,即容器盒子。

7 width:auto包含的4种场景

7.1 充分利用可用空间

div p等元素宽度默认是100%于父级元素的

7.2 收缩与包裹

典型代表: 浮动、定位、inline-block、或者table元素

7.3 收缩到最小

最容易出现在table-layout为auto中,某一列宽度最窄

7.4 超出容器限制

除非有明确的width设置,否则以上3中情况都不会超过父级元素容器宽度的。

例如内容很长的文字,或者内联元素被设置了white-space: nowarp。

.father{
  width150px;
  background#cd0000;
  white-space: nowrap;
}
.child{
  display: inline-block;
  background:#f0f3f9
}

子元素既保持了inline-block的收缩特性,又同时让内容宽度最大,直接无视父级元素限制。

8 外部尺寸和内部尺寸

盒子分为外在盒子和内在盒子,尺寸也分为内部尺寸和外部尺寸。

上面4种尺寸表现:只有第一种为外部尺寸,其余都是内部尺寸。

8.1 外部尺寸和流体特性

  1. 正常流宽度

在一个容器里面倒入足量的水时,水一定会铺满整个容器。在一个页面丢一个div元素,其尺寸表现就会和水流一样,铺满水面,这就是block容器的流特性。

  1. 格式化宽度

仅出现在‘绝对定位模型’中,也出现在position:absolute或者fixed元素中。

默认情况下, 绝对定位元素的宽度表现是包裹性,宽度由内部尺寸决定,但有一种情况是由外部尺寸决定:

当left/right top/button 对立方位属性同时存在时,元素宽度表现为格式化宽度,其宽度由最近的具有定位元素特性祖先决定

div {
  position: absolute;
  left20px;
  right20px;
}

若具有position:relative的最近的祖先width: 1000px。 则它的宽度为 width = 1000px - 20px -20px = 960px;

8.2 内部尺寸与流体特性

元素由内部元素决定。

那如何判断一个元素是否为内部尺寸: 如果元素里没有内容,宽度为0;则应用的就是内部尺寸。

内部尺寸的三种表现形式:

  1. 包裹性

包裹+自适应性

自适应性:元素尺寸由内部元素决定,但永远小于‘包含块’容器尺寸。

对于一个display:inline-block的元素来讲,即使里面内容再多,只要是正常的文本,宽度也不会超过容器。

例: 按钮具有display:inline-block特性,文字越多,宽度越宽。文字过多,自动换行。

有一个需求: 页面某个横块文字是动态的,可能是几个字,可能是几句话。文字少的时候希望居中,多的时候希望居左换行显示

.box {
  text-align: center
}
.box.content{
  display: inline-block;
  text-align: left;
}
  1. 首选最小宽度

上面的例子中假如外部容器是0px,那里面的inline-block元素的宽度会是0px么

不会的,css世界中,图文的权重远大于布局。表现为首选的最佳宽度。

汉字是每字一断,英文一般以符号分割,图片就是图片的宽度

可以做一个凸凹:

.ao{
  display:inline-block;
  width0;
}
.ao:before{
  content'Love 你 Love',
  outline: 2px solid #cd0000;
  color#fff;
}
.ao{
   display: inline-block;
   width0;
   direction:rtl;
}
.ao:before{
  content'我 Love 你',
  outline: 2px solid #cd0000;
  color#fff;
}
  1. 最大宽度

元素可以由最大宽度,如果内容无块元素或者块元素没有设定宽度值,则最大的宽度是最大的连续内联的盒子的宽度。

<div style="500px">
  <div style="border: 1px solid block;display:inline-block">
    我是文本
    <span>我在inline标签内</span>
    <button>我是按钮</button>
    <br>
    <p>我是一段描述</p>
  </div>
</div>

则最大的宽度应该是 我是文本 + 我在inline标签内 + 我是按钮

9 width细节

css盒尺寸:

css世界什么最多,盒子。比如前面的块级盒子,内联盒子。以及外在盒子,内在盒子。

这里的内在盒子分为4个盒子:

  1. content box
  2. padding box
  3. boder box
  4. margin box

例如: width为100px是直接作用在content box上的;所以div{width:100px; padding:20px; border:20px solid}则最后会变为180px。

解决此问题的方法:

9.1 宽度分离原则

.father{
  width180px
}
.son{
  border20px solid;
  padding20px;
}

缺点就是多了一层标签,增加了渲染成本。

9.2 用box-sizing来解决

box-sizing: border-box可以将作用范围调整为border范围内,而不是作用在content上。

10 height: 100%

height 与 width 有一个明显的区别就是对百分比单位的支持。对于width属性,就算父元素width:auto;其百分比也是支持的。

但对于height属性,父元素height:auto,则只要子元素在文档流中,百分比就无效。

为什么不支持: auto * 100% = NaN 无法计算;

10.1 父元素设置显式高度

html, body{height: 100%}

10.2 使用绝对定位

.div{
  height100%;
  position: absolute;
}

非绝对定位元素是相对于content box来计算的,绝对定位元素是相对于padding box来计算的

例:

.box {
  height160px;
  padding30px;
  box-sizing: border-box;
  background-color#beceed;
}
.child{
  height100%;
  background-color#cd0000;
}

则作用在content box上 高度是100px;

.box{
  height100%;
  padding30px;
  box-sizing: border-box;
  background#beceed;
  position: relative
}
.child{
  height100%;
  width100%;
  background#cd0000;
  position: absolute;
}

则高度为160px;

11 min-width/max-width

width/height的默认值是auto;

min-height/min-width的默认值是auto

max-width/max-height的默认值是none

为什么是none?

例: 父元素400px;子元素是800px;加入max-width是auto,则子元素的800px就无效了。因为max-width会覆盖width的。

11.1 !important 也无能为力

即使!important max-width 也会覆盖 width

<img src="1.png" style="width: 480px !important">
.img{
  max-width: 256px;
}

则最终的宽度还是256px生效;

11.2 min-width会覆盖max-width

.container{
  min-width: 1400px;(其作用)
  max-width: 1800px;
}

11.3 任意高度元素的展开收起动画技术

展开收起是常见的交互形式, 通常是display在none和其他值之间切换,虽然能行,但是没有动画效果;

方法一:(生硬)

.element{
  height0;
  overflow: hidden;
  transition: height .2s
}
.element.active{
  height:auto // transition不会生效的
}

方法二: 用max-height

.element{
 max-height0;
 overflow: hidden;
 transition: max-height .25s
}
.element.active{
 height666px; // 设定具体指,transition生效
}

max-height使用足够的安全最小值,这样即使有延迟,也因时间短不被发现。