CSS重要函数:变量、URL和属性函数
CSS提供了众多功能强大的函数,其中var()、url()和attr()是三个非常实用且应用场景各不相同的函数。本文将详细介绍这三个函数的使用方法、应用场景以及它们如何提升CSS的开发效率和维护性。
1. var()函数:CSS自定义变量
CSS自定义属性(也称为CSS变量)允许开发者在整个样式表中存储和复用值,大大提高了CSS代码的可维护性。
1.1 基本语法与使用
自定义属性名需要以两个减号(--)开头,属性值则可以是任何有效的CSS值。通过var()函数可以获取这些自定义属性的值。
/* 在根元素定义全局变量 */
:root {
--primary-color: #eb6844;
--secondary-color: #2b2b2b;
--default-font-size: 1rem;
--main-padding: 15px;
}
/* 使用变量 */
.element {
color: var(--primary-color);
background: var(--secondary-color);
font-size: var(--default-font-size);
padding: var(--main-padding);
}1.2 变量作用域
CSS变量遵循作用域规则,分为全局变量和局部变量。
/* 全局变量 */
:root {
--main-bg-color: brown;
--text-color: #333;
}
/* 局部变量 */
.container {
--container-width: 1200px;
--internal-padding: 20px;
width: var(--container-width);
background-color: var(--main-bg-color);
}
/* 只能在.container及其子元素中使用--internal-padding */
.content {
padding: var(--internal-padding);
color: var(--text-color);
}1.3 回退值处理
当变量无效或未定义时,var()函数可以接受回退值。
.element {
/* 如果--primary-color不存在,使用orange */
color: var(--primary-color, orange);
/* 嵌套回退值 */
background-color: var(--undefined-var, var(--secondary-color, #fff));
/* 多个回退值 */
font-size: var(--undefined-size, var(--another-undefined, 16px));
}1.4 与calc()函数结合
CSS变量可以与calc()函数结合进行动态计算。
:root {
--base-size: 12;
--spacing-unit: 8px;
}
.element {
/* 正确写法 */
font-size: calc(1px * var(--base-size));
margin: calc(var(--spacing-unit) * 2);
/* 错误写法:font-size: calc(1 * var(--size)px); */
}1.5 完整示例页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS var()函数示例</title>
<style>
:root {
--theme-color: #3498db;
--text-color: #2c3e50;
--spacing: 20px;
--border-radius: 8px;
--box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.card {
background-color: white;
padding: var(--spacing);
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
margin: var(--spacing);
border-left: 4px solid var(--theme-color);
}
.card h3 {
color: var(--theme-color);
margin-top: 0;
}
.card p {
color: var(--text-color);
line-height: 1.6;
}
.button {
display: inline-block;
background-color: var(--theme-color);
color: white;
padding: 10px 20px;
border-radius: var(--border-radius);
text-decoration: none;
border: none;
cursor: pointer;
}
.button:hover {
opacity: 0.9;
}
</style>
</head>
<body>
<div class="card">
<h3>CSS变量示例</h3>
<p>这个卡片使用CSS自定义属性定义样式。尝试修改根元素中的变量值来查看变化。</p>
<button class="button">示例按钮</button>
</div>
</body>
</html>1.6 使用JavaScript操作CSS变量
CSS变量可以通过JavaScript动态获取和修改。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JavaScript操作CSS变量</title>
<style>
:root {
--primary-color: #3498db;
--box-size: 150px;
}
.box {
width: var(--box-size);
height: var(--box-size);
background-color: var(--primary-color);
margin: 20px auto;
transition: all 0.3s ease;
}
.controls {
text-align: center;
margin: 20px;
}
button {
padding: 8px 16px;
margin: 0 5px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="box" id="zzw_demoBox"></div>
<div class="controls">
<button onclick="zzw_changeColor('#e74c3c')">红色</button>
<button onclick="zzw_changeColor('#2ecc71')">绿色</button>
<button onclick="zzw_changeColor('#3498db')">蓝色</button>
<button onclick="zzw_changeSize('200px')">变大</button>
<button onclick="zzw_changeSize('100px')">变小</button>
</div>
<script>
// 获取根元素
const zzw_root = document.documentElement;
// 修改变量值函数
function zzw_changeColor(color) {
zzw_root.style.setProperty('--primary-color', color);
}
function zzw_changeSize(size) {
zzw_root.style.setProperty('--box-size', size);
}
// 获取变量值
function zzw_getVariableValue(varName) {
return getComputedStyle(zzw_root).getPropertyValue(varName);
}
// 示例:获取当前主要颜色
console.log('当前主要颜色:', zzw_getVariableValue('--primary-color'));
</script>
</body>
</html>2. url()函数:处理外部资源
url()函数用于在CSS中引用外部资源,如背景图像、字体文件等。
2.1 基本语法
element {
background-image: url(path/to/resource);
}2.2 不同路径写法
url()函数支持多种路径写法,适应不同的资源位置需求。
/* 相对路径 */
.logo {
background-image: url(images/logo.png);
}
/* 向上一级目录 */
.background {
background-image: url(../assets/bg.jpg);
}
/* 进入子目录 */
.icon {
background-image: url(icons/user.svg);
}
/* 根路径 */
.banner {
background-image: url(/images/banner.jpg);
}
/* 绝对URL */
.external {
background-image: url(https://example.com/images/photo.jpg);
}2.3 完整示例页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS url()函数示例</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 20px;
}
.image-container {
width: 100%;
height: 300px;
margin: 20px 0;
border: 1px solid #ddd;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.local-image {
/* 假设项目目录中有images/bg.jpg文件 */
background-image: url(images/bg.jpg);
}
.absolute-image {
/* 使用在线图片URL */
background-image: url(https://via.placeholder.com/800x400/3498db/ffffff?text=Placeholder+Image);
}
.gradient-overlay {
/* 结合渐变使用 */
background-image:
linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)),
url(images/bg.jpg);
}
.custom-cursor {
cursor: url(images/cursor.png), auto;
}
@font-face {
font-family: 'CustomFont';
src: url(fonts/custom-font.woff2) format('woff2'),
url(fonts/custom-font.woff) format('woff');
}
.custom-font {
font-family: 'CustomFont', Arial, sans-serif;
}
</style>
</head>
<body>
<h1>CSS url()函数示例</h1>
<h2>本地图片背景</h2>
<div class="image-container local-image"></div>
<h2>在线图片背景</h2>
<div class="image-container absolute-image"></div>
<h2>渐变叠加背景</h2>
<div class="image-container gradient-overlay"></div>
<h2 class="custom-cursor">自定义光标(悬停查看)</h2>
<h2 class="custom-font">自定义字体示例</h2>
</body>
</html>2.4 注意事项
- 路径解析:相对路径是相对于CSS文件的位置,而不是HTML文件。
- 跨域问题:加载外部域资源时可能遇到跨域限制。
- 性能考虑:过多或过大的外部资源会影响页面加载性能。
- 错误处理:当资源加载失败时,需要有适当的回退方案。
3. attr()函数:获取HTML属性值
attr()函数用于获取所选元素的HTML属性值并在样式表中使用。
3.1 基本语法
element::before {
content: attr(attribute-name);
}3.2 支持的值类型
attr()函数可以接受类型参数,将属性值解析为特定的CSS数据类型。
/* 字符串(默认) */
.text::before {
content: attr(data-text);
}
/* 颜色值 */
.color-box {
background-color: attr(data-bg-color color);
}
/* 数值 */
.slider {
width: attr(data-width px, 100px);
}
/* URL */
.link {
background-image: attr(data-bg-url url);
}3.3 完整示例页面
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS attr()函数示例</title>
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
/* 基础用法 - 工具提示 */
.tooltip {
position: relative;
display: inline-block;
border-bottom: 1px dotted #333;
cursor: help;
margin: 20px 0;
}
.tooltip::after {
content: attr(data-tooltip);
position: absolute;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: white;
padding: 5px 10px;
border-radius: 4px;
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
font-size: 14px;
}
.tooltip:hover::after {
opacity: 1;
}
/* 进度条 */
.progress-bar {
width: 100%;
height: 20px;
background-color: #f0f0f0;
border-radius: 10px;
overflow: hidden;
margin: 15px 0;
}
.progress-bar::before {
content: "";
display: block;
height: 100%;
width: attr(data-progress %);
background-color: #3498db;
transition: width 0.3s ease;
}
/* 卡片组件 */
.card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 15px;
margin: 15px 0;
background-color: #f9f9f9;
}
.card::before {
content: attr(data-type);
display: inline-block;
background-color: #3498db;
color: white;
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
margin-bottom: 10px;
text-transform: uppercase;
}
/* 自定义列表 */
.custom-list {
list-style: none;
padding: 0;
}
.custom-list li {
margin: 10px 0;
padding-left: 25px;
position: relative;
}
.custom-list li::before {
content: attr(data-icon);
position: absolute;
left: 0;
top: 0;
width: 20px;
height: 20px;
text-align: center;
}
</style>
</head>
<body>
<h1>CSS attr()函数示例</h1>
<h2>工具提示</h2>
<div class="tooltip" data-tooltip="这是一个工具提示内容">
悬停在我上面查看工具提示
</div>
<h2>进度条</h2>
<div class="progress-bar" data-progress="75">
<div class="progress-text">75%</div>
</div>
<h2>卡片组件</h2>
<div class="card" data-type="信息">
<h3>卡片标题</h3>
<p>这是一个使用attr()函数显示类型的卡片。</p>
</div>
<div class="card" data-type="警告">
<h3>警告卡片</h3>
<p>这是一个警告类型的卡片。</p>
</div>
<h2>自定义列表</h2>
<ul class="custom-list">
<li data-icon="✓">列表项一</li>
<li data-icon="★">列表项二</li>
<li data-icon="➜">列表项三</li>
</ul>
</body>
</html>3.4 高级用法结合JavaScript
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>attr()与JavaScript结合</title>
<style>
:root {
--theme-color: #3498db;
}
.dynamic-element {
width: 200px;
height: 100px;
margin: 20px;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: bold;
}
/* 使用数据属性控制样式 */
.color-box[data-color="red"] {
background-color: #e74c3c;
}
.color-box[data-color="green"] {
background-color: #2ecc71;
}
.color-box[data-color="blue"] {
background-color: #3498db;
}
.size-box::after {
content: "宽度: " attr(data-width);
font-size: 14px;
margin-top: 10px;
display: block;
}
/* 动态内容 */
.user-card::before {
content: "用户: " attr(data-username);
display: block;
font-size: 12px;
color: #666;
margin-bottom: 5px;
}
</style>
</head>
<body>
<h1>attr()与JavaScript结合示例</h1>
<div class="dynamic-element color-box" data-color="red" id="zzw_colorBox">
颜色盒子
</div>
<div class="dynamic-element size-box" data-width="200px" id="zzw_sizeBox">
尺寸盒子
</div>
<div class="dynamic-element user-card" data-username="默认用户" id="zzw_userCard">
用户信息卡片
</div>
<button onclick="zzw_changeColor()">切换颜色</button>
<button onclick="zzw_changeSize()">改变尺寸</button>
<button onclick="zzw_changeUser()">更改用户</button>
<script>
const zzw_colorBox = document.getElementById('zzw_colorBox');
const zzw_sizeBox = document.getElementById('zzw_sizeBox');
const zzw_userCard = document.getElementById('zzw_userCard');
let zzw_colorIndex = 0;
const zzw_colors = ['red', 'green', 'blue'];
function zzw_changeColor() {
zzw_colorIndex = (zzw_colorIndex + 1) % zzw_colors.length;
zzw_colorBox.setAttribute('data-color', zzw_colors[zzw_colorIndex]);
}
function zzw_changeSize() {
const widths = ['200px', '250px', '300px', '150px'];
const currentWidth = zzw_sizeBox.getAttribute('data-width');
const currentIndex = widths.indexOf(currentWidth);
const nextIndex = (currentIndex + 1) % widths.length;
zzw_sizeBox.setAttribute('data-width', widths[nextIndex]);
zzw_sizeBox.style.width = widths[nextIndex];
}
function zzw_changeUser() {
const users = ['张三', '李四', '王五', '赵六'];
const randomUser = users[Math.floor(Math.random() * users.length)];
zzw_userCard.setAttribute('data-username', randomUser);
}
</script>
</body>
</html>3.5 注意事项
- 浏览器兼容性:除了
content属性外,其他属性对attr()的支持仍处于实验阶段。 - 类型限制:需要确保HTML属性的值与CSS属性期望的类型匹配。
- 性能考虑:过度使用可能导致性能问题,特别是在动态修改时。
4. 综合应用实例
下面是一个综合运用var()、url()和attr()函数的完整示例。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS函数综合示例</title>
<style>
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--danger-color: #e74c3c;
--text-color: #2c3e50;
--spacing: 15px;
--border-radius: 6px;
--box-shadow: 0 2px 5px rgba(0,0,0,0.1);
--background-url: url(https://via.placeholder.com/100/3498db/ffffff?text=IMG);
}
.dashboard {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: var(--spacing);
padding: var(--spacing);
max-width: 1200px;
margin: 0 auto;
}
.widget {
background: white;
border-radius: var(--border-radius);
box-shadow: var(--box-shadow);
padding: var(--spacing);
position: relative;
}
.widget::before {
content: attr(data-widget-type);
position: absolute;
top: -10px;
right: 10px;
background-color: var(--primary-color);
color: white;
padding: 2px 8px;
border-radius: 10px;
font-size: 12px;
text-transform: uppercase;
}
.widget-header {
display: flex;
align-items: center;
margin-bottom: 10px;
}
.widget-icon {
width: 40px;
height: 40px;
background-image: var(--background-url);
background-size: cover;
border-radius: 50%;
margin-right: 10px;
}
.widget-title {
color: var(--text-color);
margin: 0;
font-size: 18px;
}
.progress-container {
margin: 15px 0;
}
.progress-bar {
height: 10px;
background-color: #ecf0f1;
border-radius: 5px;
overflow: hidden;
}
.progress-fill {
height: 100%;
background-color: var(--secondary-color);
width: attr(data-progress %);
transition: width 0.5s ease;
}
.stats {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.stat-item {
text-align: center;
}
.stat-value {
font-size: 24px;
font-weight: bold;
color: var(--primary-color);
}
.stat-label {
font-size: 12px;
color: #7f8c8d;
}
/* 动态主题 */
.theme-selector {
text-align: center;
margin: 20px 0;
}
.theme-button {
padding: 8px 16px;
margin: 0 5px;
border: none;
border-radius: var(--border-radius);
cursor: pointer;
background-color: #bdc3c7;
color: var(--text-color);
}
.theme-button.active {
background-color: var(--primary-color);
color: white;
}
</style>
</head>
<body>
<div class="theme-selector">
<button class="theme-button active" onclick="zzw_changeTheme('default')">默认主题</button>
<button class="theme-button" onclick="zzw_changeTheme('dark')">暗色主题</button>
<button class="theme-button" onclick="zzw_changeTheme('warm')">暖色主题</button>
</div>
<div class="dashboard">
<div class="widget" data-widget-type="统计" data-progress="75">
<div class="widget-header">
<div class="widget-icon"></div>
<h3 class="widget-title">项目进度</h3>
</div>
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill" data-progress="75"></div>
</div>
<div class="stats">
<div class="stat-item">
<div class="stat-value">75%</div>
<div class="stat-label">完成度</div>
</div>
<div class="stat-item">
<div class="stat-value">15</div>
<div class="stat-label">剩余天数</div>
</div>
</div>
</div>
</div>
<div class="widget" data-widget-type="提醒" data-progress="30">
<div class="widget-header">
<div class="widget-icon"></div>
<h3 class="widget-title">任务状态</h3>
</div>
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill" data-progress="30"></div>
</div>
<div class="stats">
<div class="stat-item">
<div class="stat-value">30%</div>
<div class="stat-label">进行中</div>
</div>
<div class="stat-item">
<div class="stat-value">7/10</div>
<div class="stat-label">已完成</div>
</div>
</div>
</div>
</div>
<div class="widget" data-widget-type="信息" data-progress="90">
<div class="widget-header">
<div class="widget-icon"></div>
<h3 class="widget-title">资源使用</h3>
</div>
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill" data-progress="90"></div>
</div>
<div class="stats">
<div class="stat-item">
<div class="stat-value">90%</div>
<div class="stat-label">使用率</div>
</div>
<div class="stat-item">
<div class="stat-value">45GB</div>
<div class="stat-label">已使用</div>
</div>
</div>
</div>
</div>
</div>
<script>
function zzw_changeTheme(theme) {
const root = document.documentElement;
// 移除所有主题类
root.classList.remove('theme-default', 'theme-dark', 'theme-warm');
// 添加当前主题类
root.classList.add(`theme-${theme}`);
// 更新活跃按钮
document.querySelectorAll('.theme-button').forEach(btn => {
btn.classList.remove('active');
});
event.target.classList.add('active');
// 根据主题更新CSS变量
if (theme === 'dark') {
root.style.setProperty('--primary-color', '#9b59b6');
root.style.setProperty('--secondary-color', '#1abc9c');
root.style.setProperty('--text-color', '#ecf0f1');
root.style.setProperty('--background-url', 'url(https://via.placeholder.com/100/9b59b6/ffffff?text=IMG)');
} else if (theme === 'warm') {
root.style.setProperty('--primary-color', '#e67e22');
root.style.setProperty('--secondary-color', '#e74c3c');
root.style.setProperty('--text-color', '#34495e');
root.style.setProperty('--background-url', 'url(https://via.placeholder.com/100/e67e22/ffffff?text=IMG)');
} else {
// 默认主题
root.style.setProperty('--primary-color', '#3498db');
root.style.setProperty('--secondary-color', '#2ecc71');
root.style.setProperty('--text-color', '#2c3e50');
root.style.setProperty('--background-url', 'url(https://via.placeholder.com/100/3498db/ffffff?text=IMG)');
}
}
// 动态更新进度条
function zzw_animateProgress() {
document.querySelectorAll('.progress-fill').forEach(bar => {
const progress = bar.getAttribute('data-progress');
bar.style.width = progress + '%';
});
}
// 页面加载完成后执行动画
window.addEventListener('load', zzw_animateProgress);
</script>
</body>
</html>5. 浏览器兼容性总结
在使用这三个CSS函数时,需要注意浏览器兼容性问题:
| 函数 | 基本支持 | 备注 |
|---|---|---|
var() | 现代浏览器广泛支持 | IE不支持,新版Edge支持 |
url() | 所有浏览器完全支持 | 路径解析一致,跨域资源可能有限制 |
attr() | 基础功能支持良好 | 除content属性外,其他使用仍为实验性功能 |
知识点总结
| 知识点 | 内容描述 |
|---|---|
var()函数 | 用于访问CSS自定义属性(变量)的值,提高代码可维护性和主题一致性 |
| CSS变量定义 | 使用--前缀定义自定义属性,通常在:root伪类中定义全局变量 |
| 变量作用域 | CSS变量遵循作用域规则,分全局变量和局部变量,局部变量可覆盖全局变量 |
| 回退值 | var()函数支持提供回退值,当变量无效时使用 |
| JavaScript操作 | 可通过setProperty()和getPropertyValue()方法动态修改和获取CSS变量 |
url()函数 | 用于引用外部资源,如图片、字体等,支持相对路径和绝对路径 |
| 路径解析 | 相对路径相对于CSS文件位置解析,可使用多种路径格式 |
attr()函数 | 用于获取HTML元素的属性值并在CSS中使用,常用于content属性 |
| 属性类型 | attr()支持类型参数,可将属性值解析为颜色、数值等特定CSS数据类型 |
| 函数组合 | 三个函数可结合使用,并与calc()等其他CSS函数配合,实现复杂样式效果 |
通过掌握var()、url()和attr()这三个重要的CSS函数,开发者可以创建更加动态、可维护和响应式的网页设计,减少对JavaScript的依赖,提高开发效率。

