(四)不只是 huohuo 的 CSS 面试题

不只是 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选择紧挨着的同级兄弟元素divp
  • 后兄弟选择器:p~ul选择 p 后面的所有兄弟元素ul
  • 并集选择器: divp选择所有divp选择器

属性选择器(CSS3)

  • E [att]:有att属性的E元素 (如input[value]
  • E [att = "val"]:有att且等于valE元素
  • E [att^= "val"]:有att且以val开头E元素
  • E [att$= "val"]:有att且以val结尾E元素
  • E [att*= "val"]:有att且含valE元素

伪类选择器

链接伪类选择器:

  • 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 轴上更靠上,最终表现就是它离屏幕观察者更近。

  • CSS3CSS带来的变化是丰富多彩的,其中就有很多会产生层叠上下文的情况:

  • 父元素的display属性值为flex/inline-flex,子元素z-index属性值不为auto的时候,子元素为层叠上下文元素

  • 元素的opacity属性值不是 1

  • 元素的transform属性值不是

  • 元素mix-blend-mode属性值不是  normal`

  • 元素的filter属性值不是` none

  • 元素的isolation属性值是`  isolate

  • will-change指定的属性值为上面任意一个

  • 元素的-webkit-overflow-scrolling属性值设置为touch

别忘了根元素HTMLz-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)。也即定位元素和层叠上下文元素是同一个层叠顺序,遵循后来居上规则。

这里附上张鑫旭老师的层叠顺序图

image-20220414143156795

z-index 的负值探索 (了解一下即可)

给一个定位元素设置负值 ,这个元素有时候会隐藏有时候不会?

原因:z-index负值渲染的过程就是一个寻找第一个层叠上下文元素的过程,然后层叠顺序止步于这个元素。

More:如果DOM顺序无法调整的情况下不得不使用z-indexz-index一定不要超过 2

继承性

子元素会继承父元素的某些样式

比如字体属性、文本属性、背景属性。但是不会继承宽高、边距

主要优势:简化代码、降低CSS样式复杂性

优先级

我们写CSS样式的时候,免不了出现多个相同的样式属性应用在同一个元素上,这时候就出现了样式覆盖以及优先级的问题,我应该优先使用哪一个样式属性呢?

这时候我们就引入了“权重”,权重越高,优先级就越高;权重相同,则采用就近原则。

选择器的权重

  • 继承 / *:0000
  • 元素选择器:0001
  • 类、伪类选择器:0010
  • id 选择器:0100
  • 行内样式:1000

当我们的样式出现嵌套或使用复合选择器的时候,尤其是我们使用less时,就需要进行权重的叠加,判定优先使用哪个样式属性

note:

优先级高的会忽视我们上面提到的层叠性和就近原则来定义样式。比如我们在样式属性后面都使用过的!important,代表着这个属性不会被覆盖,优先级最高。

上面我们提到了层叠上下文,可能你会大声呼出“好家伙,是不是还有一个叫上下文的家伙?”

BFC

BFCBlock Formatting Context(块级格式化上下文),是Web页面中盒模型布局的CSS渲染模式,是一个隔离的独立容器,它让处于BFC内部的元素与外部的元素互相隔离。

上面是的官方描述,说实话我觉得描述的有些不清不楚,我觉得应该是这样的:

BFC 是页面中的一块渲染区域,它有一套自己的渲染规则,来决定它的子元素如何在页面中渲染

如何触发 BFC

  • 根元素(HTML)或其他包含它的元素
  • 浮动
  • 定位(fixed/absolute
  • 块级元素overflow不为visible
  • 非块级元素且displayinline-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会发生重叠。重叠的规则如上。

image-20220414143708955

image-20220414143803500

说一下你刚刚提到的 CSS 盒模型

这是一个神奇的封装HTML元素的盒子,我们主要分为以下两种

标准盒模型

box-sizing:content-box

盒子的大小(宽度):width =  内容的宽度(content)+ border + padding

IE 盒模型

box-sizing:border-box

盒子的大小(宽度):width =  内容的宽度(content + border + padding)

不超过width的情况下,paddingborder的改变不会撑大盒子

一般用来初始化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;
    }
复制代码

效果:子元素内的文本水平居中

image-20220414155427434

​ 2、块级元素

给自身设置margin:0 auto

    .test {
        height: 100px;
        width: 100px;
        background-color: aqua;
        margin: 0 auto;
    }
复制代码

效果:元素自身水平居中显示,注意元素的文本内容不被影响

image-20220414155520733

​ 3、flex(主流)

元素自身设置display: flex; justify-content: center

    .son {
        display: flex;
        justify-content: center;
        background-color: blueviolet;
    }
复制代码

效果:元素的内容水平居中显示

image-20220414155719184

换给父元素设置display: flex; justify-content: center

    .parent {
        height: 100px;
        width: 100px;
        background-color: aqua;
        display: flex;
        justify-content: center;
    }

    .son {
        background-color: blueviolet;
    }
复制代码

效果:父元素的内容(其子元素)水平居中显示

image-20220414155804619

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);
    }
复制代码

效果:父元素的内容(子元素)水平居中显示

image-20220414155855337

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;
    }
复制代码

image-20220414155855337

垂直居中

1、单行文本

若元素只是一行文本,直接用行高即可

    .test {
        height: 100px;
        line-height: 100px;
        background-color: aqua;
    }
复制代码

image-20220414160142881

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;
}
复制代码

image-20220414160719825

右浮动

左浮动实现两栏布局可真简单,左右左右,不都一样嘛,那右边替换一下就好了呗!

.left{
    background-color: aqua;
}
.right{
    background-color: blueviolet;
    float: right;
}
复制代码

image-20220414160759552

但是效果图却跟预想的不一样 ~

这里的leftright元素都是使用的div标签,也就是会独占一行

<div class="left">left</div>
<div class="right">right</div>
复制代码

在左浮动中,left 被赋予了浮动属性,所以脱离了标准文档流,最后的效果达到了我们想要的样子。而右浮动,right 浮动的效果是一样的,但是第一行已经被占完了,只会在下一行显示。

有什么办法能处理掉这个潜在的Bug呢?一步步来

  1. 首先,我们保持标签的顺序不变
  2. 我们想让这两个块级元素在同一行显示
  3. 我们这里讨论的是浮动float方案

left是块级元素,如果不让它浮动(脱标),right在不改变布局特性的情况下(仍然保持标准文档流),是不可能在同一行共存的。

所以,我们对left动手

.left {
  background-color: aqua;
  float: right;
}
.right {
  background-color: blueviolet;
}
复制代码

再看看效果是不是你想要的呢

image-20220414161005074

哈哈哈哈,两栏布局实现啦,但是我们发现两个块级元素的左右位置调换了。要是面试官一定要你left在左边,right在右边,你要怎么办呢

来了来了,你要的来了

浮动 + BFC

.left {
  background-color: aqua;
  float: left;
}
.right {
  background-color: blueviolet;
  overflow: hidden;
}
复制代码

我们给left设置了浮动,其实和上面左浮动一样。但是,为了保险起见,我们做了个清除浮动处理

圣杯布局实现两列布局

浮动 + margin

左右都浮动,左边自适应元素left设置外层div100%宽度, 这样就会独占一行, 然后里层设置右边的margin, 把右边元素位置空出来

.left {
  float: left;
  width: 100%;
  background-color: aqua;
}

.right {
  float: left;
  width: 300px;
  margin-left: -300px;
  background-color: blueviolet;
}
复制代码

image-20220414161159545

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>
复制代码

image-20220414161244648

定位 + margin (需要计算宽度)

左边设置宽度,右边设置margin, 把右边元素位置空出来

.container {
  position: relative;
}
.left {
  position: absolute;
  width: 300px;
  background-color: aqua;
}
.right {
  width: 100%;
  margin-left: 300px;
  background-color: blueviolet;
}
复制代码

image-20220414161344526

再实现一下三栏布局吧

中间固定,左右两边自适应

定位 + 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>
复制代码

image-20220414161528881

浮动 + 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>
复制代码

image-20220414161637913

三列的效果达到了,但是我们还想把right也放到第一行去。

我们注意到,HTML标签顺序是:leftmiddle再到right

所以left浮动脱离标准文档流,可以跟块级元素middle在同一行,middle已经独占一行了,right就算浮动也只能换行显示了。

怎么办呢?我们不就是想让leftright都在浮middle块上显示吗,试试让他们两个先浮起来吧

我们调整一下HTML结构

<div class="container">
  <div class="left">left</div>
  <div class="right">right</div>
  <div class="middle">middle</div>
</div>
复制代码

image-20220414161528881

圣杯布局实现三栏布局

三个标签都设置左浮动

.left {
  float: left;
  width: 200px;
  background-color: aqua;
}

.right {
  float: left;
  width: 200px;
  background-color: blueviolet;
}

.middle {
  float: left;
  width: 200px;
  background-color: burlywood;
}
复制代码

image-20220414161812920

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;
}
复制代码

image-20220414161920511

布局的方式技巧丰富多样,大家要学会巧妙地应变,死记硬背是不行滴。你看我,还是得一个个来一个个试出来才行哇!一定要多多动手哦,兄 dei!

在熟悉了各种各样的布局布局布局了之后,emmmm,好多啊,太累了把,能不能来点好玩的嘛!

用 CSS 实现一个三角形

核心:宽高设置为 0,由边框来控制大小,然后边框颜色改为透明,然后更改一遍的边框颜色为自己想要的颜色

div {
  width: 0;
  height: 0;
  border: 50px solid transparent;
  border-bottom-color: red;
}
复制代码

image-20220414162104487

注意:上面这样设计的话,div的实际占位还是个方形,如下代码实现实际占位变为三角形

div {
  width: 0;
  height: 0;
  border-left: 20px solid transparent;
  border-right: 20px solid transparent;
  border-bottom-color: 20px solid red;
}
复制代码

image-20220414162159566

不错不错,你一定是一位优秀的CSS画手,可不可以再给我画一个正方形呀?我......

CSS 实现自适应正方形

意想不到的 padding

注意:padding,margin如果设置为百分比,则均是相对于父级元素的宽度而言的

.outer {
  width: 50%;
  height: 50%;
  background-color: burlywood;
}

.inner {
  padding-bottom: 100%;
  width: 100%;
  height: 0;
}
复制代码

image-20220414162318617

来自火火的温馨提示:以下未给出效果图的方法,则实际效果图同上

定位 + 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>
复制代码

image-20220414163635245

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”,响应式的pxrpx单位是微信小程序中css的尺寸单位,它可以根据屏幕宽度进行自适应。

设计稿一般使用设备宽度为750px,可以将px等比例换算成rpx(1px = 1rpx)

vw 和 vh

这才是现在CSS3适应屏幕的真正解决方案

  • vwviewpoint width,视窗宽度,1vw等于视窗宽度的 1%。

  • vhviewpoint height,视窗高度,1vh等于视窗高度的 1%。

  • vmin:取当前vwVh中较小的那一个值,

  • vmax:取当前VwVh中较大的那一个值

vwvh% 百分比的区别:

  • %是相对于父元素的大小设定的比率,vwvh是视窗大小决定的。
  • vwvh优势在于能够直接获取高度,而用%在没有设置body高度的情况下,是无法正确获得可视区域的高度的,所以这是挺不错的优势。

calc()

CSS3中新增的一个函数, 用于动态计算宽/高,一般使用数学表达式来表示

使用“+”、“-”、“*” 和 “/”四则运算 可以使用百分比、pxem、rem等单位 可以混合使用各种单位进行计算 表达式中有“+”和“-”时,其前后必须要有空格,如"width: calc(12%+5em)"这种没有空格的写法是错误的

line-height 百分比

可以直接查看MDN上的相关解释:

line-height属性被指定为以下任何一个:

  • 一个 <数字>: 该属性的应用值是这个无单位数字<数字>乘以该元素的字体大小
  • 一个 <百分比>:与元素自身的字体大小有关。计算值是给定的百分比值乘以元素计算出的字体大小
  • 一个 <长度> :必须pxem等,详细查看CSS长度
  • 关键词normal

CSS中有一个非常常见的魔术,可以实现显示和隐藏,你是否了解它们?

CSS 隐藏元素

我想你应该能很快说出,利用displayvisibility

是否占据空间 是否渲染 继承性
display: none 是(触发回流)
visibility:hidden 否(触发重绘)

opacity:0:直接把这个元素给他透明了,是不是就看不见啦,嘿嘿!但是只局限于肉眼看不见哈

z-index = -1:这就是藏起来!直接放到根元素的背后去啦,一般情况是肯定看不见咯!

CSS 动画

这一部分一般用的比较少,大家只需要熟悉那几个重要的属性就好,即插即用

  • animation:用于设置动画属性(animation属性+@keyframes
  • transition:用于设置元素的样式过渡,和animation有着类似的效果,但细节上有很大的不同
  • transform:用于元素进行旋转、缩放、移动或倾斜,2D 或 3D 转换
  • translatetranslate只是transform的一个属性值,即移动,除此之外还有scale

BulingBuling ~~~ 未完待续

猜你喜欢

转载自juejin.im/post/7086744349916004360