HTML 和 CSS


大纲链接 §

[toc]


必考概念题:你是如何理解 HTML 语义化的?

举例法

  • 回答:我平时写代码都用的是语义化标签
  • HTML 语义化就是使用正确的标签(总结)
    • 只看标签,就能了解这个元素的意义
    • 阅读 HTML 源码,就能了解网页大致结构,利于团队 维护
    • 提供无障碍优化,浏览器焦点管理
  • 比如:
    • 段落就写 p 标签
    • 标题就写 h1~h6 标签
    • 文章就写 article 标签
    • 文章章节用 section
    • 主要内容用 main
    • 边栏用 aside
    • 导航用 nav
    • 视频就写 video 标签 可忽略
    • 音频就写 audio 标签 可忽略
    • 时间就写 time 标签
    • 画板就用 canvas 标签(DOM API getContext('2d') 操作属性)
    • 矢量图形就用 svg 标签
  • 反向回答:无明确语义的标签 div span

阐述法

  • 以前的后台开发人员使用 table 布局
  • 美工人员使用 div + css 布局
  • 专业的前端会使用正确的标签进行页面开发

概念题分六步回答

  1. 是什么:语义化标签是一种写 HTML 标签的方法论/方式,即使用 符合英语语义 的标签来表示对应的内容
  2. 怎么做:实现方法是:标题就用 h1 ~ h6,段落用 p,文章用 article,文章章节用 section,主要内容用 main,边栏用 aside,导航用 nav……(就是找到中文对应的英文)
  3. 解决了什么问题:明确了 HTML 的 书写规范
  4. 优点是:
  • 一、适合 搜索引擎检索 SEO
  • 二、适合开发者阅读源码,利于团队 维护
  • 三、提供无障碍访问优化:Web 无障碍访问 (accessibility也称为 a11y),浏览器焦点管理等
  1. 缺点是:没有
  2. 怎么解决缺点:无需解决

参考


记忆题:meta viewport 是做什么用的,怎么写?

  • 标记网页元信息的标签<meta>,其中的一类表示浏览器 视口
  • 屏幕可见区域内容的呈现机制
  • 移动端应用场景: 禁止用户缩放

举例法

  • <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  • meta
  • name="viewport" 视口属性
  • content 内容属性
    • width=device-width 宽度
    • initial-scale 初始尺寸(倍数)
    • maximum-scale 最大尺寸(倍数)
    • minimum-scale 最小尺寸(倍数)

一般可参考淘宝等大厂的写法

  • <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
    • name="viewport"
    • content
      • width=device-width
      • initial-scale=1
      • minimum-scale=1
      • maximum-scale=1
      • user-scalable=no
      • viewport-fit=cover

记忆题:你用过哪些 HTML 5 标签?

  • 文章相关:header main footer nav aside section article figure mark time 等标签

  • 多媒体相关:video audio svg canvas

  • 表单input新增:type=email type=tel

  • 不要提不熟悉的标签,很可能变为下一道题

记忆题 使用举例法

  • <header>可以表示整个网页的头部,也可以表示一篇文章或者一个区块的头部
    • 如果用在网页的头部,就称为“页眉”
    • 网站导航搜索栏 通常会放在<header>里面
  • <footer>表示网页、文章或章节的尾部
    • 如果用于整张网页的尾部,就称为“页尾”
    • 通常包含 版权信息 或者其他相关信息
  • <header><footer>不能互相嵌套,一个具体的场景里面只能包含一个<header><footer>
  • <main>表示页面的主体内容,一个页面只能有一个
  • <article>表示一篇文章,可以有自己的标题h1~h6,段落p,章节<section>
  • <aside>来放置侧边栏
  • <section> 通常用在文档里面表示一个章节,<article>可以包含多个<section>
  • <nav>标签用于放置页面或文档的导航信息,可放置ul > li ol
  • <h1> ~ <h6>表示文章的标题
  • 适当提一些在项目中使用的例子
    • 我在share blog共享博客项目中,整个布局就是使用header main footer nav

区分题:Canvas 和 SVG 的区别是什么?

区分题答题思路为:

  1. 先说一
  2. 再说二
  3. 再说相同点
  4. 最后说不同点

