大厂面试总结 CSS 篇

shanyue
English

01 如何实现一个元素的水平垂直居中

<blockquote>
更多描述: 要求对行内元素、块状元素及不定宽高的块状元素均可适用:

可打开 codepen 进行调试: https://codepen.io/shanyue/pe...,以下是布局代码

<div class="container">
  <div class="item" style="width: 100px; height: 100px; background: #999;">
    块状元素
  </div>
</div>

<div class="container">
  <div class="item">不定高宽的块状元素</div>
</div>

<div class="container">
  <span class="item">行内元素</span>
</div>
.container {
   // 把代码写在这里
}

.container {
  height: 20rem;
  background: #ccc;
  margin: 1rem;
}

</blockquote>

Issue 或者我的网站中交流与讨论: 01 如何实现一个元素的水平垂直居中

提供一些现代浏览器下使用 flex/grid 的方法,不仅支持块状元素,而且支持行内元素,对固定高宽与不固定高宽皆可使用。

使用 flex,以下是经典的垂直居中。

.container {
  display: flex;
  justify-content: center;
  align-items: center;
}

使用 grid,它是做二维布局的,但是只有一个子元素时,一维布局与二维布局就一样了。

结合 justify-content/justify-itemsalign-content/align-items 就有四种方案

效果可以见 codepen

.container {
  display: grid;
  justify-content: center;
  align-content: center;
}
.container {
  display: grid;
  justify-content: center;
  align-items: center;
}
.container {
  display: grid;
  justify-items: center;
  align-content: center;
}
.container {
  display: grid;
  justify-items: center;
  align-items: center;
}

三个属性略显啰嗦,其实只需两个属性即可:

.container {
  display: grid;
  place-items: center;
}
.container {
  display: grid;
  place-content: center;
}

02 css 如何实现左侧固定300px,右侧自适应的布局

Issue 或者我的网站中交流与讨论: 02 css 如何实现左侧固定300px,右侧自适应的布局

代码见 左侧固定,右侧自适应 - Codepen

使用 flex 布局,左侧 300px,右侧 flex-grow: 1pug 代码及 css 代码示例如下

.container
  .left
  .main
.container {
  display: flex;
}

.left {
  flex-basis: 300px;
  flex-shrink: 0;
}

.main {
  flex-grow: 1;
}

如果只使用 Grid 布局,则代码会更加简单,只需要控制容器的 CSS 属性

.container {
  display: grid;
  grid-template-columns: 300px 1fr;
}

03 有没有使用过 css variable,它解决了哪些问题

Issue 或者我的网站中交流与讨论: 03 有没有使用过 css variable,它解决了哪些问题

可在运行时动态修改 CSS。与 less/sass 相比,更加灵活,因为它很容易通过 JS 来控制。根据它来做主题切换简直得心应手。

04 谈谈你对 styled-component 的看法

Issue 或者我的网站中交流与讨论: 04 谈谈你对 styled-component 的看法

最为流行的 CSS-in-JS 方案

05 display: inline 的元素设置 margin 和 padding 会生效吗

Issue 或者我的网站中交流与讨论: 05 display: inline 的元素设置 margin 和 padding 会生效吗

可参考文章 http://maxdesign.com.au/artic...

inline 元素的 margin 与 padding 左右生效,上下生效,准确说在上下方向不会使其它元素受到挤压,仿佛不生效,如下图设置 border 会发现它其实生效了

image

代码为,可见于 行内元素的padding与margin - codepen

<div class="container">
  我是<span class="item">行内元素</span>白日依山尽,黄河入海流。欲穷千里目,更上一层楼。白日依山尽,黄河入海流。欲穷千里目,更上一层楼。白日依山尽,黄河入海流。欲穷千里目,更上一层楼。白日依山尽,黄河入海流。欲穷千里目,更上一层楼。
</div>

.item 行内元素设置样式,观察效果:

.item {
  padding: 1rem;
  border: 1px solid red;
}

.container {
  margin: 3rem;
  background-color: #ccc;
  height: 10rem;
}

06 html 的默认 display 属性是多少

Issue 或者我的网站中交流与讨论: 06 html 的默认 display 属性是多少

html 根元素的默认 displayblock

