终于到了 CSS 篇了,好像可以放松一些了,可能相比于前面两篇,你会觉得 CSS 要简单很多吧。不会吧不会吧,不会真有人觉得 CSS 简单吧?不知道你是否认同, CSS 是所有编程语言里最好玩的一门语言。但是我想你必须认同张鑫旭老师的神作《CSS世界》,从中你势必跟我一样会发现 CSS 是有多么的奇妙啊!
由于个人职业规划上时间原因,我并未好好的读完这本神作,但是在这篇文章里,我一定会在读完后写下自己所有的理解,请保持期待哦!
所以,关于这一篇,目前的结构是以核心面试题问答的形式展开 ~
CSS 选择器有哪些?
基本选择器
- 标签选择器:通配符选择器 *、根据标签为元素设置的样式
- 类选择器:.class 类选择器是为一类状态声明样式规则(可多次使用)
- id 选择器:#id 为有 id 属性的元素设置样式(只可使用一次)
结构选择器
- 后代选择器:ol li 选择 ol内部的所有的 li
- 子选择器:div>p 选择 div 的子元素 p(不包括孙级及以下元素)
- 兄弟选择器: div+p 选择紧挨着的同级兄弟元素 div 和 p
- 后兄弟选择器:p~ul 选择 p 后面的所有兄弟元素 ul
- 并集选择器: div,p 选择所有 div 和 p 选择器
属性选择器(CSS3)
- E [att]:有 att 属性的 E元素 (如 input[value])
- E [att = "val"]:有 att 且等于 val 的 E 元素
- E [att^= "val"]:有 att 且以 val 开头 E 元素
- E [att$= "val"]:有 att 且以 val 结尾 E 元素
- E [att*= "val"]:有 att 且含 val 的 E 元素
伪类选择器
链接伪类选择器:
- a:link 选择所有未被访问的链接
- a:visited 选择所有已被访问的链接
- a:hover 选择鼠标指针位于其上的链接
- a:active 选择活动链接(鼠标按下的状态)
focus 伪类选择器:
- input:focus 一般用于表单
结构伪类选择器(CSS3):
- E:first-child 父元素中的第一个子元素 E
- E:last-child 父元素中的最后一个子元素 E
- E:nth-child(n) 父元素中的第 n 个子元素 E
- E:first-of-type 指定类型 E 的第一个
- E:last-of-type 指定类型 E 的最后一个
- E:nth-of-type(n) 指定类型 E 的第 n 个
note:这里的 n 可以是 even(偶数)、odd(奇数)、公式
伪元素选择器(CSS3):
- E::before 在元素 E 内部的前面插入内容
- E:after 在元素 E 内部的后面插入内容
note:该选择器权重为1,且该伪元素为行内元素,创建了伪元素但是不会出现(清除浮动)
CSS 三大特性
虽然我写的 CSS 也不少了,但是偶然的,当有人问到我,CSS 的三大特性是什么,我瞬间卡住了。拼命在脑海里寻找这个答案,但是还是模棱两可。哇呜 ~ 我好菜啊 ~
CSS 三大特性:层叠性、继承性、优先级
层叠性
CSS 的层叠性,用张鑫旭老师的描述就是“CSS 世界的层叠规则”,即当网页中的元素发生层叠时(样式冲突)的表现规则。
有规则,就必定有冲突的存在。哪个元素才可以优先展示呢?(不冲突,不会层叠)
我们在写样式的时候,最容易碰见的层叠就是一个 div 压在另一个 div 上面,这个时候,两个层叠的 div 遵循什么样的规则,决定了不同肉眼可见的效果。而这个层叠不就类似于三维空间的 Z 轴叠加吗。
说到大家最能理解的 Z 轴,那就不得不先提一个大家最熟悉的 z-index
在我的实际开发中,有时候因为层级问题,也会使用到 z-index,来帮助一个元素优先展示。但是有时候发现,给元素设置 z-index 竟然无效。究竟它内部蕴含的层叠规则是什么样的呢?
先来看看它比较明显的规则:
- CSS 中,z-index 属性只有和定位元素(注意position 不能为 static)在一起才能生效。正负数都可以,数值越大层级越高
- CSS3 中,弹性盒(flex)的子元素也可以设置 z-index 了
note:影响层叠顺序的属性远不止 z-index 一个,判断元素在 Z 轴上的层叠顺序,也不仅仅是比较两个元素之间的 z-index 值大小。而是由,层叠上下文、层叠水平共同决定。
层叠上下文(Stacking Content)
如果一个元素含有层叠上下文,我们可以理解为这个元素在Z轴
上更靠上,最终表现就是它离屏幕观察者更近。
CSS3 给 CSS 带来的变化是丰富多彩的,其中就有很多会产生层叠上下文的情况:
- 父元素的display属性值为 flex/inline-flex,子元素 z-index
- 元素的 opacity 属性值不是
1
- 元素的 transform 属性值不是
- 元素 mix-blend-mode 属性值不是 normal
- 元素的 filter 属性值不是 none
- 元素的 isolation 属性值是 isolate
- will-change 指定的属性值为上面任意一个
- 元素的 -webkit-overflow-scrolling 属性值设置为 touch
别忘了根元素 HTML 、z-index 值不为 auto 的绝对/相对定位都会产生哦!
层叠水平(Stacking Level)
层叠水平(所有元素都存在)决定了同一个层叠上下文中元素在 z 轴上的显示顺序
层叠顺序(规则)
元素发生层叠时,遵循如下规则(其实就是一个就近原则):
- 谁大谁上:当具有明显的层叠水平标识的时候,如生效的 z-index 属性值,在同一个层叠上下文领域,层叠水平值大的那一个覆盖小的那一个。
- 后来居上:当元素的层叠水平一致、层叠顺序相同的时候,在 DOM 流中处于后面的元素会覆盖前面的元素。
note:一旦普通元素具有了层叠上下文,其层叠顺序就会变高
- 如果层叠上下文元素不依赖 z-index 数值,则其层叠顺序是 z-index:auto,可看成 z:index:0 级别;
- 如果层叠上下文元素依赖 z-index 数值,则其层叠顺序由 z-index 值决定。
这时候你可能会思考,为什么定位元素会显示在普通元素上面呢?
根本原因:元素一旦成为定位元素,其 z-index 就会生效为默认的 auto(0)。也即定位元素和层叠上下文元素是同一个层叠顺序,遵循后来居上规则。
这里附上张鑫旭老师的层叠顺序图
z-index 的负值探索 (了解一下即可)
给一个定位元素设置负值 ,这个元素有时候会隐藏有时候不会?
原因:z-index 负值渲染的过程就是一个寻找第一个层叠上下文元素的过程,然后层叠顺序止步于这个元素。
More:如果 DOM 顺序无法调整的情况下不得不使用 z-index,z-index 一定不要超过2
继承性
子元素会继承父元素的某些样式
比如字体属性、文本属性、背景属性。但是不会继承宽高、边距
主要优势:简化代码、降低 CSS 样式复杂性
优先级
我们写 CSS 样式的时候,免不了出现多个相同的样式属性应用在同一个元素上,这时候就出现了样式覆盖以及优先级的问题,我应该优先使用哪一个样式属性呢?
这时候我们就引入了“权重”,权重越高,优先级就越高;权重相同,则采用就近原则。
选择器的权重
- 继承 / *:0000
- 元素选择器:0001
- 类、伪类选择器:0010
- id 选择器:0100
- 行内样式:1000
当我们的样式出现嵌套或使用复合选择器的时候,尤其是我们使用 less 时,就需要进行权重的叠加,判定优先使用哪个样式属性
note:
优先级高的会忽视我们上面提到的层叠性和就近原则来定义样式。比如我们在样式属性后面都使用过的 !important,代表着这个属性不会被覆盖,优先级最高。
上面我们提到了层叠上下文,可能你会大声呼出“好家伙,是不是还有一个叫上下文的家伙?”
BFC
BFC Block Formatting Context(块级格式化上下文),是Web页面中盒模型布局的CSS渲染模式,是一个隔离的独立容器,它让处于 BFC 内部的元素与外部的元素互相隔离。
上面是的官方描述,说实话我觉得描述的有些不清不楚,我觉得应该是这样的:
BFC 是页面中的一块渲染区域,它有一套自己的渲染规则,来决定它的子元素如何在页面中渲染
如何触发 BFC
- 根元素(HTML)或其他包含它的元素
- 浮动
- 定位(fixed/absolute)
- 块级元素 overflow 不为 visible
- 非块级元素且 display 为 inline-block / table-cell / table-caption / flex / inline-flex
BFC 运行规则
- 内部的元素会在垂直方向,一个接一个地放置。
- 元素垂直方向的距离由 margin 决定。属于同一个BFC的两个相邻元素的 margin 会发生重叠
- 每个元素的左外边缘(margin-left), 与包含块的左边(contain box left)相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。除非这个元素自己形成了一个新的BFC。
- BFC的区域不会与浮动元素重叠。
- BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。
- 计算BFC的高度时,浮动元素也参与计算
BFC 的作用
- 清除浮动
- 布局:自适应两栏布局
- 防止垂直 margin 合并
一个有趣的现象
有两个 div ,上下排列,给他们都设置 margin,两个 div 之间的 margin 会出现什么现象呢?
- margin 都为正或都为负,则取最大的绝对值生效
- margin 一正一负,则加起来再生效
这个现象的产生源于 BFC,元素在 BFC 中上下排列,垂直距离由 margin 决定,并且他们的 margin 会发生重叠。重叠的规则如上。
说一下你刚刚提到的 CSS 盒模型
这是一个神奇的封装 HTML 元素的盒子,我们主要分为以下两种
标准盒模型
box-sizing:content-box
盒子的大小(宽度):width = 内容的宽度(content)+ border + padding
IE 盒模型
box-sizing:border-box
盒子的大小(宽度):width = 内容的宽度(content + border + padding)
不超过 width 的情况下,padding 和 border 的改变不会撑大盒子
一般用来初始化CSS或在图片或盒子之间加边框(可以解决宽度不够,后面图片换行问题)
前面你还提到了清除浮动
浮动(float)
网页布局第一准则
- 多个块级元素纵向排列找标准文档流(标准文档流可让元素上下或左右流式排列)
- 多个块级元素横向排列找浮动
浮动的特性
- 脱离标准文档流的控制移动(浮)到指定位置(动) —— 脱标
- 浮动的元素(不再保留原先的位置)
- 多个元素设浮动,按属性值一行内显示且顶端对齐排列(浮动的元素互相贴靠或换行)
- 浮动元素具有行内块元素特性
网页布局第二准则
- 先设盒子大小,后设盒子位置
浮动的注意点
浮动和标准文档流的父元素搭配
- 先用标准文档流的父元素排列上下位置,之后内部子元素采取浮动排列左右位置
一个元素浮动了,理论上其余的兄弟元素也要浮动
- 浮动的盒子只会影响浮动盒子后面的标准文档流,不会影响前面的标准文档流
清除浮动
先看看清除浮动的背景:高度坍塌
父元素很多情况下,不方便给高度,但子元素浮动又不占有位置,最后父元素高度为0时,会影响下面的标准文档流。
本质:
清除浮动后,父元素会根据浮动的子盒子自动检测高度,父元素有了高度,就不会影响下面布局了
方法:
- 空标签法:如 <div style="clear:both;"></div> (必须是块级元素)
- 父元素加 overflow:hidden / auto (父元素产生 BFC 机制,即父元素的高度计算会包括浮动元素的高度)
- 父元素加 after 伪元素
- 父元素加双伪元素
顺带谈谈定位吧
浮动可以让多个块级盒子在一行空间没有缝隙地排列显示,经常用于横向排列盒子。而定位可以让盒子自由地在某个盒子内移动或固定,并且可以压住其他的盒子(层叠)。
定位 = 定位模式 + 边偏移
开局先讲一个定位与小姐姐的故事吧
有一次面试的时候,面试官小姐姐问到“定位有哪几种”
我脱口而出“Relative、Absolute、Fixed、Sticky”,答完之后洋洋得意,心想“问这么简单”。
接下来,小姐姐问“还有吗?”
我说“没了”
小姐姐笑着追问“真的没有吗?”。
阿这,我蒙了啊,还有吗?我怎么想不起来了?
小姐姐马上有点俏皮地说出:“Static”
“哇,哦对哦对,还有这个,我给忘了”,好家伙,定位定位,我一直想着把一个盒子定位到其他地方,让一个盒子变来变去,真的就把这个在原位静止不动的给遗忘了呗!低级错误,我认输还不行吗 ~~~~
小姐姐的故事讲完了,我们来全身心投入到定位的那些事吧 ~
相对定位(Relative)
特点:
- 移动位置的时候参照点是元素在正常标准文档流中的位置(原来的位置)
- 元素原来在标准文档流的位置空间继续被占有,后面的元素仍然以标准文档流的方式对待它(不脱标,继续保留原来位置)
绝对定位(Absolute)
特点:
- 元素没有祖先元素或它的祖先元素没有定位,则以浏览器为参照物进行定位
- 祖先元素有定位,则以最近一级有定位的祖先元素为参照物进行定位
- 脱标,不再占有原来的位置
固定定位(Fixed)
特点:
- 以浏览器的可视窗口为参照物进行定位
- 与父级元素没关系。且固定的元素应有宽度
- 脱标,不再占有原来的位置(margin:0 auto 无效)
粘性定位(Sticky)
粘性定位 = 相对定位 + 固定定位
特点:
- 以浏览器的可视窗口为参照物进行定位
- 必须添加 top left right bottom 中的一个
- 不脱标,继续保留原来位置
子绝父相
- 子元素绝对定位,不会占位,可放到父元素任何地方,不影响兄弟元素
- 父元素需加定位限制资源子啊父元素内显示
- 父元素布局时,需占位,故只能相对定位
相对定位元素经常用来作为绝对定位元素的父元素
拓展
1、绝对定位元素的居中算法:
- left:50%
- margin-left:- 元素自身宽度一半
注:加了绝对定位的盒子不能通过 margin:0 auto 来水平居中(相对定位却可以)
2、定位的特殊特性(类似浮动)
- 行内元素加绝对/固定定位,可直接设置宽高
- 行内元素加绝对/固定定位,不设置宽高时,默认大小是内容大小
3、浮动元素、绝对/固定定位的元素都不会触发外边距合并问题(坍塌)
4、绝对/固定定位会压住下面的标准文档流所有内容;浮动元素只会压住下面标准文档流的元素,不会压住元素内的文字或图片(文字环绕效果)
居中
水平居中
1、行内元素
有父元素,给其父元素设置 text-align:center
.parent {
height: 100px;
width: 100px;
background-color: aqua;
text-align: center;
}
.son {
height: 50px;
width: 50px;
background-color: blueviolet;
}
效果:子元素内的文本水平居中
2、块级元素
给自身设置 margin:0 auto
.test {
height: 100px;
width: 100px;
background-color: aqua;
margin: 0 auto;
}
效果:元素自身水平居中显示,注意元素的文本内容不被影响
3、flex(主流)
元素自身设置 display: flex; justify-content: center
.son {
display: flex;
justify-content: center;
background-color: blueviolet;
}
效果:元素的内容水平居中显示
换给父元素设置 display: flex; justify-content: center
.parent {
height: 100px;
width: 100px;
background-color: aqua;
display: flex;
justify-content: center;
}
.son {
background-color: blueviolet;
}
效果:父元素的内容(其子元素)水平居中显示
4、定位 + transform
父元素相对定位,子元素绝对定位 + transform
.parent {
height: 100px;
width: 100px;
background-color: aqua;
position: relative;
}
.son {
background-color: blueviolet;
position: absolute;
left: 50%;
transform: translate(-50%, 0);
}
效果:父元素的内容(子元素)水平居中显示
5、定位 + margin
定位 + margin 负值(宽度一半)
.parent {
height: 100px;
width: 100px;
background-color: aqua;
position: relative;
}
.son {
background-color: blueviolet;
position: absolute;
width: 50px;
left: 50%;
margin-left: -25px;
}
定位 + margin auto
.parent {
height: 100px;
width: 100px;
background-color: aqua;
position: relative;
}
.son {
background-color: blueviolet;
position: absolute;
width: 50px;
left: 0;
right: 0;
margin: 0 auto;
}
垂直居中
1、单行文本
若元素只是一行文本,直接用行高即可
.test {
height: 100px;
line-height: 100px;
background-color: aqua;
}
2、行内块元素或元素高度不定(了解即可)
a)使用 display: inline-block, vertical-align: middle 和一个伪元素让内容块处于容器中央
b) 父元素display:table, 子元素 display:table-cell;vertical-align:middle;
3、flex (主流)
父元素 display: flex; align-items: center;
4、定位 + transform
.son{
position:absolute;
top:50%;
-webkit-transform: translate(0,-50%);
-ms-transform: translate(0,-50%);
transform: translate(0,-50%);
}
5、元素高度固定
.son{
position:absolute;
top:50%;
height:50px;
margin-top:-25px;
}
6、定位 + margin
.son{
position:absolute;
height:50px;
top:0;
bottom:0;
margin:auto 0;
}
布局
标准文档流布局
- 浏览器默认的 HTML 布局方式,表现为按文档的顺序依次显示
- 块元素独占一行,内联元素在同一行排列
浮动布局
- 使用 float 属性,即可使元素脱离标准文档流
定位布局
- 通过 positon 属性来定位(子绝父相)
display 布局
- display 属性允许我们更改默认的元素显示方式(如块级元素变为内联元素)
flex 布局
- 来自 CSS3 的弹性布局,非常便于垂直居中
- 通过容器(父子容器)和轴(主轴、交叉轴)进行布局
- 属性是 flex-grow(放大比例)、flex-shrink(缩小比例)、flex-basis(占据主轴空间), 默认值为 0 1 auto (后两个属性可选)
grid 网格布局(了解)
- 可实现二维布局(类似 table)
多列布局
- 把内容按列的排序方式进行布局。使用 column-count 属性设置需要多少列,也可以使用 column-width 以至少某个宽度的尽可能多的列来填充容器。
实现一下两栏布局吧
简单来说就是三种方式:浮动、flex、定位
左浮动
.left{
background-color: aqua;
float: left;
}
.right{
background-color: blueviolet;
}
右浮动
左浮动实现两栏布局可真简单,左右左右,不都一样嘛,那右边替换一下就好了呗!
.left{
background-color: aqua;
}
.right{
background-color: blueviolet;
float: right;
}
但是效果图却跟预想的不一样 ~
这里的 left 、right 元素都是使用的 div 标签,也就是会独占一行
<div class="left">left</div>
<div class="right">right</div>
在左浮动中,left 被赋予了浮动属性,所以脱离了标准文档流,最后的效果达到了我们想要的样子。而右浮动,right 浮动的效果是一样的,但是第一行已经被占完了,只会在下一行显示。
有什么办法能处理掉这个潜在的 Bug 呢?一步步来
- 首先,我们保持标签的顺序不变
- 我们想让这两个块级元素在同一行显示
- 我们这里讨论的是浮动 float 方案
而 left 是块级元素,如果不让它浮动(脱标),right 在不改变布局特性的情况下(仍然保持标准文档流),是不可能在同一行共存的。
所以,我们对 left 动手
.left{
background-color: aqua;
float: right;
}
.right{
background-color: blueviolet;
}
再看看效果是不是你想要的呢
哈哈哈哈,两栏布局实现啦,但是我们发现两个块级元素的左右位置调换了。要是面试官一定要你 left 在左边,right 在右边,你要怎么办呢
来了来了,你要的来了
浮动 + BFC
.left{
background-color: aqua;
float: left;
}
.right{
background-color: blueviolet;
overflow: hidden;
}
我们给 left 设置了浮动,其实和上面左浮动一样。但是,为了保险起见,我们做了个清除浮动处理
圣杯布局实现两列布局
浮动 + margin
左右都浮动,左边自适应元素 left 设置外层div 100%宽度, 这样就会独占一行, 然后里层设置右边的margin, 把右边元素位置空出来
.left {
float: left;
width: 100%;
background-color: aqua;
}
.right {
float: left;
width: 300px;
margin-left: -300px;
background-color: blueviolet;
}
flex 来了
父元素开启 flex 布局,子元素都占1份,直接上代码和效果图吧
<style>
.container {
display: flex;
}
.left {
flex: 1;
background-color: aqua;
}
.right {
flex: 1;
background-color: blueviolet;
}
</style>
<body>
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
</div>
</body>
定位 + margin (需要计算宽度)
左边设置宽度,右边设置 margin, 把右边元素位置空出来
.container {
position: relative;
}
.left {
position: absolute;
width: 300px;
background-color: aqua;
}
.right {
width: 100%;
margin-left: 300px;
background-color: blueviolet;
}
再实现一下三栏布局吧
中间固定,左右两边自适应
定位 + margin
三个div,两个左右绝对定位脱离标准文档流,中间内容需将左右的空间使用 margin 隔开
<style>
.container {
position: relative;
}
.left {
position: absolute;
top: 0;
left: 0;
width: 200px;
background-color: aqua;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
background-color: blueviolet;
}
.middle {
margin: 0 200px;
background-color: burlywood;
}
</style>
<body>
<div class="container">
<div class="left">left</div>
<div class="middle">middle</div>
<div class="right">right</div>
</div>
</body>
浮动 + margin
原理跟定位一样,我们先来看看代码跟效果
<style>
.container {}
.left {
float: left;
width: 200px;
background-color: aqua;
}
.right {
float: right;
width: 200px;
background-color: blueviolet;
}
.middle {
margin: 0 200px;
background-color: burlywood;
}
</style>
<body>
<div class="container">
<div class="left">left</div>
<div class="middle">middle</div>
<div class="right">right</div>
</div>
</body>
三列的效果达到了,但是我们还想把 right 也放到第一行去。
我们注意到, HTML 标签顺序是:left 到 middle 再到 right
所以 left 浮动脱离标准文档流,可以跟块级元素 middle 在同一行,middle 已经独占一行了,right 就算浮动也只能换行显示了。
怎么办呢?我们不就是想让 left 和 right 都在浮 middle 块上显示吗,试试让他们两个先浮起来吧
我们调整一下 HTML 结构
<div class="container">
<div class="left">left</div>
<div class="right">right</div>
<div class="middle">middle</div>
</div>
圣杯布局实现三栏布局
三个标签都设置左浮动
.left {
float: left;
width: 200px;
background-color: aqua;
}
.right {
float: left;
width: 200px;
background-color: blueviolet;
}
.middle {
float: left;
width: 200px;
background-color: burlywood;
}
flex 布局
这就简单多啦
.container {
display: flex;
}
.left {
flex: 1;
background-color: aqua;
}
.right {
flex: 1;
background-color: blueviolet;
}
.middle {
width: 33.33%;
background-color: burlywood;
}
不过我经常使用 display: flex; justify-content: space-between;
让左右的两个元素贴着左右显示,中间内容独占一栏,分别自适应
.container {
display: flex;
justify-content: space-between;
}
.left {
background-color: aqua;
}
.right {
background-color: blueviolet;
}
.middle {
width: 33.33%;
background-color: burlywood;
}
布局的方式技巧丰富多样,大家要学会巧妙地应变,死记硬背是不行滴。你看我,还是得一个个来一个个试出来才行哇!一定要多多动手哦,兄dei!
在熟悉了各种各样的布局布局布局了之后,emmmm,好多啊,太累了把,能不能来点好玩的嘛!
用 CSS 实现一个三角形
核心:宽高设置为0,由边框来控制大小,然后边框颜色改为透明,然后更改一遍的边框颜色为自己想要的颜色
div{
width: 0;
height: 0;
border:50px solid transparent;
border-bottom-color:red;
}
注意:上面这样设计的话,div的实际占位还是个方形,如下代码实现实际占位变为三角形
div{
width: 0;
height: 0;
border-left:20px solid transparent;
border-right:20px solid transparent;
border-bottom-color:20px solid red;
}
不错不错,你一定是一位优秀的 CSS 画手,可不可以再给我画一个正方形呀?我......
CSS 实现自适应正方形
意想不到的 padding
注意:padding,margin 如果设置为百分比,则均是相对于父级元素的宽度而言的
.outer {
width: 50%;
height: 50%;
background-color: burlywood;
}
.inner {
padding-bottom: 100%;
width: 100%;
height: 0;
}
来自火火的温馨提示:以下未给出效果图的方法,则实际效果图同上
定位 + padding
双重嵌套,外层我们使用 padding 向上来撑开一个50%的空间,内层我们定位到外层的左上角,宽高百分百,实际就是占有了整个外层元素的大小,随着外层元素大小自适应变换。
<style>
.outer {
padding-top: 50%;
height: 0;
background: #ccc;
width: 50%;
position: relative;
}
.inner {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: burlywood;
}
</style>
</head>
<body>
<div class="outer">
<div class="inner">hello</div>
</div>
</body>
VW、VH
利用视口宽高来实现元素等比缩放
.inner {
width: 50vw;
height: 50vw;
background-color: burlywood;
}
伪元素 + margin
<style>
.container {
/* 触发 BFC 解决 margin 问题 */
overflow: hidden;
width: 100%;
background-color: burlywood;
}
.container:after {
content: "";
margin-top: 100%;
/* 块级元素才可以有垂直方向上的 margin */
display: block;
}
</style>
</head>
<body>
<div class="container"></div>
</body>
note:这里的元素 container 里不能有文本内容,不然会破坏正方形的宽高比例哦!
上面我们提到过 vw vh 这些布局上的尺寸单位,我想你肯定还知道其他的尺寸单位,并且在项目中能轻车熟路的使用吧?
你知道的一些描述尺寸的单位
px 咱就不说了吧,懂得都懂,嘿嘿!不过还是提一下:px 是关于像素的绝对单位
em
相对单位,参照物是父元素的 font-size,具有继承的特点。如果字体大小是16px(浏览器的默认值),那么 1em = 16px
rem(root em,根 em)
说到 rem ,那就不得不提它的适配原理了
- 核心思想: 百分比布局可实现响应式布局,而 rem 的本质就是基于宽度等比缩放
- 实现原理:动态获取当前视口宽度 width(如360px),除以一个固定的数 n(把屏幕分为多少份,如100),得到 rem 的值。表达式为rem = width / n (1rem = 3.6px)。
- 通过此方法,rem 的值始终为 width 的 n 等分。
那如何把 UI 图中像素单位转换为以 rem 为单位的值呢?
- 公式:(元素宽度 / UI 图尺寸宽度)* 100
怎么让 1rem = 1px?
rem 是 相对根节点 html 的字体大小(默认16px)来计算的(如 html{font-size:10px},那么 1rem = 10px)。假设我们将屏幕宽度100等分,让 html 元素字体的大小,恒等于屏幕宽度的1/100就可以了(即 html{font-size:width / 100})
项目中,通过 JS 获取到设备宽度,动态地设置根元素的 font-size来实现 1rem = 1px(插件)
实际开发
使用 lib-flexible库,在webpack 中配置 px2rem-loader, 或者 pxrem-loader (配置 px转rem的计算规则),开发的时候就可以直接按照设计稿的尺寸写 px,编译后会自动转化成 rem 实现自适应
微信小程序的 rpx
全称“response pixel”,响应式的px,rpx单位是微信小程序中css的尺寸单位,它可以根据屏幕宽度进行自适应。
设计稿一般使用设备宽度为750px,可以将 px 等比例换算成 rpx(1px = 1rpx)
vw 和vh
这才是现在 CSS3 适应屏幕的真正解决方案
vw:viewpoint width,视窗宽度,1vw等于视窗宽度的1%。
vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。
vmin:取当前vw和Vh中较小的那一个值, vmax:取当前Vw和Vh中较大的那一个值
vw、vh 与 % 百分比的区别:
- % 是相对于父元素的大小设定的比率,vw、vh 是视窗大小决定的。
- vw、vh 优势在于能够直接获取高度,而用 % 在没有设置 body 高度的情况下,是无法正确获得可视区域的高度的,所以这是挺不错的优势。
calc()
CSS3中新增的一个函数, 用于动态计算宽/高,一般使用数学表达式来表示
- 使用“+”、“-”、“*” 和 “/”四则运算
- 可以使用百分比、px、em、rem等单位
- 可以混合使用各种单位进行计算
- 表达式中有“+”和“-”时,其前后必须要有空格,如"width: calc(12%+5em)"这种没有空格的写法是错误的
line-height 百分比
可以直接查看 MDN 上的相关解释:
line-height 属性被指定为以下任何一个:
- 一个 <数字>: 该属性的应用值是这个无单位数字<数字>乘以该元素的字体大小
- 一个 <百分比>:与元素自身的字体大小有关。计算值是给定的百分比值乘以元素计算出的字体大小
- 一个 <长度> :必须px, em等,详细查看 CSS长度
- 关键词 normal。
CSS 中有一个非常常见的魔术,可以实现显示和隐藏,你是否了解它们?
CSS 隐藏元素
我想你应该能很快说出,利用 display 和 visibility
是否占据空间 | 是否渲染 | 继承性 | |
display: none | 否 | 是(触发回流) | 否 |
visibility:hidden | 是 | 否(触发重绘) | 是 |
可能你没有想到,还可以这样实现隐藏:
opacity:0:直接把这个元素给他透明了,是不是就看不见啦,嘿嘿!但是只局限于肉眼看不见哈
z-index = -1:这就是藏起来!直接放到根元素的背后去啦,一般情况是肯定看不见咯!
CSS 动画
这一部分一般用的比较少,大家只需要熟悉那几个重要的属性就好,即插即用
- animation:用于设置动画属性(animation属性+@keyframes)
- transition:用于设置元素的样式过渡,和animation有着类似的效果,但细节上有很大的不同
- transform:用于元素进行旋转、缩放、移动或倾斜,2D或3D转换
- translate:translate只是transform的一个属性值,即移动,除此之外还有 scale 等
BulingBuling ~~~ 未完待续