Appearance
现代CSS
简介
现代CSS是指近年来CSS规范的快速发展所带来的新特性和新方法,这些特性使得CSS更加强大、灵活和易于维护。本文将介绍现代CSS的核心特性、最佳实践和常见应用场景。
核心特性
CSS变量(自定义属性)
CSS变量允许开发者定义可重用的值,提高代码的可维护性和一致性:
css
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--text-color: #333;
--spacing-unit: 8px;
}
.button {
background-color: var(--primary-color);
color: white;
padding: calc(var(--spacing-unit) * 2);
margin-bottom: var(--spacing-unit);
}
.button.secondary {
background-color: var(--secondary-color);
}Flexbox布局
Flexbox提供了一种更加高效和可预测的方式来布局、对齐和分配容器中项目之间的空间:
css
.container {
display: flex;
justify-content: space-between; /* 水平分布 */
align-items: center; /* 垂直居中 */
flex-wrap: wrap; /* 允许换行 */
}
.item {
flex: 1 0 300px; /* 增长、收缩、基础宽度 */
margin: 10px;
}Grid布局
CSS Grid是一个二维布局系统,提供了强大的网格布局能力:
css
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 20px;
}
.header {
grid-column: 1 / -1; /* 跨越所有列 */
}
.sidebar {
grid-row: 2 / span 2; /* 从第2行开始跨越2行 */
}媒体查询与响应式设计
现代CSS中的媒体查询允许根据设备特性应用不同的样式:
css
/* 基础样式 - 移动优先 */
.container {
padding: 15px;
font-size: 16px;
}
/* 平板设备 */
@media (min-width: 768px) {
.container {
padding: 20px;
font-size: 18px;
}
}
/* 桌面设备 */
@media (min-width: 1024px) {
.container {
padding: 30px;
max-width: 1200px;
margin: 0 auto;
}
}容器查询
容器查询是媒体查询的进阶版,允许基于父容器的大小而非视口大小来应用样式:
css
/* 定义一个容器 */
.card-container {
container-type: inline-size;
container-name: card;
}
/* 基础卡片样式 */
.card {
display: flex;
flex-direction: column;
}
/* 当容器宽度大于700px时应用的样式 */
@container card (min-width: 700px) {
.card {
flex-direction: row;
}
.card-image {
width: 30%;
}
.card-content {
width: 70%;
}
}现代CSS选择器
属性选择器
css
/* 选择所有带有data-type="primary"属性的元素 */
[data-type="primary"] {
background-color: var(--primary-color);
}
/* 选择所有href以https开头的链接 */
a[href^="https"] {
color: green;
}
/* 选择所有href以.pdf结尾的链接 */
a[href$=".pdf"] {
font-weight: bold;
}伪类选择器
css
/* 第一个子元素 */
li:first-child {
font-weight: bold;
}
/* 最后一个类型为p的元素 */
p:last-of-type {
margin-bottom: 0;
}
/* 奇数行 */
tr:nth-child(odd) {
background-color: #f2f2f2;
}
/* 每隔3个元素 */
li:nth-child(3n) {
color: red;
}CSS动画与过渡
过渡(Transitions)
css
.button {
background-color: var(--primary-color);
color: white;
padding: 10px 20px;
border-radius: 4px;
transition: all 0.3s ease;
}
.button:hover {
background-color: var(--secondary-color);
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}关键帧动画(Keyframe Animations)
css
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.element {
animation: fadeIn 0.5s ease-out forwards;
}
/* 更复杂的动画 */
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
.heart {
animation: pulse 1.5s infinite;
}CSS预处理器与后处理器
虽然现代CSS已经非常强大,但预处理器和后处理器仍然在开发工作流中扮演重要角色:
预处理器(如Sass、Less)
- 提供变量、嵌套、混合、函数等功能
- 允许模块化CSS代码
- 提供条件逻辑和循环
后处理器(如PostCSS)
- 自动添加浏览器前缀(Autoprefixer)
- 转换现代CSS语法为兼容性更好的代码
- 优化和压缩CSS
CSS架构与方法论
BEM(Block, Element, Modifier)
css
/* Block */
.card {}
/* Element */
.card__title {}
.card__image {}
.card__content {}
/* Modifier */
.card--featured {}
.card__title--large {}CUBE CSS
- Composition(组合)
- Utility(工具)
- Block(块)
- Exception(例外)
css
/* Composition */
.flow > * + * {
margin-top: var(--flow-space, 1em);
}
/* Utility */
.center {
max-width: var(--content-max-width);
margin-left: auto;
margin-right: auto;
padding-left: var(--content-padding);
padding-right: var(--content-padding);
}
/* Block */
.card {
background: white;
border-radius: 0.5rem;
box-shadow: 0 5px 15px -5px rgba(0, 0, 0, 0.1);
}
/* Exception */
.card.featured {
border-left: 3px solid var(--primary-color);
}浏览器兼容性与渐进增强
特性查询(Feature Queries)
css
/* 基础样式 - 所有浏览器 */
.grid {
display: block;
}
/* 检查浏览器是否支持Grid */
@supports (display: grid) {
.grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
grid-gap: 20px;
}
}
/* 检查浏览器是否支持粘性定位 */
@supports (position: sticky) {
.header {
position: sticky;
top: 0;
z-index: 10;
}
}性能优化
关键CSS(Critical CSS)
- 提取并内联首屏渲染所需的CSS
- 异步加载非关键CSS
选择器性能
- 避免过度嵌套的选择器
- 避免通配符和低效选择器
- 使用类选择器而非标签选择器
动画性能
css
/* 优化动画性能 */
.element {
/* 使用transform和opacity进行动画,而不是改变布局属性 */
transform: translateX(0);
opacity: 1;
transition: transform 0.3s, opacity 0.3s;
/* 告诉浏览器这个元素将会被动画 */
will-change: transform, opacity;
}
.element:hover {
transform: translateX(10px);
opacity: 0.8;
}