07 对一个非定长宽的块状元素如何做垂直水平居中

Issue 或者我的网站中交流与讨论: 07 对一个非定长宽的块状元素如何做垂直水平居中

css position

        .container {
            position: relative;
        }
        .container .item {
            width: 100px;
            height: 50px;
            position: absolute;
            top: 0;
            left: 0;
            bottom: 0;
            right: 0;
            margin: auto;
        }

非定宽了,你这个不行呀

08 如何实现左右固定,中间自适应布局

Issue 或者我的网站中交流与讨论: 08 如何实现左右固定,中间自适应布局

可以参考 【Q017】css 如何实现左侧固定300px,右侧自适应的布局

.container
  .left
  .main
  .right
.container {
  display: flex;
}

.left {
  flex-basis: 300px;
  flex-shrink: 0;
}

.right {
  flex-basis: 300px;
  flex-shrink: 0;
}

.main {
  flex-grow: 1;
}

09 如何实现表格单双行条纹样式

Issue 或者我的网站中交流与讨论: 09 如何实现表格单双行条纹样式

通过 css3 中伪类 :nth-child 来实现。其中 :nth-child(an+b) 匹配下标 { an + b; n = 0, 1, 2, ...} 且结果为整数的子元素

  • nth-child(2n)/nth-child(even): 双行样式
  • nth-child(2n+1)/nth-child(odd): 单行样式

其中 tr 在表格中代表行,实现表格中单双行样式就很简单了:

tr:nth-child(2n) {
  background-color: red;
}


tr:nth-child(2n+1) {
  background-color: blue;
}

同理:

  1. 如何匹配最前三个子元素: :nth-child(-n+3)
  2. 如何匹配最后三个子元素: :nth-last-child(-n+3)

10 简述下 css specificity

Issue 或者我的网站中交流与讨论: 10 简述下 css specificity

css specificity 即 css 中关于选择器的权重,以下三种类型的选择器依次下降

  1. id 选择器,如 #app
  2. classattributepseudo-classes 选择器,如 .header[type="radio"]:hover
  3. type 标签选择器和伪元素选择器,如 h1p::before

其中通配符选择器 *,组合选择器 + ~ >,否定伪类选择器 :not() 对优先级无影响

另有内联样式 <div class="foo" style="color: red;"></div>!important(最高) 具有更高的权重

:not 的优先级影响 - codepen 可以看出 :not 对选择器的优先级无任何影响

CSS Specificity - codepen 可以看出十几个 class 选择器也没有一个 id 选择器权重高

11 '+' 与 '~' 选择器有什么不同

Issue 或者我的网站中交流与讨论: 11 '+' 与 '~' 选择器有什么不同
  • + 选择器匹配紧邻的兄弟元素
  • ~ 选择器匹配随后的所有兄弟元素

12 position: sticky 如何工作,适用于哪些场景

Issue 或者我的网站中交流与讨论: 12 position: sticky 如何工作,适用于哪些场景

position: sticky 可理解为 relativefixed 的结合体

13 伪类与伪元素有什么区别

Issue 或者我的网站中交流与讨论: 13 伪类与伪元素有什么区别
  1. 伪类使用单冒号,而伪元素使用双冒号。如 :hover 是伪类,::before 是伪元素
  2. 伪元素会在文档流生成一个新的元素,并且可以使用 content 属性设置内容

参考 https://www.w3.org/TR/CSS2/se...

14 css 如何匹配前N个子元素及最后N个子元素

Issue 或者我的网站中交流与讨论: 14 css 如何匹配前N个子元素及最后N个子元素

【Q307】如何实现表格单双行条纹样式

  • 如何匹配最前三个子元素: :nth-child(-n+3)
  • 如何匹配最后三个子元素: :nth-last-child(-n+3)

15 如何使用 CSS 实现网站的暗黑模式 (Dark Mode)

<blockquote>
更多描述: 可参考以下文章:

  1. Dark mode in 5 minutes, with inverted lightness variables
    </blockquote>
Issue 或者我的网站中交流与讨论: 15 如何使用 CSS 实现网站的暗黑模式 (Dark Mode)
@media (prefers-color-scheme: dark) {
    :root{
    }
}

