Tailwind CSS - 样式复用
Tailwind CSS 采用实用功能优先的方法,即使用小型、专注、单一用途的类来构建设计。这种方法有助于避免复杂性并保持代码的一致性。
在开发项目时,您可能会发现自己在多个地方使用同一套实用功能类。与其为重复的样式编写自定义 CSS,不如使用Tailwind 的实用功能类来高效地处理这些重复内容。
这是一个在网页上显示个人资料小部件的简单示例,每个小部件都应用了类似的实用功能类三次。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-4 bg-gray-100">
<div class="flex space-x-4 overflow-x-auto p-4 bg-gray-200">
<!-- Profile Widget 1 -->
<div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300
rounded-lg shadow-lg flex flex-col items-center space-y-3">
<div class="mb-3">
<img class="h-20 w-20 rounded-full border-4 border-cyan-500
shadow-md" src="https://randomuser.me/api/portraits/men/1.jpg"
alt="Profile Picture"/>
</div>
<div class="text-center">
<h3 class="text-lg font-semibold text-gray-800 mb-1">John Doe</h3>
<p class="text-gray-600 text-sm mb-2">Tech Enthusiast</p>
<p class="text-gray-500 text-xs">John has over 5 years of
experience in the tech industry, focusing on software
development and innovation.
</p>
</div>
</div>
<!-- Profile Widget 2 -->
<div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300
rounded-lg shadow-lg flex flex-col items-center space-y-3">
<div class="mb-3">
<img class="h-20 w-20 rounded-full border-4 border-rose-500
shadow-md" src="https://randomuser.me/api/portraits/women/2.jpg"
alt="Profile Picture"/>
</div>
<div class="text-center">
<h3 class="text-lg font-semibold text-gray-800 mb-1">
Jane Smith
</h3>
<p class="text-gray-600 text-sm mb-2">UI/UX Designer</p>
<p class="text-gray-500 text-xs">Jane is a skilled UI/UX
designer with 3 years of experience in creating intuitive user
interfaces and enhancing user experiences.
</p>
</div>
</div>
<!-- Profile Widget 3 -->
<div class="flex-shrink-0 w-56 p-4 bg-white border border-gray-300
rounded-lg shadow-lg flex flex-col items-center space-y-3">
<div class="mb-3">
<img class="h-20 w-20 rounded-full border-4 border-violet-500
shadow-md" src="https://randomuser.me/api/portraits/men/3.jpg"
alt="Profile Picture"/
>
</div>
<div class="text-center">
<h3 class="text-lg font-semibold text-gray-800 mb-1">
Alice Johnson</h3>
<p class="text-gray-600 text-sm mb-2">Data Scientist</p>
<p class="text-gray-500 text-xs">Alice has 7 years
of experience as a data scientist, specializing in data
analysis and machine learning.
</p>
</div>
</div>
</div>
</body>
</html>
别担心!我们将帮助您了解如何在项目中复用样式,以及何时有效地使用每种方法。
使用编辑器和语言功能
重复样式通常不是问题,因为它们都集中在一个地方,或者使用循环创建,因此您只需编写一次代码。
如果您在单个文件中工作,请使用多光标编辑功能一次更改多行。对于重复元素,请使用循环从一段代码生成它们。这可以让您的工作高效且井然有序。
多光标编辑
多光标编辑是许多文本编辑器中的一项功能,可让您在文档中的不同位置放置多个光标。这使得您可以一次性在多个位置进行相同的更改,非常适合快速更新重复内容。
当单个文件中包含重复的样式或元素时,多光标编辑功能可以帮助您一次性修改所有样式或元素。让我们通过一个示例来了解其工作原理。
假设您有以下项目列表,并且您希望将每个项目的类名从 bg-red-100 更新为 bg-teal-100。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-4">
<h3 class="font-bold underline mb-4">
List of Item in Shopping cart:
</h3>
<ul class="shopping-cart">
<li class="bg-red-100 p-2">Apples</li>
<li class="bg-red-100 p-2">Bananas</li>
<li class="bg-red-100 p-2">Oranges</li>
<li class="bg-red-100 p-2">Grapes</li>
</ul>
</body>
</html>
添加光标
按住 Alt 键并点击代码中每个 bg-red-100 旁边的 。这会将一个光标放置在您点击的每个位置,并在所有光标都位于原位的情况下输入 bg-teal-100。所有 bg-red-100 实例将立即更新为 bg-teal-100。
更新后的代码:
<ul class="shopping-cart">
<li class="bg-teal-100 p-2">Apples</li>
<li class="bg-teal-100 p-2">Bananas</li>
<li class="bg-teal-100 p-2">Oranges</li>
<li class="bg-teal-100 p-2">Grapes</li>
</ul>
您可能会发现,使用多光标编辑通常是处理重复样式最简单的方法。它可以帮助您一次性更新所有实例,因此您无需额外的工具或方法。
循环
循环在编程中可以更轻松地处理重复元素。您可以使用循环自动创建相同的 HTML 结构,而无需一遍又一遍地编写相同的代码。因此,在 Web 项目中处理重复的设计元素时,有效地使用循环非常重要。
在为每个重复的设计元素创建单独的组件或自定义类之前,请检查您是否多次使用了该元素。
例如,本指南开头显示的配置文件小部件使用了相同的设计,重复了三次。我们可以使用循环从单个模板生成多个元素,而无需逐个编写每个小部件。让我们在下面的示例中看看它是如何工作的。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-4">
<div id="profile-container" class="flex space-x-4 overflow-x-auto
p-4 bg-gray-200">
<!-- Profile Widgets will be dynamically inserted here -->
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const profiles = [
{ name: "John Doe", role:
"Tech Enthusiast",
imgSrc: "https://randomuser.me/api/portraits/men/1.jpg",
borderColor: "border-cyan-500" },
{ name: "Jane Smith", role: "UI/UX Designer",
imgSrc: "https://randomuser.me/api/portraits/women/2.jpg",
borderColor: "border-rose-500" },
{ name: "Alice Johnson", role: "Data Scientist",
imgSrc: "https://randomuser.me/api/portraits/men/3.jpg",
borderColor: "border-violet-500" }
];
const container = document.getElementById('profile-container');
profiles.forEach(profile => {
container.innerHTML += `
<div class="flex-shrink-0 w-56 p-4 bg-white border
border-gray-300 rounded-lg shadow-lg flex flex-col items-center space-y-3">
<div class="mb-3">
<img class="h-20 w-20 rounded-full border-4 ${profile.borderColor} shadow-md"
src="${profile.imgSrc}" alt="Profile Picture"/>
</div>
<div class="text-center">
<h3 class="text-lg font-semibold text-gray-800 mb-1">
${profile.name}</h3>
<p class="text-gray-600 text-sm mb-2">
${profile.role}</p>
<p class="text-gray-500 text-xs">Profile description here.</p>
</div>
</div>
`;
});
});
</script>
</body>
</html>
使用 loop 意味着您只需编写一次标记,避免重复,并简化更新。它可以高效地管理动态数据,并确保更改在一处应用。
提取组件和局部代码
如果您想在不同文件中复用样式,如果您使用的是 React、Swelte 或 Vue 等前端框架,则最好创建一个组件。如果您使用的是 Blade、ERB、Twig 或 Nunjucks 等模板语言,则应该创建一个模板局部代码。这种方法有助于保持代码井然有序,并使其更易于维护。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-4">
<div class="testimonial-sectio">
<div class="testimonial-card p-4 bg-white border border-gray-300
rounded-lg shadow-lg">
<img class="w-16 h-16 rounded-full border-2 border-gray-300"
src="https://randomuser.me/api/portraits/men/1.jpg"
alt="Alice Johnson's photo" />
<h3 class="mt-2 text-lg font-semibold text-gray-800">
Alice Johnson
</h3>
<p class="mt-1 text-gray-600">
This service is fantastic! It exceeded all my expectations.
</p>
</div>
<div class="testimonial-card p-4 bg-white border border-gray-300
rounded-lg shadow-lg mt-4">
<img class="w-16 h-16 rounded-full border-2 border-gray-300"
src="https://randomuser.me/api/portraits/women/2.jpg"
alt="Bob Smith's photo" />
<h3 class="mt-2 text-lg font-semibold text-gray-800">
Bob Smith
</h3>
<p class="mt-1 text-gray-600">
An excellent experience from start to finish.
</p>
</div>
</div>
</body>
</html>
对于上面的示例,请使用 Tailwind CSS 在 React 中创建一个 TestimonialCard 组件,并根据项目需要多次使用它。下面是一个可用于显示用户评价的函数式组件。
示例
// TestimonialCard.jsx
import React from 'react';
const TestimonialCard = ({ name, photo, testimonial }) => (
<div className="p-4 bg-white border border-gray-300 rounded-lg shadow-lg">
<img
className="w-16 h-16 rounded-full border-2 border-gray-300"
src={photo}
alt={`${name}'s photo`}
/>
<h3 className="mt-2 text-lg font-semibold text-gray-800">{name}</h3>
<p className="mt-1 text-gray-600">{testimonial}</p>
</div>
);
export default TestimonialCard;
要在您的应用或设计中使用 TestimonialCard 组件,只需导入它并提供必要的属性即可。
示例
// App.jsx
import React from 'react';
import TestimonialCard from './TestimonialCard';
const App = () => (
<div className="p-4 bg-gray-100">
<div className="flex space-x-4">
<TestimonialCard
name="John Doe"
photo="https://randomuser.me/api/portraits/men/1.jpg"
testimonial="John's experience was wonderful.
The service was top-notch and exceeded expectations."
/>
<TestimonialCard
name="Jane Smith"
photo="https://randomuser.me/api/portraits/women/2.jpg"
testimonial="Jane had a fantastic experience!
Highly recommended for anyone looking for quality service."
/>
</div>
</div>
);
export default App;
可在任何地方使用此组件,并可轻松从一处更新样式。
与 CSS 抽象的比较
在设计 Web 界面时,仅使用 CSS 不足以处理复杂的组件。您需要同时使用 HTML 和 CSS 才能有效地处理详细的 UI 元素。
以"进度跟踪器"为例。组件不是使用 CSS 单独设置每个步骤的样式,而是将每个步骤的 HTML 和 CSS 组合在一起。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="flex justify-center items-center h-screen bg-gray-100">
<div class="w-full max-w-3xl px-4 py-6 bg-white rounded-lg shadow-md">
<div class="text-center mb-8 text-gray-800">
<p class="text mb-4 ml-4">
This tracker shows your progress through different stages:
</p>
<ul class="list-disc list-inside text-left text-gray-600">
<li><strong class="text-green-500">Completed:</strong>
Finished steps
</li>
<li><strong class="text-yellow-500">Current:</strong>
The active step
</li>
<li><strong class="text-gray-300">Upcoming:</strong>
Future steps
</li>
</ul>
</div>
<div class="relative flex items-center">
<div class="absolute inset-0 flex items-center pointer-events-none">
<div class="flex-1 h-1 bg-green-500"></div>
<div class="flex-1 h-1 bg-yellow-400"></div>
<div class="flex-1 h-1 bg-gray-300"></div>
<div class="flex-1 h-1 bg-gray-300"></div>
</div>
<!-- Steps -->
<div class="flex-1 text-center relative z-10">
<div class="w-12 h-12 rounded-full bg-green-500 text-white
flex items-center justify-center mx-auto mb-2 text-2xl">✔</div>
<div class="text-sm">Step 1</div>
</div>
<div class="flex-1 text-center relative z-10">
<div class="w-12 h-12 rounded-full bg-yellow-500 text-white
flex items-center justify-center mx-auto mb-2 text-2xl">▶</div>
<div class="text-sm">Step 2</div>
</div>
<div class="flex-1 text-center relative z-10">
<div class="w-12 h-12 rounded-full bg-gray-200 text-white
flex items-center justify-center mx-auto mb-2 text-2xl">•</div>
<div class="text-sm">Step 3</div>
</div>
<div class="flex-1 text-center relative z-10">
<div class="w-12 h-12 rounded-full bg-gray-200 text-white
flex items-center justify-center mx-auto mb-3 text-2xl">•</div>
<div class="text-sm">Step 4</div>
</div>
<div class="absolute right-0 top-1/2 w-1/4 h-px bg-gray-300"></div>
</div>
</div>
</body>
</html>
即使使用类进行样式设置,每次使用该组件时也都需要重复编写 HTML 代码。虽然更新字体大小很简单,但仅使用 CSS 进行更复杂的更改(例如将标题转换为链接)则很困难。
组件和模板部分组件更佳,因为它们结合了 HTML 和 样式。这样,您可以在一个地方更新字体大小或将所有标题更改为链接。
考虑使用 模板部分组件 或 JavaScript 组件 以获得更简单的解决方案。
示例
import React from 'react';
function Step({ status, number }) {
const statusClasses = {
completed: 'bg-green-500',
current: 'bg-yellow-500',
upcoming: 'bg-gray-200'
};
return (
<div className="flex-1 text-center relative z-10">
<div className={`w-12 h-12 rounded-full ${statusClasses[status]}
text-white flex items-center justify-center mx-auto mb-2 text-2xl`}>
{status === 'completed' ? '✔' : status === 'current' ? '▶' : '•'}
</div>
<div className="text-sm">Step {number}</div>
</div>
);
}
function ProgressTracker() {
return (
<div className="relative flex items-center">
<div className="absolute inset-0 flex items-center pointer-events-none">
<div className="flex-1 h-1 bg-green-500"></div>
<div className="flex-1 h-1 bg-yellow-400"></div>
<div className="flex-1 h-1 bg-gray-300"></div>
<div className="flex-1 h-1 bg-gray-300"></div>
</div>
<Step status="completed" number={1} />
<Step status="current" number={2} />
<Step status="upcoming" number={3} />
<Step status="upcoming" number={4} />
<div className="absolute right-0 top-1/2 w-1/4 h-px bg-gray-300"></div>
</div>
);
}
export default ProgressTracker;
使用 组件 和 模板 部分,您只需要实用类,因为样式都在一个地方处理。
使用 Tailwind 的 @apply 指令提取类
在设计网页时,重复使用相同的 实用类 会使您的 HTML 变得混乱且难以管理。Tailwind CSS 通过 @apply 指令 来解决这个问题。
什么是 @apply ?何时使用它?
@apply 指令允许您通过应用一组 Tailwind 实用类 来创建自定义 CSS 类。这通过将重复的样式移动到 CSS 文件中,使您的 HTML 更简洁。
虽然模板部分适用于复杂的组件,但 @apply 非常适合常用的样式。它有助于保持 HTML 简洁,并保持一致的样式。
在使用 @apply 之前,您可以直接在 HTML 中添加多个实用程序类来设置卡片的样式。
示例
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="p-4 bg-gray-200">
<div class="p-6 max-w-sm mx-auto bg-white rounded-lg shadow-md">
<h2 class="text-xl font-bold mb-2">Card Title</h2>
<p class="text-gray-700 ">
This is a card component styled with Tailwind utilities.
</p>
</div>
</body>
</html>
使用 @apply: 后,在 CSS 中为卡片定义一个自定义类,然后在 HTML 中使用它:
<div class="card">
<h2 class="card-title">Card Title</h2>
<p class="card-content">
This is a card component
styled with Tailwind utilities.
</p>
</div>
带有 @apply 的 CSS
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
.card {
@apply p-6 max-w-sm mx-auto bg-white rounded-lg shadow-md;
}
.card-title {
@apply text-xl font-bold mb-2;
}
.card-content {
@apply text-gray-700;
}
}
使用 @apply 指令有助于保持样式的条理性和代码的简洁性。
避免过早抽象
不要仅仅为了清理 HTML 代码而使用 @apply。这看似是个好主意,但它可能会带来更多问题:
- 命名问题:想出类名可能很累人。
- 多次编辑:过度使用 @apply 意味着需要不断在 CSS 和 HTML 之间切换。
- 样式更改:对一个类的更改可能会无意中影响网站的其他部分。
- 更大的 CSS 文件:许多自定义类会增加 CSS 文件的大小并影响性能。
对按钮等小型可重复使用的项目使用 @apply,或者使用像 React 这样的框架中的组件来实现更好的管理。

