Title
text
之前的笔记:
本来是想把H5C3JS的东西放一起整理的,然后看了下有点长……
毕竟主自用,还是先拆开来方便自己复习了
tag 是 HTML 中用于提供页面元数据(metadata)的标签,它不会直接显示在页面中,但会被浏览器、搜索引擎、社交平台等工具读取。
常见用途包括:
设置字符编码(charset)
控制 viewport(响应式布局)
设置 SEO 信息(如 description, keywords)
定义页面作者
配置浏览器行为(如 http-equiv
)
常见的 & 用法
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="A lightweight e-commerce site built with React and Node.js" />
<meta name="keywords" content="React, Node.js, MongoDB, E-commerce" />
<meta name="author" content="Louise Han" />
<meta http-equiv="cache-control" content="no-cache" />
Semantic tags 是指那些 带有语义(semantic meaning) 的 HTML 标签,它们告诉浏览器、开发者和 assistive technology(如 screen reader)“这块内容的作用是什么”。
常见的语义标签
标签 | 用途说明 | 释义 |
---|---|---|
|
页面或 section 的头部区域 | 页眉区域 |
|
网站导航栏 | 导航栏 |
|
页面主内容,唯一出现一次 | 主体内容 |
|
拥有独立主题的一块内容 | 内容区块 |
|
独立的文章、博文、论坛贴文等 | 独立内容 |
|
与主内容相关但不直接相关的信息(如侧边栏) | 侧边信息 |
|
页面或 section 的底部区域 | 页脚 |
/
|
图像 + 图说 | 图片配文 |
|
时间元素,可被机器读取 | 机器可识别的时间 |
|
高亮文本 | 高亮词汇(搜索匹配) |
为什么使用 Semantic Tags
默认有焦点样式)text
:单行文本输入(默认类型)
password
:密码输入,用户输入内容会以圆点/星号显示
email
:必须为邮箱格式,会启用浏览器校验
url
:必须为合法的 URL(浏览器校验)
number
:只能输入数字,可配合 min
、max
、step
tel
:电话号码输入,不会强制格式校验,但移动端会弹出数字键盘
search
:语义上表示搜索,功能上类似 text,可提供清除按钮(某些浏览器)
date
:选择日期(浏览器弹出日期选择器)
time
:选择时间
datetime-local
:选择本地时间和日期
month
:选择月份
week
:选择第几周
checkbox
:复选框,可多选,值为 true
/ false
radio
:单选按钮(需要 name
相同才能形成互斥组)
range
:滑动条(可配合 min/max/step)
file
:文件上传,accept
可限定类型
color
:颜色选择器,返回 HEX 色值
hidden
:隐藏字段(不显示在页面上,但提交时会包含)
可以传递包括用户id、CSRF Token之类的字段
注意不要放敏感信息,毕竟还是可以被JS所访问的
特性 | +
|
+
|
---|---|---|
是否可自由输入 | ✅ Yes(可选或自填) | ❌ No(只能选择) |
外观可定制性 | 基于 ,可定制性高 |
原生样式难以改造 |
表单提交值 | 仅提交 的值 |
提交 的选中值 |
使用场景 | 搜索框、模糊匹配、辅助推荐 | 下拉菜单、选项限定 |
datalist的用法:
<label for="browser">Choose your browser:label>
<input list="browsers" name="browser" id="browser">
<datalist id="browsers">
<option value="Chrome">
<option value="Firefox">
<option value="Safari">
<option value="Edge">
datalist>
select+options的用法:
<select name="fruit">
<option value="apple">Appleoption>
<option value="banana">Bananaoption>
<option value="mango" selected>Mangooption>
select>
维度 |
|
|
---|---|---|
语义(Semantics) | 表示“表单提交区域” — 属于结构语义标签之一 | 没有语义,只是一个容器 |
默认行为 | 提交时会触发表单事件、支持 submit 操作 |
不会自动触发提交行为 |
可访问性支持 | 默认被 Assistive Technology 识别为表单 | 屏幕阅读器不会当做表单处理 |
事件行为支持 | 可监听 onSubmit 事件 |
没有 submit 行为 |
可与按钮协作 | 可直接触发表单提交 |
必须手动添加 JS 才能模拟提交 |
浏览器原生校验 | 支持如 required 、pattern 等自动校验 |
不支持,需要自己写 JavaScript 校验逻辑 |
HTML 并不是可以随意嵌套标签的语言,浏览器会根据 HTML 规范对结构做自动修正。如果标签嵌套不当,可能会出现异常、访问性问题,和语义化校验失败
基础语义分类
通用嵌套规则
一些个人的总结 & 反思
span
不是一定要嵌套在 p
里使用
span
负责的还是段落内做标记使用,只不过大多数情况下这个段落直译成了 paragraph,也就是 p
标签。不过从其他的UI库中也可以看到,不少的UI库直接使用 span
做样式——比如说封装成button
交互元素之间的嵌套
其实之前没注意到这个问题,一直到写React的时候碰到了,就是 a
标签 → 由 React Router DOM 提供的 Link
和 button
嵌套的时候出现了问题,就是重定向不工作
找了一下才发现,HTML规定了交互元素(interactive content)不能互相嵌套,否则会发生不可预期的问题,在我当时的情况下就是重定向失败,点击没有任何的反应
React本身是不会修正这种问题的,所以实现的时候还是需要注意一下……本地没有报错是运气好,特别是现在本地开发环境React会渲染两次,这个情况确实mask了很多问题。上了production再出现问题就糟糕了……
对于 label
、fieldset
、legend
这些 表单进阶标签,它们主要起的是结构化和可访问性(accessibility)优化的作用,只需要熟悉它们的作用和用法场景即可
作用:用于描述表单控件的含义(文本说明)
常用写法:
<label for="username">Usernamelabel>
<input type="text" id="username" />
<label>
Username
<input type="text" />
label>
优势:
作用:将多个表单控件逻辑分组,用于视觉区块化和辅助语义划分
使用场景:例如“个人信息”、“支付方式”这样的分块区域
通常搭配 使用
示例:
<fieldset>
<legend>Personal Infolegend>
<label for="name">Name:label>
<input id="name" type="text" />
<label for="age">Age:label>
<input id="age" type="number" />
fieldset>
提供标题说明,是视觉和语义上的「小标题」
只能直接作为
的第一个子元素出现
,它没有独立语义意义Accessibility(可访问性)指的是:**确保网页内容对所有用户都可用,包括视障、听障或行动不便的用户;**常见实践不仅提升用户体验,也有助于 SEO
核心目标
实用标签
标签 | 功能 |
---|---|
label |
关联表单元素,提升 screen reader 识别准确性 |
fieldset + legend |
对表单区域进行语义分组和说明 |
button |
明确的交互控件,优于滥用
|
a (超链接) |
应该有明确 href ,避免仅作按钮用 |
nav , header , main , footer |
结构语义清晰,有助 assistive tech 理解页面 |
alt (图片说明) |
为 img 提供描述内容或说明装饰性(如 alt="" ) |
推荐实现
alt
描述
、
等原生可交互元素 模拟点击(无法 tab focus)
- 如必须自定义组件,添加
tabindex="0"
和 role="button"
- 添加 Skip to Content 跳转锚点(推荐大项目)
-
ARIA(Accessible Rich Internet Applications)
ARIA 是补充机制,优先使用原生语义标签
ARIA的使用方式包括:
属性
用途
aria-label
给元素添加可识别名称
aria-hidden="true"
隐藏不重要的视觉装饰元素
role
补充 HTML 结构中缺失的语义,例如 role="dialog"
aria-live
通知 screen reader 某区域内容动态更新
HTML 加载顺序与性能
浏览器加载顺序是 HTML → CSS → JS,即:
- 自上而下解析 HTML
- 遇到
:阻塞渲染(必须等待 CSS 下载 & 解析)
- 遇到
(无 async
/ defer
):阻塞解析(必须等待 JS 执行完,才继续解析 HTML)
-
JS前如果有CSS文件,并且CSS尚未加载完毕,那么JS会等到CSS加载完成后再执行
-
因此传统做法——在 defer
未出现时——是将JS放到
最底部,让HTML先完成解析,渲染部分UI
现代开发则是通过使用 defer
+ 将 script 放在
,配合模块化打包(vite/webpack)实现更好的加载性能与维护行
-
加载方式对比
属性
是否阻塞 HTML 解析
执行时机
执行顺序
使用场景
默认
✅ 阻塞
下载完立即执行
顺序执行
样板页 script、页面逻辑入口
async
❓ 不完全阻塞
下载时不阻塞解析
但是下载完成后,执行时会阻塞
下载完立即执行(⚠ 无顺序)
⚠️ 不保证顺序
独立脚本(如广告/统计脚本)
defer
❌ 不阻塞
DOM 全解析后、DOMContentLoaded 前执行
顺序执行
页面初始化逻辑推荐使用
preload
❌ 不执行,仅预取
N/A
N/A
提前加载 JS,但需配合
- 解析完成后,构建 DOM、CSSOM → 生成 Render Tree → 触发绘制 &布局
CSS 样式机制
CSS 选择器分类
类型
示例
说明
Specificity 权重
通配选择器
*
匹配所有元素
0,0,0,0
元素选择器(Element)
div
, p
, a
匹配特定标签
0,0,0,1
类选择器(Class)
.card
, .active
匹配指定 class 的元素
0,0,1,0
属性选择器(Attribute)
[type="text"]
匹配指定属性的元素
0,0,1,0
伪类选择器(Pseudo-class)
:hover
, :nth-child(2)
选择特定状态
0,0,1,0
ID 选择器(ID)
#header
, #app
匹配特定 ID 的元素
0,1,0,0
伪元素(Pseudo-element)
::before
, ::after
针对元素插入虚拟节点
0,0,0,1
(同元素选择器)
组合选择器(Combinator)
div .title
, ul > li
父子/兄弟等嵌套结构
权重相加(逐个计算)
优先权最高:内联样式
style="color: red;"
直接写在元素上
1,0,0,0
(最高)
!important
(特例)
color: red !important
不属于 specificity,但强制优先
会覆盖正常权重规则(除非被另一条更强的 !important
覆盖)
CSS Specificity 是 4 维度权重,记作 a,b,c,d
:
a
:是否为内联样式 → 1,0,0,0
b
:ID 选择器数量
c
:Class、属性、伪类
d
:标签选择器、伪元素
box model
Box Model 是 HTML 元素在页面中所占空间的数学模型。
每个元素都可以看作一个矩形盒子,由以下几部分组成:
(Outline - 不占空间)
+---------------------------+
| Margin |
| +---------------------+ |
| | Border | |
| | +---------------+ | |
| | | Padding | | |
| | | +--------+ | | |
| | | | Content | | | |
| | | +--------+ | | |
| | +---------------+ | |
| +---------------------+ |
+---------------------------+
层级
是否占据空间
描述说明
outline
❌ 否
仅视觉效果,不影响布局,常用于焦点提示
margin
✅ 是
元素与外部元素的距离
border
✅ 是
包裹 padding + content 的边线
padding
✅ 是
内容与边框之间的内边距
content
✅ 是
实际显示文本/图片的区域
-
标准盒模型(content-box)→ 默认
width
为 content的宽度,所以计算的时候需要通过 c o n t e n t + p a d d i n g + b o r d e r content + padding + border content+padding+border 的方式去计算
-
替代盒模型(border-box)→ 推荐
width
为 c o n t e n t + p a d d i n g + b o r d e r content + padding + border content+padding+border 的宽度,即元素的整体宽度,计算起来相对省心
也是现代CSS框架的默认计算方式
display
display
定义了元素的布局行为,是 CSS 中最基础也最重要的属性之一。它决定了元素如何参与文档流以及是否能成为容器
属性值
说明
block
块级元素,占满整行,可设置宽高(如 )
inline
行内元素,不可设置宽高(如
)
inline-block
兼具行内与块级特性,可并排也可设置宽高
none
元素隐藏且不参与渲染,不占据空间
flex
启用 Flex 一维弹性布局容器
inline-flex
行内弹性容器,可与文字并排显示
grid
启用 Grid 二维网格布局容器
inline-grid
行内网格容器
table
模拟表格布局行为
contents
不渲染元素自身,只保留子元素结构(⚠ 有兼容性问题)
list-item
元素表现为列表项,通常带有 •
符号
常见场景推荐:
- 页面区域布局 → 推荐使用
flex
或 grid
- 水平排布多个组件 → 使用
inline-block
或 flex
- 条件渲染 → 用
display: none
控制显示与隐藏
position 定位机制
position
定义元素脱离文档流的方式,影响其在页面中的位置计算方式
属性值
说明
static
默认值,按照文档流正常排列
relative
相对自身原位置偏移,可配合 top/right/bottom/left
使用
absolute
相对最近的非 static父元素定位,脱离文档流
fixed
相对于 视口(viewport) 定位,常用于吸顶、悬浮按钮
sticky
在滚动时在 relative
与 fixed
之间切换,实现“粘性”效果
配套偏移属性(仅 relative
/ absolute
/ fixed
/ sticky
有效):
top: 10px;
left: 20px;
right: 0;
bottom: auto;
注意:
absolute
必须有明确定位上下文,否则会相对 body
定位
fixed
不随滚动条滚动,适合做悬浮按钮
sticky
需要设置 top
或其他边界,且外层容器不能有 overflow: hidden
实用技巧:
-
经典居中方法:
.centered {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
-
粘性标题栏:
header {
position: sticky;
top: 0;
background: white;
}
column layout
允许将一个元素的内容分成多个列,类似报纸排版
核心属性包括:
属性名
说明
column-count
指定列的个数
column-width
指定每列的理想宽度(浏览器会根据实际情况调整)
columns
简写形式:columns: column-width column-count;
column-gap
列与列之间的间隙(默认 1em
)
column-rule
列之间的分隔线(包含宽度、样式、颜色)
break-inside
控制子元素是否可中断换列(避免被拆开)
它的限制与注意事项:
特点
说明
❌ 支持不如 Flex/Grid 丰富
无法灵活控制每列内容的对齐、分布
❌ 不支持嵌套列
嵌套结构时可能会失效或排版错乱
✅ 非常适合内容流排版
如长文本、段落内容、简报式展示
flex layout
Flex 是一种一维布局系统,擅长处理 主轴方向的对齐、伸缩、排序等问题。核心概念是容器(flex container)和项目(flex item)
-
启用flex的方法比较简单,将 display改成flex即可:
.container {
display: flex; /* 或 inline-flex */
}
这样所有的自元素都自动成为flex item
-
主轴方向控制使用 flex-direction
:
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
-
换行控制使用 flex-wrap
:
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
-
主轴对齐:justify-content
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
}
-
交叉轴对齐使用 align-items
:
.container {
align-items: stretch | flex-start | flex-end | center | baseline;
}
现在比较流行的一种水平/垂直的实现方法,就是使用 justify-content
+ align-items
实现的
-
多行对齐:align-content
.container {
align-content: stretch | flex-start | flex-end | center | space-between | space-around;
}
-
子项控制:flex
简写
.item {
flex: [flex-grow] [flex-shrink] [flex-basis];
}
-
子项对齐(覆盖 align-items):align-self
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
-
间距控制:gap
.container {
gap: 1rem; /* 行列统一间距 */
row-gap: 10px; /* 仅行间距 */
column-gap: 20px; /* 仅列间距 */
}
grid layout
Grid 是一种 二维布局系统,适合处理复杂网格、区域布局等需求。与 Flex 不同,Grid 可以同时控制行(row)和列(column)
-
启用 Grid 布局
.container {
display: grid; /* 或 inline-grid */
}
-
定义网格行与列
.container {
grid-template-columns: 100px 1fr 2fr; /* 列宽 */
grid-template-rows: auto 50px; /* 行高 */
}
-
设置间距:gap
.container {
gap: 10px; /* 同时设置行列间距 */
row-gap: 10px;
column-gap: 20px;
}
-
放置子项:行列定位
.item {
grid-column: 1 / 3; /* 第1列开始到第3列前结束(跨2列) */
grid-row: 2 / span 2; /* 从第2行开始,跨2行 */
}
-
命名区域(推荐)
.container {
grid-template-areas:
"header header"
"sidebar main"
"footer footer";
}
.item-header {
grid-area: header;
}
-
自动排列:auto-fill
与 auto-fit
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
-
对齐内容
.container {
justify-items: start | center | end;
align-items: start | center | end;
}
column vs flex vs grid
特性
Column Layout
Flexbox
Grid
排版方式
垂直分栏
一维(行或列)
二维(行 + 列)
控制力
⭐️ 中等
⭐️⭐️⭐️ 强
⭐️⭐️⭐️⭐️ 最强
内容流动
自动分流
子项自己布局
显式定义区域
使用场景
报纸式文本
UI组件对齐
页面布局骨架
响应式布局&媒体查询
响应式设计是指页面可以根据不同屏幕尺寸、分辨率和设备特性自动调整布局与样式,从而提供良好用户体验的一种设计理念
-
核心目标
- 同一个 HTML 页面,适配不同设备(手机、平板、桌面)
- 自动调整布局、字号、边距、组件显示/隐藏等
- 避免内容“溢出”或“太小看不清”
-
实现方法
主要通过media query去做,基础的模板代码为:
@media <媒体类型> and (<条件>) {
/* 只在满足该条件下才生效 */
}
如:
/* 屏幕宽度小于等于 768px(平板及以下) */
@media (max-width: 768px) {
.sidebar {
display: none;
}
}
/* 屏幕宽度大于等于 1024px(桌面端) */
@media (min-width: 1024px) {
body {
font-size: 16px;
}
}
-
常用断点
断点类型
宽度范围(参考值)
用途
Extra small (xs
)
< 576px
手机竖屏
Small (sm
)
≥ 576px
手机横屏
Medium (md
)
≥ 768px
平板设备
Large (lg
)
≥ 992px
小型桌面
Extra large (xl
)
≥ 1200px
常规桌面
XXL (xxl
)
≥ 1400px
大屏显示器
-
响应式单位 &技巧补充
单位
说明
%
相对于父元素的宽/高
vw
视口宽度的百分比(100vw = 屏幕宽)
vh
视口高度的百分比(100vh = 屏幕高)
em/rem
字体相对单位,适用于字号随屏幕变小自动缩放
clamp()
设定最小、推荐值、最大值,实现响应式字体大小:clamp(14px, 2vw, 18px)
-
响应式布局技巧
-
使用 flex-wrap: wrap
或 Grid 布局 + auto-fit
-
使用 gap
代替传统 margin-right
/padding
-
合理隐藏某些组件:
@media (max-width: 768px) {
.menu-sidebar {
display: none;
}
}
-
用容器类限制最大宽度(如 max-width: 1200px; margin: 0 auto;
)
-
Mobile First
目前responsive design的主流策略,核心理念是从小屏幕(如手机)出发设计 UI,再逐步为大屏幕添加增强样式
这种设计用 max-width
更加的合适,反之,如果从 desktop first 则用 min-width
BEM 命名
BEM 是一种 结构化命名规范,用于让 CSS 类名清晰表达组件结构与状态,便于维护、避免冲突
部分
描述
示例
Block
独立的功能模块(可以单独复用)
card
, nav
, form
Element
Block 内部的组成部分
card__title
, nav__item
Modifier
表示 Block 或 Element 的状态 / 变体
card--highlighted
, button--disabled
如:
/* Block */
.button {}
/* Element:使用两个下划线 */
.button__icon {}
/* Modifier:使用两个连字符 */
.button--primary {}
.button__icon--large {}
一般来说用BEM的话,写原生CSS比较多,或者是需要构建比较大的UI库这种情况,我们项目的话,因为有自己的UIF(UI Framework),所以反而会比较多的依赖UIF的实现,有需要重在的情况BEM也帮不上什么忙,就用JSX里的inline css搞定了
SCSS/SASS 简述
底层编译器相同:两者都使用 Dart Sass(现在是官方唯一支持的实现),不过实现的格式有些许的不同:
特性
SASS (.sass)
SCSS (.scss)
语法风格
缩进式(无大括号、分号)
类似 CSS(用大括号和分号)
可读性
更简洁,偏向 Ruby 风格
更接近原生 CSS,学习曲线低
支持程度
老项目可能使用
新项目主流使用
推荐程度
可选(老项目或喜欢极简)
✅ 推荐(兼容性、迁移、团队协作)
-
变量定义
$primary-color: #3498db;
.button {
background: $primary-color;
}
-
嵌套规则(Nested Rules)
.navbar {
ul {
list-style: none;
}
li {
display: inline-block;
}
}
-
Mixin(类似函数,可传参)
@mixin flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.container {
@include flex-center;
}
-
Extend(继承已有样式)
%base-button {
padding: 0.5rem 1rem;
border-radius: 4px;
}
.btn-primary {
@extend %base-button;
background-color: blue;
}
-
条件和循环(Control Directives)
$themes: light, dark, blue;
@each $theme in $themes {
.theme-#{$theme} {
// 动态类名
}
}
过渡
元素状态变更时的过渡,一般与 :hover
、:focus
等伪类配合使用,如:
.button {
transition: all 0.3s ease-in-out;
}
.button:hover {
transform: scale(1.05);
}
具体结构为:
transition: ;
动画
animation
:关键帧动画(更复杂),使用方法如下:
@keyframes fade-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.card {
animation: fade-in 0.6s ease forwards;
}
具体结构为:
animation: ;
常见参数:
infinite
:无限循环
alternate
:来回动画
forwards
:保留最后状态(常用!)
animation vs. transition
点
transition
animation
用途
简单状态切换(如 hover)
复杂序列动画
触发方式
被动(如鼠标 hover)
可自动播放(无须交互)
控制方式
仅开始状态和结束状态
多帧(keyframes)
写法复杂度
低
中高
视觉可访问性 Visual Accessibility
-
重要性:
- WCAG(Web Content Accessibility Guidelines)明确要求视觉元素满足对比和聚焦可见性要求
- 企业级产品(尤其 B2B/Gov)经常要通过 A11y 审核
- Tailwind / Chakra / MUI 等现代框架已经内建
-
颜色对比 color contrast
元素类型
最低对比度比值
正文文字
4.5:1
粗体大文字(≥18px bold / 24px regular)
3:1
UI 组件边界(如按钮边框)
通常建议 ≥ 3:1
检查工具包括:
- WebAIM Contrast Checker
- Figma 的 A11y 插件
- VS Code 插件:WCAG Color Contrast Checker
-
焦点可见性 focus outline
目标用户:键盘用户(Tab键导航者)、辅助技术用户
推荐实现方法:
button:focus,
a:focus {
outline: 2px solid #2684FF;
outline-offset: 2px;
}
outline
: 视觉边框,不占空间,适合可访问性标示
outline-offset
: 将 outline 往外或内偏移,不会遮住按钮内容
- ⚠️ 如果用了
outline: none
,必须自己补上焦点状态的视觉标识(如 box-shadow
、border
等),否则违反可访问性规范
-
图片与alt文字,之前提过
-
可感知的状态变化(Visible State Change)
仅靠颜色可能不太明确,正确方法推荐:
**<input type="email" aria-invalid="true" />
<span class="error">邮箱格式不正确span>**
这个应该是针对色盲/色弱做的优化
-
深色模式支持 Dark Mode Support
属于现代设计中的视觉舒适性优化,对于光敏感用户尤为关键
-
字体大小 / 可缩放性(Zoom & Font Size)
页面应支持最高到 200% 的缩放,仍能正常操作和阅读
那……很多网页应该是做不到的……
-
认知可访问性(Cognitive Accessibility)
- 避免使用动图、闪烁图像(容易引发癫痫/认知负担)
- 避免使用过多动画(结合
prefers-reduced-motion
)
- 保持按钮文本明确(如“提交表单”比“点我一下”更清晰)