不只是 huohuo 的 CSS 面试题
一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第 4 天,点击查看活动详情。
终于到了 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
属性值不为auto
的时候,子元素为层叠上下文元素 -
元素的
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、行内块元素或元素高度不定(了解即可)
-
使用
display: inline-block, vertical-align: middle
和一个伪元素让内容块处于容器中央 -
父元素
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>
<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
、e
m、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 ~~~ 未完待续