16 介绍隐藏页面中某个元素的几种方法

Issue 或者我的网站中交流与讨论: 16 介绍隐藏页面中某个元素的几种方法

01 display: none

通过 CSS 操控 display,移出文档流

display: none;

02 opacity: 0

透明度为0,仍在文档流中,当作用于其上的事件(如点击)仍有效

opacity: 0;

03 visibility: hidden

透明度为0,仍在文档流中,但作用于其上的事件(如点击)无效,这也是 visibility:hiddenopacity: 0 的区别

visibility: hidden;

04 content-visibility

移出文档流,但是再次显示时消耗性能低

content-visibility: hidden;

05 绝对定位于当前页面的不可见位置

position: absolute;
top: -9000px;
left: -9000px;

06 字体大小设置为 0

font-size: 0;

17 css 如何实现响应式布局大屏幕三等分、中屏幕二等分、小屏幕一等分

Issue 或者我的网站中交流与讨论: 17 css 如何实现响应式布局大屏幕三等分、中屏幕二等分、小屏幕一等分

页面布局元素如下,item 数量不固定

<div class="container">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

使用 Grid 布局可以轻松解决这个问题,如若使用其它方案,控制好等分的同时再控制好间距也是一个十分头疼的问题:

  1. grid-template-columns: 控制等分
  2. gap: 控制间隙

效果可见 codepen

@media (min-width: 768px) {
  .container {
    grid-template-columns: repeat(2, minmax(0,1fr));
  }
}

@media (min-width: 1024px) {
  .container {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.container {
  display: grid;
}

.conainer {
  gap: 1rem;
}

TailwindCSS 是一款非常方便的 CSS 原子类框架,只需要一行即可搞定

<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"></div>

但是这就够了吗?

这远远不够,这也足够复杂!

  1. 需要媒体查询
  2. 需要人为设置 breakpoint,设置大小屏幕的边界

终极解决方案

Grid 布局可以自动判断容器大小,无论大小屏幕自动撑满并均分,请看以下属性

.container {
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr))
}
  1. repeat: 用以 N 整分
  2. auto-fill:表示自动填充
  3. minmx: 即书面意思,最小宽度为 300px

使用终极解决方案的在线页面

18 如何自定义滚动条的样式

Issue 或者我的网站中交流与讨论: 18 如何自定义滚动条的样式

滚动条相关样式都是伪元素,以 scrollbar 打头,有以下伪元素,从 -webkit 中可见兼容性一般,不过无所谓,现在 Chrome 浏览器占大头

  • ::-webkit-scrollbar — 整个滚动条.
  • ::-webkit-scrollbar-button — 滚动条上的按钮 (上下箭头).
  • ::-webkit-scrollbar-thumb — 滚动条上的滚动滑块.
  • ::-webkit-scrollbar-track — 滚动条轨道.
  • ::-webkit-scrollbar-track-piece — 滚动条没有滑块的轨道部分.
  • ::-webkit-scrollbar-corner — 当同时有垂直滚动条和水平滚动条时交汇的部分.
  • ::-webkit-resizer — 某些元素的corner部分的部分样式(例:textarea的可拖动按钮).

但其实最常用的是以下几个伪元素:滚动条、滑块、轨道,如下滚动条设置成功

::-webkit-scrollbar {
    width: 6px;
    height: 6px
}

::-webkit-scrollbar-track {
    border-radius: 3px;
    background: rgba(0,0,0);
    box-shadow: inset 0 0 5px rgba(0,0,0,.08)
}

::-webkit-scrollbar-thumb {
    border-radius: 3px;
    background: rgba(0,0,1);
    box-shadow: inset 0 0 10px rgba(0,0,0,.2)
}

19 网站设置字体时,如何设置优先使用系统默认字体

Issue 或者我的网站中交流与讨论: 19 网站设置字体时,如何设置优先使用系统默认字体
font-family: system-ui;

system-ui 将会自动选取系统默认字体作为字体,如 bootstrap 的样式规则

$font-family-sans-serif: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "Liberation Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji" !default;

20 写 CSS 时如何避免命名样式冲突

Issue 或者我的网站中交流与讨论: 20 写 CSS 时如何避免命名样式冲突

