CSS基础-单位与颜色系统
CSS中的单位和颜色系统是样式设计的基础,选择合适的单位和颜色表示方法对于创建灵活、可维护的样式至关重要。
本文将系统介绍CSS的各种长度单位、颜色表示方法以及CSS变量的使用。
# 一、长度单位
CSS长度单位分为两大类:绝对单位和相对单位。
# 1.1 绝对单位
绝对单位的长度是固定的,不会因为其他元素的尺寸变化而变化。
# px (像素)
.box {
width: 200px;
height: 100px;
font-size: 16px;
border: 1px solid #ccc;
}
特点:
- 最常用的绝对单位
- 在不同设备上显示大小可能不同(受设备像素比影响)
- 适合需要精确控制的场景(边框、阴影等)
注意高分辨率屏幕:
/* 普通屏幕:1px = 1物理像素 */
/* Retina屏幕:1px = 2或3物理像素 */
.line {
border-bottom: 1px solid #ddd; /* 在Retina屏可能显得较粗 */
}
/* 使用transform实现真正的1物理像素 */
.hairline::after {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background-color: #ddd;
transform: scaleY(0.5); /* Retina屏上显示为真正的1物理像素 */
}
# 其他绝对单位(少用)
.element {
width: 2in; /* 英寸 (1in = 96px) */
width: 5cm; /* 厘米 (1cm = 37.8px) */
width: 50mm; /* 毫米 (1mm = 3.78px) */
width: 12pt; /* 点 (1pt = 1/72in = 1.33px) */
width: 1pc; /* 派卡 (1pc = 12pt = 16px) */
}
使用场景:主要用于打印样式表 @media print。
# 1.2 相对单位
相对单位的长度是相对于其他长度而言的,更加灵活和响应式。
# em
相对于当前元素的 font-size。
.parent {
font-size: 16px;
}
.child {
font-size: 2em; /* 2 * 16px = 32px */
padding: 1em; /* 1 * 32px = 32px (相对于自身font-size) */
margin-bottom: 0.5em; /* 0.5 * 32px = 16px */
}
特点:
- 会继承并累积父元素的
font-size - 适合创建可缩放的组件
- 容易造成复杂的计算
嵌套问题:
.level1 {
font-size: 1.2em; /* 相对于父元素 */
}
.level2 {
font-size: 1.2em; /* 1.2 * 1.2 = 1.44em */
}
.level3 {
font-size: 1.2em; /* 1.2 * 1.44 = 1.728em */
}
/* 嵌套越深,字体越大 */
# rem (推荐)
相对于根元素 (<html>) 的 font-size。
html {
font-size: 16px; /* 基准值 */
}
.container {
font-size: 1rem; /* 16px */
padding: 2rem; /* 32px */
margin-bottom: 1.5rem; /* 24px */
}
.title {
font-size: 2rem; /* 32px */
margin-bottom: 1rem; /* 16px */
}
特点:
- 不会累积,计算简单
- 便于实现整体缩放
- 现代响应式设计的首选
响应式字体大小:
html {
font-size: 14px;
}
@media (min-width: 768px) {
html {
font-size: 16px;
}
}
@media (min-width: 1200px) {
html {
font-size: 18px;
}
}
/* 所有使用rem的元素都会自动缩放 */
.text {
font-size: 1rem; /* 14px/16px/18px */
}
# % (百分比)
相对于父元素的对应属性。
.parent {
width: 1000px;
height: 500px;
font-size: 16px;
}
.child {
width: 50%; /* 500px (父元素width的50%) */
height: 80%; /* 400px (父元素height的80%) */
font-size: 150%; /* 24px (父元素font-size的150%) */
/* padding/margin的百分比相对于父元素的width */
padding: 10%; /* 100px (父元素width的10%) */
margin-top: 5%; /* 50px (父元素width的5%) */
}
特殊情况:
padding和margin的百分比总是相对于父元素的 widthposition: absolute时,相对于定位祖先元素
/* 利用padding实现固定宽高比 */
.aspect-ratio-16-9 {
width: 100%;
padding-bottom: 56.25%; /* 9/16 = 0.5625 */
position: relative;
background-color: #f0f0f0;
}
.aspect-ratio-16-9 > * {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
# vw / vh (视口单位)
相对于视口(浏览器窗口)的尺寸。
.element {
width: 50vw; /* 视口宽度的50% */
height: 100vh; /* 视口高度的100% */
font-size: 5vw; /* 视口宽度的5% */
padding: 2vh 3vw; /* 视口高度的2%, 视口宽度的3% */
}
其他视口单位:
.box {
width: 50vmin; /* vw和vh中较小的值 */
height: 50vmax; /* vw和vh中较大的值 */
}
应用场景:
/* 1. 全屏布局 */
.hero {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
/* 2. 响应式字体 */
.title {
font-size: calc(2rem + 2vw); /* 结合rem和vw */
}
/* 3. 固定侧边栏 */
.sidebar {
width: 20vw;
min-width: 200px;
max-width: 300px;
}
注意移动端问题:
/* 移动端浏览器地址栏会影响100vh */
.mobile-full-height {
height: 100vh; /* 可能被地址栏遮挡 */
/* 解决方案:使用JavaScript */
/* height: var(--vh); */
}
// 修复移动端100vh问题
const setVH = () => {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty('--vh', `${vh}px`);
};
setVH();
window.addEventListener('resize', setVH);
.mobile-full-height {
height: calc(var(--vh, 1vh) * 100);
}
# ch / ex (字符单位)
.element {
width: 40ch; /* 相对于字符"0"的宽度 */
height: 10ex; /* 相对于字母"x"的高度 */
}
应用场景:
/* 控制每行字符数,提高可读性 */
.article {
max-width: 65ch; /* 每行约65个字符 */
line-height: 1.6;
}
/* 输入框宽度 */
input[type="text"] {
width: 20ch; /* 容纳20个字符 */
}
# 1.3 单位选择指南
| 使用场景 | 推荐单位 | 说明 |
|---|---|---|
| 字体大小 | rem | 便于全局缩放 |
| 边框、阴影 | px | 需要精确控制 |
| 间距(padding/margin) | rem 或 px | rem更灵活,px更精确 |
| 容器宽度 | % 或 vw | 响应式布局 |
| 容器高度 | vh 或 auto | 全屏或自适应 |
| 媒体查询断点 | em 或 px | em更灵活 |
| 图标大小 | em | 跟随文字大小 |
最佳实践:
/* 基础设置 */
html {
font-size: 16px; /* 基准字体大小 */
}
*, *::before, *::after {
box-sizing: border-box;
}
/* 容器 */
.container {
width: 90%;
max-width: 1200px;
margin: 0 auto;
padding: 0 1rem;
}
/* 文字 */
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
h3 { font-size: 1.75rem; }
p { font-size: 1rem; line-height: 1.6; }
/* 间距 */
.section {
padding: 3rem 0;
margin-bottom: 2rem;
}
/* 边框 */
.card {
border: 1px solid #ddd;
border-radius: 8px;
}
# 二、颜色系统
# 2.1 颜色表示方法
# 颜色关键字
.element {
color: red;
background-color: white;
border-color: transparent;
/* CSS扩展颜色 */
color: tomato;
background-color: cornflowerblue;
border-color: lightgray;
}
常用关键字:black、white、red、green、blue、transparent
特殊关键字:
.element {
color: currentColor; /* 继承当前元素的color值 */
border-color: currentColor;
}
.inherit {
color: inherit; /* 继承父元素的color */
}
# 十六进制 (HEX)
.element {
/* 6位:#RRGGBB */
color: #ff0000; /* 红色 */
color: #00ff00; /* 绿色 */
color: #0000ff; /* 蓝色 */
/* 3位简写(相同时可省略) */
color: #f00; /* #ff0000 */
color: #0f0; /* #00ff00 */
color: #abc; /* #aabbcc */
/* 8位:#RRGGBBAA (带透明度) */
color: #ff000080; /* 红色,50%透明 */
/* 4位简写 */
color: #f008; /* #ff000088 */
}
透明度计算:
00= 0% (完全透明)80= 50% (半透明)FF= 100% (完全不透明)
# RGB / RGBA
.element {
/* RGB: rgb(red, green, blue) */
/* 取值范围:0-255 */
color: rgb(255, 0, 0); /* 红色 */
color: rgb(0, 255, 0); /* 绿色 */
color: rgb(0, 0, 255); /* 蓝色 */
/* RGBA: rgb(red, green, blue, alpha) */
/* alpha取值:0-1 */
color: rgba(255, 0, 0, 0.5); /* 红色,50%透明 */
color: rgba(0, 0, 0, 0.1); /* 黑色,10%透明 */
/* 现代语法(推荐) */
color: rgb(255 0 0 / 0.5); /* 使用空格和斜杠 */
color: rgb(255 0 0 / 50%); /* 百分比透明度 */
}
# HSL / HSLA
HSL = Hue(色相) + Saturation(饱和度) + Lightness(亮度)
.element {
/* HSL: hsl(hue, saturation, lightness) */
/* hue: 0-360 (色环角度) */
/* saturation: 0-100% (饱和度) */
/* lightness: 0-100% (亮度) */
color: hsl(0, 100%, 50%); /* 红色 */
color: hsl(120, 100%, 50%); /* 绿色 */
color: hsl(240, 100%, 50%); /* 蓝色 */
/* HSLA: hsl(hue, saturation, lightness, alpha) */
color: hsla(0, 100%, 50%, 0.5); /* 红色,50%透明 */
/* 现代语法 */
color: hsl(0 100% 50% / 0.5);
}
色相环:
0°/360°= 红色60°= 黄色120°= 绿色180°= 青色240°= 蓝色300°= 洋红
HSL的优势:
/* 主色 */
.primary {
background-color: hsl(210, 80%, 50%);
}
/* 更亮的主色(调整亮度) */
.primary-light {
background-color: hsl(210, 80%, 70%);
}
/* 更暗的主色 */
.primary-dark {
background-color: hsl(210, 80%, 30%);
}
/* 降低饱和度 */
.primary-muted {
background-color: hsl(210, 40%, 50%);
}
# 2.2 颜色应用场景
# 文本颜色
.text {
color: #333; /* 主文本 */
color: #666; /* 次要文本 */
color: #999; /* 辅助文本 */
}
.link {
color: #007bff; /* 链接 */
}
.link:hover {
color: #0056b3; /* 悬停状态 */
}
# 背景颜色
.background {
background-color: #ffffff; /* 白色背景 */
background-color: #f8f9fa; /* 浅灰背景 */
background-color: rgba(0, 0, 0, 0.05); /* 半透明黑色 */
}
/* 渐变背景 */
.gradient {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
# 边框颜色
.border {
border: 1px solid #ddd; /* 浅边框 */
border: 2px solid #007bff; /* 蓝色边框 */
}
.focus {
outline: 2px solid rgba(0, 123, 255, 0.5); /* 半透明轮廓 */
}
# 阴影颜色
.shadow {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); /* 轻阴影 */
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); /* 中阴影 */
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2); /* 重阴影 */
}
.text-shadow {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
# 2.3 颜色系统设计
# 主题色
:root {
/* 主色 */
--primary-color: #007bff;
--primary-light: #4da3ff;
--primary-dark: #0056b3;
/* 辅助色 */
--secondary-color: #6c757d;
/* 功能色 */
--success-color: #28a745;
--warning-color: #ffc107;
--danger-color: #dc3545;
--info-color: #17a2b8;
/* 中性色 */
--gray-100: #f8f9fa;
--gray-200: #e9ecef;
--gray-300: #dee2e6;
--gray-400: #ced4da;
--gray-500: #adb5bd;
--gray-600: #6c757d;
--gray-700: #495057;
--gray-800: #343a40;
--gray-900: #212529;
/* 文本色 */
--text-primary: #212529;
--text-secondary: #6c757d;
--text-muted: #adb5bd;
/* 背景色 */
--bg-primary: #ffffff;
--bg-secondary: #f8f9fa;
}
/* 使用 */
.button {
background-color: var(--primary-color);
color: white;
}
.button:hover {
background-color: var(--primary-dark);
}
# 暗色主题
/* 亮色主题(默认) */
:root {
--bg-color: #ffffff;
--text-color: #212529;
--border-color: #dee2e6;
}
/* 暗色主题 */
[data-theme="dark"] {
--bg-color: #212529;
--text-color: #f8f9fa;
--border-color: #495057;
}
/* 使用 */
body {
background-color: var(--bg-color);
color: var(--text-color);
}
.card {
border: 1px solid var(--border-color);
}
// 切换主题
const toggleTheme = () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
};
# 三、CSS 变量 (自定义属性)
# 3.1 基本语法
/* 定义变量 */
:root {
--main-color: #007bff;
--spacing-unit: 8px;
--border-radius: 4px;
}
/* 使用变量 */
.button {
background-color: var(--main-color);
padding: var(--spacing-unit);
border-radius: var(--border-radius);
}
/* 使用变量(带默认值) */
.element {
color: var(--text-color, #333); /* 如果--text-color未定义,使用#333 */
}
# 3.2 作用域
/* 全局变量 */
:root {
--global-color: red;
}
/* 局部变量 */
.card {
--card-padding: 20px;
padding: var(--card-padding);
}
.card-body {
padding: var(--card-padding); /* 继承父元素的变量 */
}
.other-element {
padding: var(--card-padding); /* 无法访问,未定义 */
}
# 3.3 变量计算
:root {
--base-size: 16px;
--scale: 1.5;
}
.title {
/* calc() 函数 */
font-size: calc(var(--base-size) * var(--scale)); /* 24px */
margin-bottom: calc(var(--base-size) / 2); /* 8px */
}
.container {
--container-width: 1200px;
--padding: 20px;
width: var(--container-width);
/* 内容宽度 = 容器宽度 - 两侧padding */
max-width: calc(var(--container-width) - var(--padding) * 2);
}
# 3.4 动态更新
:root {
--theme-color: blue;
}
.element {
color: var(--theme-color);
}
// JavaScript动态修改变量
document.documentElement.style.setProperty('--theme-color', 'red');
// 获取变量值
const color = getComputedStyle(document.documentElement)
.getPropertyValue('--theme-color');
# 3.5 实用案例
# 响应式间距系统
:root {
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
}
@media (min-width: 768px) {
:root {
--spacing-xs: 8px;
--spacing-sm: 12px;
--spacing-md: 24px;
--spacing-lg: 36px;
--spacing-xl: 48px;
}
}
.section {
padding: var(--spacing-lg) 0;
}
.card {
padding: var(--spacing-md);
margin-bottom: var(--spacing-sm);
}
# 主题切换
:root {
--primary: #007bff;
--success: #28a745;
--danger: #dc3545;
}
[data-theme="purple"] {
--primary: #6f42c1;
--success: #20c997;
--danger: #e83e8c;
}
.btn-primary {
background-color: var(--primary);
}
# 组件配置
# 四、calc() 函数
# 4.1 基本用法
.element {
/* 加减乘除 */
width: calc(100% - 20px);
height: calc(100vh - 60px);
font-size: calc(1rem + 2px);
padding: calc(1em * 2);
/* 混合单位 */
width: calc(100% / 3 - 10px);
margin-left: calc(50% - 200px);
}
注意事项:
/* ✅ 正确:运算符前后有空格 */
width: calc(100% - 20px);
/* ❌ 错误:没有空格 */
width: calc(100%-20px);
/* ✅ 正确:乘除可以不加空格,但建议加 */
width: calc(100% / 2);
width: calc(100%/2);
# 4.2 实用案例
# 全屏布局减去固定头部
.header {
height: 60px;
position: fixed;
top: 0;
width: 100%;
}
.main {
height: calc(100vh - 60px);
margin-top: 60px;
}
# 流体网格
.grid {
display: grid;
grid-template-columns: repeat(3, calc((100% - 40px) / 3));
gap: 20px;
}
# 水平居中(已知宽度)
.center {
width: 400px;
margin-left: calc(50% - 200px);
}
# 动态字体大小
# 五、现代CSS颜色函数
# 5.1 color-mix()
.element {
/* 混合两种颜色 */
background-color: color-mix(in srgb, blue 50%, red);
/* 不同比例混合 */
color: color-mix(in srgb, #007bff 70%, white);
/* 创建色板 */
--primary: #007bff;
--primary-light: color-mix(in srgb, var(--primary) 30%, white);
--primary-dark: color-mix(in srgb, var(--primary) 70%, black);
}
浏览器兼容性:现代浏览器支持(2023+)
# 5.2 color-contrast()
.element {
/* 自动选择对比度更高的颜色 */
color: color-contrast(var(--bg-color) vs white, black);
}
注意:该功能仍在标准化中,浏览器支持有限。
# 5.3 hwb()
HWB = Hue(色相) + Whiteness(白度) + Blackness(黑度)
.element {
/* hwb(hue, whiteness, blackness) */
color: hwb(0 0% 0%); /* 纯红色 */
color: hwb(0 50% 0%); /* 浅红色(加白) */
color: hwb(0 0% 50%); /* 暗红色(加黑) */
}
# 六、最佳实践
# 6.1 单位使用建议
/* ✅ 推荐 */
html {
font-size: 16px; /* 基准 */
}
.container {
max-width: 1200px;
padding: 0 1rem;
}
.title {
font-size: 2rem; /* 响应式字体 */
margin-bottom: 1.5rem;
}
.border {
border: 1px solid #ddd; /* 精确边框 */
}
/* ❌ 不推荐 */
.element {
width: 800px; /* 固定宽度不灵活 */
padding: 15px 15px 15px 15px; /* 重复 */
font-size: 14px; /* 不易缩放 */
}
# 6.2 颜色系统建议
/* ✅ 推荐:使用CSS变量统一管理 */
:root {
--color-primary: #007bff;
--color-text: #212529;
--color-border: #dee2e6;
}
.button {
background: var(--color-primary);
color: white;
}
/* ❌ 不推荐:颜色值到处散落 */
.button1 { background: #007bff; }
.button2 { background: #007bff; }
.link { color: #007bff; }
# 6.3 可访问性
/* 确保足够的颜色对比度 */
/* WCAG AA标准:正文4.5:1,大字3:1 */
/* ✅ 好的对比度 */
.text {
color: #212529; /* 深灰 */
background-color: #ffffff; /* 白色 */
/* 对比度: 16.1:1 */
}
/* ❌ 对比度不足 */
.poor-contrast {
color: #999999; /* 浅灰 */
background-color: #ffffff; /* 白色 */
/* 对比度: 2.85:1 不符合标准 */
}
# 6.4 性能优化
/* ✅ 使用CSS变量减少重复计算 */
:root {
--container-width: 1200px;
--half-width: calc(var(--container-width) / 2);
}
.element {
width: var(--half-width); /* 只计算一次 */
}
/* 避免过度使用calc() */
/* ❌ 不推荐 */
.element {
width: calc(calc(100% - 20px) / 2 + 5px);
}
/* ✅ 推荐:简化计算 */
.element {
width: calc(50% - 5px);
}
# 七、浏览器兼容性
| 特性 | Chrome | Firefox | Safari | Edge |
|---|---|---|---|---|
| rem | ✅ | ✅ | ✅ | ✅ |
| vw/vh | ✅ | ✅ | ✅ | ✅ |
| CSS变量 | ✅ 49+ | ✅ 31+ | ✅ 10+ | ✅ 15+ |
| calc() | ✅ | ✅ | ✅ | ✅ |
| hsl() | ✅ | ✅ | ✅ | ✅ |
| hwb() | ✅ 101+ | ✅ 96+ | ✅ 15+ | ✅ 101+ |
| color-mix() | ✅ 111+ | ✅ 113+ | ✅ 16.2+ | ✅ 111+ |
兼容性建议:
- CSS变量:现代浏览器都支持,IE不支持
- 视口单位:注意移动端浏览器的100vh问题
- 新颜色函数:提供降级方案
/* 降级方案 */
.element {
background: #007bff; /* 降级 */
background: color-mix(in srgb, blue 80%, white); /* 现代浏览器 */
}
# 八、总结
单位和颜色是CSS的基础:
- 长度单位:优先使用
rem(字体和间距)、%(布局)、vw/vh(视口相关) - 颜色表示:十六进制用于静态颜色,HSL用于主题系统,RGBA用于透明效果
- CSS变量:统一管理颜色、间距等设计令牌,便于维护和主题切换
- calc()函数:灵活计算,混合不同单位
- 响应式:结合媒体查询和相对单位,创建灵活的布局
- 可访问性:确保颜色对比度符合WCAG标准
掌握这些基础知识,能让你的样式更加灵活、可维护和响应式。
祝你变得更强!
编辑 (opens new window)
上次更新: 2025/11/20