标准答案:

  1. Canvas 主要是用 笔刷 来绘制 2D 图形
  2. SVG 主要是用 svg标签(xml标签) 来标记绘制 矢量图
  3. 相同点:都是主要用来画 2D 图形
  4. 不同点1:
  • <canvas>调用canvas API方法(canvas.getContext('2d'))生成位图图像
  • SVG 则是一个 XML 文件,通过各种子元素生成图像,可使用JS 操作 SVG DOM
  1. 不同点2:SVG 支持分层和事件,Canvas 不支持,但是可以用库实现。
  2. 不同点3:SVG 矢量图形放大不失真 非像素点

不同点详细

  • Canvas 画的是 基于像素的 位图,SVG 画的是无损的 矢量图
  • SVG 节点过多时渲染慢,Canvas 性能更好一点,但由于是使用JS脚本调用各种API,写起来更复杂
  • SVG 支持分层和事件,Canvas 不支持,但是可以用库实现
    • 比如Echarts.jsCanvas模式
  • SVG 图像可单向转为 Canvas 图像
    • 用到的API:new Image() new Blob() window.self.URL.createObjectURL(svg) 类似base64编码图片
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<svg width="100" height="100">
  <rect width="150"
        height="75"
        style="fill: rgb(0, 0, 20); stroke-width: 3; stroke: rgb(0, 0, 0);"
  />
</svg>

<canvas id="myCanvas"
        width="100"
        height="100">
</canvas>
<script>
  const c = document.getElementById('myCanvas')
  const cxt = c.getContext('2d')
  cxt.fillStyle = '#f00'
  cxt.fillRect(0, 0, 150, 75)
</script>
  • SVG 可用直接标签来表示形状,线条,轮廓等图形以及文字
  • SVG 可用直接使用CSS写样式属性
  • Canvas 通过脚本描述的 动态绘制图形
  • Canvas 的图形基于像素

Canvas优势

  • 绘制出的图形 渲染性能 好于SVG
  • 适合数据量大的情况
  • 大量图形高频交互
  • 可以导出常用格式的图片

SVG优势

  • 矢量图放大不失真
  • 基于标签,支持事件处理器 和 分层结构
  • 文字独立、可编辑、可读取、可搜索

Echarts.js应用

  • 复杂的图表更适合Canvas

扩展

项目

  • 我在项目中使用svg
  • 通常使用 阿里图标库 iconfont 通过svg -spirit 的精灵图形式 引入js脚本 在svg标签中使用
  • 使用一些第三方库
    • vue svgo
  • 好处是:相对于图片体积小 请求一个脚本 也可以作为本地脚本资源引

概念题:H5 是什么?

阐述法

  • H5表示移动端页面,活动页,而不是HTML5

必考区分题:两种盒模型分别说一下

答题思路为:先说一,再说二,再说相同点,最后说不同点

  • 设置盒模型的属性为box-sizing,可取值为以下两种:
    • 第一种盒模型是 content-box
    • 第二种盒模型是 border-box
  • 相同点是都是用来 指定元素宽高 的方式
  • 不同点是 border-box 更符合习惯/直觉,不用额外考虑 盒子实际尺寸,将padding + border计算在内,使用起来更方便
    • content-box元素的 宽高 指定的仅仅是 content 区域宽度,而不是实际宽度
      • 元素的实际宽高为 width/height + padding + border 计算不方便 不符合直觉
    • border-box元素的 宽高 指定的是包含 边框 border 内的距离
      • 元素的实际宽高为 width/height

记忆题:flex 怎么用,常用属性有哪些?

  • 适用于响应式布局,局部细节节点的布局,属于一维布局
  • 常用API

记忆题:grid 怎么用,常用属性有哪些?

  • 适用于响应式布局,全局页面的整体布局,属于二维布局
  • 常用API

必考概念题:BFC 是什么?(作用/副作用/触发条件)

概念 特性 作用 触发条件

  • 是什么(翻译成中文):「块级格式化上下文」
  • 怎么做(触发条件):OFPD
    • Ooverflow 属性值不为默认值 visible 的块元素(实现做法:添加父元素,并在该父元素上加 overflow: hidden;)
    • F:元素的 float属性 不是 none(将浮动属性设为float: left/right; 浮动元素)
    • P:元素的 position属性 不为 relativestaticposition: absolute/fixed/sticky; 绝对/固定/黏性定位元素)
    • Ddisplay: inline-block/flex/inline-flex/grid/inline-grid/...; 行内块元素 / 弹性元素 直接子元素 就可形成*FC
  • 解决了什么问题:
    • 清除浮动(为什么不用 .clearfix::after{display: block;clear: both;} 呢?)
      • 避免父级元素高度塌陷
      • 清除 BFC 区域外部浮动,避免重叠
      • 内部浮动,不让 BFC 区域内的浮动元素“越界”影响区域外的布局, 使其被浮动被限制于 BFC 区域内
    • 防止 垂直方向 父子/相邻元素 margin 合并,隔离元素
    • 某些古老的布局方式会用到(已过时)
  • 优点:无
  • 缺点:有副作用
  • 怎么解决缺点:使用最新的 display: flow-root; 来为元素创建 BFC,就没有副作用了,从而实现清除元素外部浮动,避免元素被覆盖