1. BEM 式: .home-page .home-page-btn

.home-page {
  .home-page-btn {}
}

BEM 有一个缺点,就是有些太长,可适当简化,只包裹该页面组件的根类名,但有可能增加样式冲突的风险

.home-page {
  .btn {}
}

2. CSS Scoped

scoped css 会对当前组件(scope)下所有元素生成唯一的属性或类名,对所有 CSS 规则将携带唯一属性实现作用域的命名保护

// 手动写
.btn {}

// 编译后
.btn .jsx-1287234 {}

css scoped demo

3. CSS Module

module css 会对类名进行 hash 化

css modules demo

21 HTML 标签有哪些行内元素

Issue 或者我的网站中交流与讨论: 21 HTML 标签有哪些行内元素

常见的标签有以下几种,可参考 inline element

  • a
  • img
  • picture
  • span
  • input
  • textarea
  • select
  • label

22 CSS如何设置一行超出显示省略号

Issue 或者我的网站中交流与讨论: 22 CSS如何设置一行超出显示省略号
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;

23 CSS如何设置多行超出显示省略号

Issue 或者我的网站中交流与讨论: 23 CSS如何设置多行超出显示省略号

使用 -webkit-line-clamp 来设置多行超出显示省略号

overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;

24 flex 布局中 order 有何作用

Issue 或者我的网站中交流与讨论: 24 flex 布局中 order 有何作用

order 属性定义Flex布局中子元素的排列顺序,数值越小,排列越靠前,默认为0。

25 flex 布局中 align-content 与 align-items 有何区别

Issue 或者我的网站中交流与讨论: 25 flex 布局中 align-content 与 align-items 有何区别

示例代码见: align-content 与 align-items

  • align-content 作用于纵轴多行元素,一行元素不起作用
  • align-items 作用于纵轴单行元素

下图,上部分为 align-content,下部分为 align-items

image

26 子元素垂直居中,并且长度为父容器一半的正方形

Issue 或者我的网站中交流与讨论: 26 子元素垂直居中,并且长度为父容器一半的正方形

垂直居中长度为父容器一半的子元素 - Codepen

<div class="container">
  <div class="item"></div>
</div>

以前采用百分比撑高 padding,那这种方案已经过时,会挤压 Content 内容,无法在其中填充内容(需要绝对定位)。

可使用最新的属性 aspect-ratio,即长宽比

.container {
  display: grid;
  place-items: center;
}

.item {
  width: 50%;
  aspect-ratio: 1/1;
}

27 简述 css 中 position 的值

Issue 或者我的网站中交流与讨论: 27 简述 css 中 position 的值
  • static: 默认值,无定位,toprightbottomleft 不起任何作用
  • relative: 相对定位
  • absolute: 绝对定位,脱离文档流,上下左右以最近的定位父元素为参照系
  • fixed: 脱离文档流,上下左右以浏览器视口为参照系
  • sticky: relativefixed 的结合体

28 什么是 BFC

<blockquote>
更多描述: + 它是如何生成的

  • 它有什么作用及应用
    </blockquote>
Issue 或者我的网站中交流与讨论: 28 什么是 BFC

块级格式化上下文,Block Formatting Context

29 CSS 如何实现固定长宽比的元素

Issue 或者我的网站中交流与讨论: 29 CSS 如何实现固定长宽比的元素

过去的解决方案是使用 padding。一个元素的 padding 如若设置为百分比,则代表的是以父元素宽度为基准,根据这个原理,可设置长宽比。但实际上意义有限,毕竟你把 padding 给占了,content 无任何区域。

现代化的解决方案是使用长宽比的 CSS 属性: aspect-ratio

30 rem、em、vw、wh 的值各是什么意思

Issue 或者我的网站中交流与讨论: 30 rem、em、vw、wh 的值各是什么意思

他们同属于 CSS Data Type 中的 [length],见文档 length - MDN

  • rem: 根据根元素(即 html)的 font-size
  • em: 根据自身元素font-size
  • vw: viewport width
  • vh: viewport height

31 normalize.css 与 reset.css 又何区别

Issue 或者我的网站中交流与讨论: 31 normalize.css 与 reset.css 又何区别

