CSS 函数详解
一、calc() 函数
calc() 函数用于动态计算长度值。
基本语法
/* 最终计算得到 width:300px */
width: calc(100px + 200px);
/* 先算乘法,再算减法 得到 width:150px */
width: calc(100px - 50px * -1);
/* 先算除法,再算减法 得到 width:75px */
width: calc(100px - 50px / 2);
/* 先算除法,再算减法,假设 100% 对应父元素宽为 200px,则算得结果 175px */
width: calc(100% - 50px / 2);使用注意事项
| 注意事项 | 说明 |
|---|---|
| 支持运算符 | calc() 函数支持 + - * / 运算 |
| 运算符空格 | 运算符前后都需要保留一个空格,例如:width: calc(100% - 10px); |
* / 空格 | * 和 / 时,其前后可以没有空格,但建议留有空格 |
| 支持单位 | 任何长度值都可以使用 calc() 函数进行计算 |
| 单位类型 | 可以使用百分比、px、em、rem 等单位 |
| 运算优先级 | calc() 函数使用标准的数学运算优先级规则 |
案例演示
<style>
.box {
/* 宽始终比浏览器小 100px */
width: calc(100% - 100px);
height: 200px;
/* 水平居中 */
margin: 0px auto;
background-color: skyblue;
}
</style>
<body>
<div class="box"></div>
</body>实战应用场景
场景1: 自适应宽度减去固定值
.container {
width: calc(100% - 200px); /* 总宽度减去侧边栏宽度 */
}
/* 侧边栏 + 主内容布局 */
.sidebar {
width: 200px;
}
.main {
width: calc(100% - 200px);
}场景2: 居中对齐
.center-element {
position: absolute;
left: calc(50% - 50px); /* 水平居中,元素宽 100px */
top: calc(50% - 50px); /* 垂直居中,元素高 100px */
width: 100px;
height: 100px;
}场景3: 响应式网格布局
.grid-item {
width: calc(33.33% - 20px); /* 三列布局,减去间距 */
margin-right: 20px;
}
.grid-item:last-child {
margin-right: 0;
}二、var() 函数
1. :root 选择器
:root 选择器用于匹配文档的(html)根元素。
/* 页面背景色为红色 */
:root {
background-color: red;
}:root 与 html 选择器的区别
两者的唯一区别在于 :root 选择器的优先级要高于 html 标签选择器。
:root {
/* 背景黄色 */
background-color: khaki;
}
html {
/* 背景天蓝色 */
background-color: skyblue;
}结果: 因为 :root 的优先级高于 html 标签选择器,则最终的浏览器背景以 khaki 黄色呈现。
2. var() 函数解读
var() 函数用于插入自定义的属性值(CSS 变量),如果一个属性值在多处被使用,该方法就很有用。
规则
- 自定义属性一定要以
--开头 - 自定义属性会从自身开始一直向外找,以最近找到的为主
- 写在后面的自定义属性会覆盖写在前面的
基本用法
<style>
:root {
/* 自定义属性 */
--font-color: red;
}
.box {
/* 自定义属性 */
--font-color: blue;
}
.item {
/* var 函数调用自定义属性 */
color: var(--font-color); /* 使用 .box 中的 blue */
}
</style>
<body>
<div class="box">
<div class="item">自定义属性的寻找原则:就近原则</div>
</div>
</body>全局自定义属性
通常自定义属性是写在 :root 选择器中,并且 :root 选择器会放在 CSS 的最上面,这样所有的选择器都能用到这个自定义变量属性。
<style>
:root {
/* --开头,表示自定义属性 */
--font-color: red;
--font-size: 20px;
--primary-color: #007bff;
--secondary-color: #6c757d;
--spacing: 16px;
}
h3 {
/* 字体颜色为红色 */
color: var(--font-color);
}
p {
/* 字体大小为 20px */
font-size: var(--font-size);
}
ul li {
font-size: var(--font-size);
color: var(--font-color);
}
</style>实战应用场景
场景1: 主题切换
<style>
/* 默认主题 */
:root {
--primary-color: #000;
--font-color: #fff;
--background-color: #fff;
}
/* 红色主题 */
.theme-red {
--primary-color: red;
--font-color: yellow;
--background-color: #fff0f0;
}
/* 蓝色主题 */
.theme-blue {
--primary-color: blue;
--font-color: #fff;
--background-color: #f0f8ff;
}
/* 引用主题色 */
body {
background-color: var(--background-color);
color: var(--font-color);
}
.button {
background-color: var(--primary-color);
}
</style>
<!-- 动态设置 html class 的属性值,用来切换主题 -->
<html lang="en" class="theme-red">
<body>
我是页面中文字
<button class="button">按钮</button>
</body>
</html>场景2: 间距统一管理
:root {
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
}
.card {
padding: var(--spacing-md);
margin-bottom: var(--spacing-lg);
}
.button {
padding: var(--spacing-sm) var(--spacing-md);
}场景3: 颜色系统
:root {
--color-primary: #007bff;
--color-secondary: #6c757d;
--color-success: #28a745;
--color-danger: #dc3545;
--color-warning: #ffc107;
}
.btn-primary {
background-color: var(--color-primary);
}
.btn-success {
background-color: var(--color-success);
}三、其他 CSS 函数
1. rgb() 和 rgba()
/* RGB */
color: rgb(255, 0, 0);
/* RGBA - 带透明度 */
color: rgba(255, 0, 0, 0.5);
background-color: rgba(0, 0, 0, 0.1);2. hsl() 和 hsla()
/* HSL */
color: hsl(120, 100%, 50%); /* 绿色 */
/* HSLA - 带透明度 */
color: hsla(120, 100%, 50%, 0.5);3. url()
background-image: url('./images/bg.png');
background-image: url('https://example.com/image.jpg');四、综合实战案例
案例1: 竖状文件夹结构
<style>
:root {
--folder-structure-item-height: 20px; /* 每个 li 行高 */
--folder-structure-item-margin-left: 30px; /* 每个 ul 左外边距 */
--folder-structure-item-padding-top: 15px; /* 每个 li 上外边距 */
}
body {
font-size: 20px;
}
/* 清除默认样式 */
body, ul, li {
margin: 0;
padding: 0;
}
.folder-structure {
margin-left: 100px;
}
ul {
list-style-type: none;
margin-left: 30px;
margin-left: var(--folder-structure-item-margin-left);
}
.folder-structure li {
line-height: 20px;
padding-top: 15px;
padding-top: var(--folder-structure-item-padding-top);
position: relative;
}
/* 制作竖直线 */
.folder-structure li::before {
content: "";
position: absolute;
top: 0;
left: 0;
height: 100%;
border-left: 1px solid #333;
margin-left: -30px;
margin-left: calc(-1 * var(--folder-structure-item-margin-left));
}
/* 制作水平横线 */
.folder-structure li::after {
content: "";
position: absolute;
left: 0;
top: calc(var(--folder-structure-item-padding-top) + var(--folder-structure-item-height) / 2);
border-bottom: 1px solid #333;
width: var(--folder-structure-item-margin-left);
margin-left: calc(-1 * var(--folder-structure-item-margin-left));
}
/* 更改每一级最后一个 li 的高度 */
.folder-structure li:last-child::before {
height: calc(var(--folder-structure-item-padding-top) + var(--folder-structure-item-height) / 2);
}
</style>
<body>
<div class="folder-structure">
<ul>
<!-- 一级目录 -->
<li>
前端
<ul>
<!-- 二级目录 -->
<li>HTML</li>
<li>
CSS
<!-- 三级目录 -->
<ul>
<li>文本样式</li>
<li>盒子模型</li>
<li>position 定位</li>
<li>背景样式</li>
</ul>
</li>
<li>JavaScript</li>
<li>Vue</li>
<li>React</li>
</ul>
</li>
<li>Java</li>
<li>Python</li>
</ul>
</div>
</body>五、最佳实践
1. 合理命名 CSS 变量
/* ✅ 推荐: 语义化命名 */
:root {
--color-primary: #007bff;
--font-size-base: 16px;
--spacing-md: 16px;
}
/* ❌ 不推荐: 无意义命名 */
:root {
--color1: #007bff;
--fs: 16px;
--s: 16px;
}2. 提供默认值
/* 提供默认值,防止变量未定义 */
.element {
color: var(--font-color, #000);
padding: var(--spacing, 16px);
}3. 使用 calc() 结合变量
:root {
--spacing-base: 16px;
--container-width: 1200px;
}
.element {
padding: calc(var(--spacing-base) / 2);
width: calc(var(--container-width) - 200px);
}