隔离元素

  • BFC 区域内部元素的布局,不会“越界”影响外部元素布局
  • 外部元素布局也不会“穿透”,影响 BFC 区域内部布局

根元素 html 天然就会创建 BFC

  • iframe 会创建一个 html,所以 iframe 也会天然创建 BFC
  • display 值为 flow-root 的元素。flow-root 可以创建一个无副作用的 BFC,模拟 html 根元素

FC 的全称是 Formatting Context,种类有:

  • BFC(Block Formatting Context)块级格式化上下文
  • IFC(Inline Formatting Context)行内级格式化上下文
  • GFC(Grid Formatting Context)栅格格式化上下文
  • FFC(Flex Formatting Context)弹性格式化上下文
  • CSS2.1 中只有 BFC 和 IFC,CSS3 中才有 GFC 和 FFC

记忆题:CSS 选择器优先级

样式的权值越大越优先 A > B > C > D

  1. 内联样式表的权重值最高 A
  2. ID 选择器的权值为 B
  3. Class 类/伪类/属性 选择器的权值为 C
  4. HTML 标签/伪元素 选择器的权值 D

补充

  • 等级越高的优先级越高:内联样式表 > ID选择器 > 类选择器 > 标签选择器
  • 同等级 越具体 优先级越高:.aaa .bbb {} > .aaa {}
  • 同等优先级,写在 后面覆盖前面
  • 样式权重可累加计算(各等级间/同等级嵌套元素间),但无进位关系
  • !important 优先级最高,但基本不用
  • 浏览器的默认样式权重低于网页内容中的样式
  • 继承的 CSS 样式权重低于后来指定的样式
  • 通配选择符* 关系选择符 +相邻兄弟, >子, ~同级兄弟, ' '后代 和 否定伪类:not()`对优先级没有影响
  • 但在 :not() 内部声明的选择器会影响优先级
  • @layer 级联层语法 可控制 级联层间 样式的优先级
    • 先定义级联层命名和顺序
    • 后写具体样式实现

记忆题:清除浮动说一下

背代码

  • 方法一:使用伪元素::after,给父元素加上.clear-fix类,子元素的浮动就被清除了
  • 关键是clear: both;属性
1
2
3
4
5
6
7
8
.clear-fix::after {
  content: '';
  display: block; /*或者 table*/
  clear: both;
}
.clear-fix {
  zoom: 1; /* IE 兼容*/
}
  • 方法二,给父元素加上 overflow: hidden;

必考实践题:如何垂直居中?

  • 基于box-sizing: border-box;
  • 最常用法flexalign-items: center;
  • 进阶用法gridalign-items: center;
  • 超级居中 flex / grid: place-items: center;
  • 古老用法absolute top/bottom/left/right: 0; margin: auto;
  • 普通用法absolute 元素定位+移动 top/left:50%(子元素宽高)
    • margin移动:margin-top/margin-left设置为-50%(子元素宽高)
    • translate移动子元素的 -50%transform: translate(-50%,-50%);
  • HACK用法 inline-block伪元素 0高0宽 伪元素撑开父元素 vertical-align: middle;

不写死父元素的height

  • .parent 的 height 不写,只需 padding: 10px 0; 就能将 .child 垂直居中

水平居中

  • 只需要变换 height/width X/Y top/left column/row align-items/justify-content; 等属性位置

实践题:如何处理文本的溢出显示

如何实现 单行文本溢出显示 省略号?

  • 设置 overflow: hidden; 属性
  • 设置 text-overflow: ellipsis; 属性
  • 设置 white-space: nowrap; 属性
  • 设置 width 固定宽度 属性
1
2
3
4
5
6
7
.omit-single {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* 定宽 */
  max-width: 90vw;
}

如何实现 多行文本溢出显示 省略号?

  • 设置 overflow: hidden; 属性,DOM盒内容超出显示
  • 设置 text-overflow: ellipsis; 属性,文字内容超出显示
  • 设置 white-space: nowrap; 属性,是否折行
  • 设置 word-wrap: break-word; 属性,断字折行
  • 设置 display: -webkit-box; 属性,元素显示模式
  • 设置 -webkit-box-orient: vertical; 方向属性
  • 设置 -webkit-line-clamp: 3; 属性,保留行数
  • 设置 width & height 宽高 属性
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
.omit-multi {
  display: -webkit-box;
  overflow: hidden;
  text-overflow: ellipsis;
  word-wrap: break-word;
  white-space: normal !important;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  /* 固定宽高 */
  max-height: 4em;
  max-width: 90vw;
}

如何实现 多行文本溢出显示 透明蒙层CSS mask

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
:root {
  --height: 24px;
}

.mask {
  margin: auto;
  width: 450px;
  line-height: var(--height);
  font-size: 20px;
  overflow: hidden;
  word-wrap: break-word;
  white-space: normal;

  /* box */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;

  /* mask */
  -webkit-mask: linear-gradient(270deg, transparent, transparent 30%, #000),
  linear-gradient(270deg, #000, #000);
  -webkit-mask-size: 100% 66px, 100% calc(100% - var(--height));
  -webkit-mask-position: bottom, top;
  -webkit-mask-repeat: no-repeat;
}
  • 在使用的时候,不再需要再去添加一个用于蒙层的盒子
  • 只需要在文段上使用mask加上一层遮罩
  • mask在单独使用的时候,会默认设置100%的宽高
  • 所以这里一共定义了两个遮罩,一个在上方,一个在末行 占据剩下的位置

参考


实践题:如何快速实现元素靠右对齐

有以下几种实现方法:

  1. 第一种:flex盒子中设置 justify-content: flex-end;
  2. 第二种:父、子节点 设置宽度值
  • 设置 子节点 margin-left: auto;
  • 左边自适应撑开,左边自动占据了剩余的全部宽度
  • 右边是容器盒子设置的宽度
  • 具体见 《css权威指南》 P170
  1. 第三种:position: absolute;元素 定位设置 right: 0;
  2. 第四种:float: right;

实现10种现代布局

1.实现超级居中

1
2
3
4
.parent {
  display: grid;
  place-items: center;
}
  • 是以下两个 CSS 属性的简写:
    • align-items
    • justify-items
  • MDN place-items

Super Centered


2.卡片弹性自适应

1
2
3
4
5
<div class="parent">
  <div class="box">1</div>
  <div class="box">2</div>
  <div class="box">3</div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.parent {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

.box {
  flex: 1 1 150px;
  /* flex: 0 1 150px; */ /*  No stretching: */
  margin: 5px;
}
  • flex-grow: 1 表示自动延展到最大宽度

3.网格列实现 经典侧边栏

  • grid-template-columns: minmax(<min>, <max>) ... 网格列
1
2
3
4
5
6
7
8
9
<div class="parent">
  <aside>
    Min: 150px / Max: 25%
  </aside>
  <main>
    This element takes the second grid position (1fr), meaning
    it takes up the rest of the remaining space.
  </main>
</div>
1
2
3
4
.parent {
  display: grid;
  grid-template-columns: minmax(150px, 25%) 1fr;
}
  • 边栏:最小为150px,最大为父容器的25%
  • 内容:1fr 占据剩余空间总的 1等份 <flex>CSS单位

  • grid-template-rows: auto 1fr auto; 网格行
  • 固定高度的 header 和 footer
  • 占据剩余空间的 body 高度可变
  • 利用 grid 和 fr 单位完美实现
1
2
3
4
5
<div class="parent">
  <header>Header</header>
  <main> Main Content</main>
  <footer>Footer</footer>
</div>
1
2
3
4
.parent {
  display: grid;
  grid-template-rows: auto 1fr auto;
}

5.网格布局实现 经典圣杯 classical holy Grail layout

  • 使用 Grid 布局来实现圣杯布局,并且是弹性的
  • grid-template: auto 1fr auto / auto 1fr auto;,表示网格模板简写,一种表示方式为:
  • grid-template 行列隐式生成
  • 所简写属性:grid-template-rowsgrid-template-columnsgrid-template-areas
    • 定义网格线的名称和网格轨道的尺寸大小
    • grid-template-columns 网格列
    • grid-template-rows 网格行
  • grid-column 指定竖栏网格线(划定起始和终止线)放置元素
    • grid-column-startgrid-column-end 的简写属性
1
2
3
4
5
6
7
<div class="parent">
  <header>Header</header>
  <nav>Left Sidebar</nav>
  <main> Main Content</main>
  <aside>Right Sidebar</aside>
  <footer>Footer</footer>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
.parent {
  display: grid;
  grid-template: auto 1fr auto / auto 1fr auto;
  grid-template-areas: none;
}

header {
  padding: 2rem;
  grid-column: 1 / 4;
}

nav {
  grid-column: 1 / 2;
}

main {
  grid-column: 2 / 3;
}

aside {
  grid-column: 3 / 4;
}

footer {
  grid-column: 1 / 4;
}

6.跨列 columns 网格 Span Grid

  • grid-template-columns 指定竖栏 和 项目grid-column划线放置,结合repeat函数 和 fr单位
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
.parent {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}

.span-12 {
  grid-column: 1 / span 12;
}

.span-6 {
  grid-column: 1 / span 6;
}

.span-4 {
  grid-column: 4 / span 4;
}

.span-2 {
  grid-column: 3 / span 2;
}

/* centering text */
.section {
  display: grid;
  place-items: center;
  text-align: center;
}

7.卡片网格自适应

RAM 技巧:repeatauto-fitminmax

  • 适用网格布局 图片/卡片 ,一行可以排放(或叠放)的相同尺寸卡片数量,并自动适应
  • grid-template-columns结合repeat(auto-fit, minmax(150px, 1fr))
  • 使用单位fr实现和flex相同的自适应功能
1
2
3
4
5
<div class="parent">
  <div>Card 1</div>
  <div>Card 2</div>
  <div>Card 3</div>
</div>
1
2
3
4
5
.parent {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
}
  • MDN repeat(, )
    • 以更紧凑的形式,写入大量显示重复模式的列或行
    • 用于 CSS Grid 属性中 grid-template-columnsgrid-template-rows
  • MDN auto-fit
    • repeat()取值
  • MDN minmax()
    • 定义了一个长宽范围的闭区间, 与CSS 网格布局一起使用
  • MDN fr单位
    • 代表网格容器中可用空间的一等份

8. 多卡片内容排齐

  • grid 更精确地控制 整体/区域(面性内容) 排版样式
  • flex 控制内部 线性内容 排版样式
    • justify-content: space-between
1
2
3
4
5
6
7
8
<!-- vue 模板语法 -->
<div class="parent">
  <div v-for="item in data" class="card">
    <h3>{{ item.title }}</h3>
    <p>{{ item.msg }}</p>
    <div class="visual"></div>
  </div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
.parent {
  height: auto;
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(3, 1fr);
}

.visual {
  height: 100px;
  width: 100%;
}

.card {
  display: flex;
  flex-direction: column;
  padding: 1rem;
  justify-content: space-between;
}

9.剪裁clamp流式排版 fluid typography

  • clamp(<min>, <actual>, <max>)
  • 适合包含阅读内容的卡片
1
2
3
4
5
6
7
<div class="parent">
  <div class="card">
    <h1>Title Here</h1>
    <div class="visual"></div>
    <p>Descriptive Text. Lorem ipsum dolor sit, amet consectetur adipisicing elit. Sed est error repellat veritatis.</p>
  </div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
.parent {
  display: grid;
  place-items: center;
}

.card {
  width: clamp(18em, 50%, 32em);
  display: flex;
  flex-direction: column;
  padding: 1rem;
}

.visual {
  height: 125px;
  width: 100%;
}

10.完美实现比例

  • aspect-ratio: <width> / <height>
  • 期望图片、video、卡片能够按照固定的比例进行布局
1
2
3
4
5
6
7
<div class="parent">
  <div class="card">
    <h1>Video Title</h1>
    <div class="visual"></div>
    <p>Descriptive Text. This demo works in Chromium 84+.</p>
  </div>
</div>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
.parent {
  display: grid;
  place-items: center;
}

.visual {
  aspect-ratio: 16 / 9;
}

.card {
  width: 50%;
  display: flex;
  flex-direction: column;
  padding: 1rem;
}


参考文章

相关文章


  • 作者: Joel
  • 文章链接:
  • 版权声明
  • 非自由转载-非商用-非衍生-保持署名