What is the difference between Normalize.css and Reset CSS?

  • normalize.css: 会保留有用的样式,比如 h1 的字体大小
  • reset.css: 把所有样式都重置,比如 h1、h2、h3 的字体大小都进行了重置,保持了无样式

32 line-height 的值分别取 [2, 2em, 200%] 有什么区别?

Issue 或者我的网站中交流与讨论: [32 line-height 的值分别取 [2, 2em, 200%] 有什么区别?](https://q.shanyue.tech/fe/css...

代码见: lineHeight - codepen

line-height 是相对于元素自身的字体大小来取值,但同时会被继承。在实际工作中,取值 2em 或者 200% 有可能遇到未预测的内容。

比如:

  • 父元素: fontSize: 18px; lineHeight: 1.5em(27px,150% 同理); ,它的 lineHeight 计算下来为 27px,会被子元素继承
  • 子元素: fontSize: 30px,子元素的 lineHeight 被继承为 27px,出现问题

以下为演示代码,见: lineHeight - codepen

<div class="box green">
  <h1>lineHeight: 1.5; 这是没有问题的框框</h1>
  lineHeight: 1.5; 这是没有问题的框框
  lineHeight: 1.5; 这是没有问题的框框
</div>

<div class="box red">
 <h1>lineHeight: 1.5em; 这是有问题的框框</h1>
  lineHeight: 1.5em; 这是有问题的框框
  lineHeight: 1.5em; 这是有问题的框框
</div>

<div class="box orange">
 <h1>lineHeight: 150%; 这是有问题的框框</h1>
  lineHeight: 150%; 这是有问题的框框
  lineHeight: 150%; 这是有问题的框框
</div>
.green {
  line-height: 1.5;
  border: solid limegreen;
}

.red {
  line-height: 1.5em;
  border: solid red;
}

.orange {
  line-height: 150%;
  border: solid orange;
}

h1 {
  font-size: 30px;
}

.box {
  width: 18em;
  display: inline-block;
  vertical-align: top;
  font-size: 16px;
}

33 Grid 布局的优势在哪里

Issue 或者我的网站中交流与讨论: 33 Grid 布局的优势在哪里

响应式!

34 如何实现三列均分布局

<blockquote>
更多描述: 布局代码如下所示,可见 三列均分布局 - codepen

注: 在第一个元素中设置文字,子元素不能因文字过长而挤压。
<div class="container">
  <div class="item">白日依山尽,黄河入海流。欲穷千里目,更上一层楼。</div>
  <div class="item"></div>
  <div class="item"></div>
</div>

// 以下为样式代码,非核心功能代码
* {
  box-sizing: border-box;
}

.container {
  background-color: #eee;
  height: 10rem;
  width: 40rem;
  margin: 1rem;
}

.item {
  border: 1px solid #888;
}

</blockquote>

Issue 或者我的网站中交流与讨论: 34 如何实现三列均分布局

见代码 三均分布局 - Codepen

使用 Flex

注意使用 calc(100% / 3) 设置 flex-basis,同时它的缺陷是不能够很好的为子元素设置左右间隙

.flex-container {
  display: flex;
  flex-wrap: wrap;
  // gap: 1rem;


  .item {
   flex: 0 0 calc(100% / 3);
  }
}
注意: 如果同时给子元素使用 flex-grow: 1 控制均分,当子元素拥有文字等内容时,会受到挤压,将无法实现均分布局。

使用 Grid

使用 Grid 直接操作容器即可,对于子元素之间的间隙也可以很好地控制,可看出 Grid 更为简单,更为高效,更为精确

.grid-container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: 1rem;
}

35 z-index: 999 元素一定会置于 z-index: 0 元素之上吗

Issue 或者我的网站中交流与讨论: 35 z-index: 999 元素一定会置于 z-index: 0 元素之上吗

代码见 zindex - codepen

不可,更复杂的示例见 层叠上下文 - MDN

阅读 1.3k

程序员的自我成长
对一些学习的总结

暮从碧山下,山月(shanyue)随人归。

4.5k 声望
679 粉丝
0 条评论
你知道吗?

暮从碧山下,山月(shanyue)随人归。

4.5k 声望
679 粉丝
宣传栏