欢迎来到css世界
1 何为流
流是css世界中一种基本的定位和布局机制
css世界构建的基石是HTML,而HTML最具两个基石:
- div(块级元素) 相当于容器中的水
- span(内联元素) 相当于水里的木头,水平的依次排列,不足则换行
2 流如何影响整个css世界
- 擒贼先擒王
css世界基石是HTML,只要让HTML符合流,则整个css世界可以被流统治
- 特殊布局和流的破坏
可以通过破坏流实现特殊布局
- 流向的改变
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;
width: 128px;
margin-left: 10px;
border: 1px 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{
width: 150px;
background: #cd0000;
white-space: nowrap;
}
.child{
display: inline-block;
background:#f0f3f9
}
子元素既保持了inline-block的收缩特性,又同时让内容宽度最大,直接无视父级元素限制。
8 外部尺寸和内部尺寸
盒子分为外在盒子和内在盒子,尺寸也分为内部尺寸和外部尺寸。
上面4种尺寸表现:只有第一种为外部尺寸,其余都是内部尺寸。
8.1 外部尺寸和流体特性
- 正常流宽度
在一个容器里面倒入足量的水时,水一定会铺满整个容器。在一个页面丢一个div元素,其尺寸表现就会和水流一样,铺满水面,这就是block容器的流特性。
- 格式化宽度
仅出现在‘绝对定位模型’中,也出现在position:absolute或者fixed元素中。
默认情况下, 绝对定位元素的宽度表现是包裹性,宽度由内部尺寸决定,但有一种情况是由外部尺寸决定:
当left/right top/button 对立方位属性同时存在时,元素宽度表现为格式化宽度,其宽度由最近的具有定位元素特性的祖先决定
div {
position: absolute;
left: 20px;
right: 20px;
}
若具有position:relative的最近的祖先width: 1000px。 则它的宽度为 width = 1000px - 20px -20px = 960px;
8.2 内部尺寸与流体特性
元素由内部元素决定。
那如何判断一个元素是否为内部尺寸: 如果元素里没有内容,宽度为0;则应用的就是内部尺寸。
内部尺寸的三种表现形式:
- 包裹性
包裹+自适应性
自适应性:元素尺寸由内部元素决定,但永远小于‘包含块’容器尺寸。
对于一个display:inline-block的元素来讲,即使里面内容再多,只要是正常的文本,宽度也不会超过容器。
例: 按钮具有display:inline-block特性,文字越多,宽度越宽。文字过多,自动换行。
有一个需求: 页面某个横块文字是动态的,可能是几个字,可能是几句话。文字少的时候希望居中,多的时候希望居左换行显示
.box {
text-align: center
}
.box.content{
display: inline-block;
text-align: left;
}
- 首选最小宽度
上面的例子中假如外部容器是0px,那里面的inline-block元素的宽度会是0px么
不会的,css世界中,图文的权重远大于布局。表现为首选的最佳宽度。
汉字是每字一断,英文一般以符号分割,图片就是图片的宽度
可以做一个凸凹:
.ao{
display:inline-block;
width: 0;
}
.ao:before{
content: 'Love 你 Love',
outline: 2px solid #cd0000;
color: #fff;
}
.ao{
display: inline-block;
width: 0;
direction:rtl;
}
.ao:before{
content: '我 Love 你',
outline: 2px solid #cd0000;
color: #fff;
}
- 最大宽度
元素可以由最大宽度,如果内容无块元素或者块元素没有设定宽度值,则最大的宽度是最大的连续内联的盒子的宽度。
<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个盒子:
- content box
- padding box
- boder box
- margin box
例如: width为100px是直接作用在content box上的;所以div{width:100px; padding:20px; border:20px solid}则最后会变为180px。
解决此问题的方法:
9.1 宽度分离原则
.father{
width: 180px
}
.son{
border: 20px solid;
padding: 20px;
}
缺点就是多了一层标签,增加了渲染成本。
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{
height: 100%;
position: absolute;
}
非绝对定位元素是相对于content box来计算的,绝对定位元素是相对于padding box来计算的
例:
.box {
height: 160px;
padding: 30px;
box-sizing: border-box;
background-color: #beceed;
}
.child{
height: 100%;
background-color: #cd0000;
}
则作用在content box上 高度是100px;
.box{
height: 100%;
padding: 30px;
box-sizing: border-box;
background: #beceed;
position: relative
}
.child{
height: 100%;
width: 100%;
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{
height: 0;
overflow: hidden;
transition: height .2s
}
.element.active{
height:auto // transition不会生效的
}
方法二: 用max-height
.element{
max-height: 0;
overflow: hidden;
transition: max-height .25s
}
.element.active{
height: 666px; // 设定具体指,transition生效
}
max-height使用足够的安全最小值,这样即使有延迟,也因时间短不被发现。