出处:掘金

原作者:前端微白


避免 CSS 冲突的方案

1. 命名约定(BEM/OOCSS)

最基础的样式隔离方案,通过严格的命名规则避免冲突:

<div class="card">
  <button class="card__btn card__btn--primary">提交</button>
</div>

<style>
/* BEM 方法 */
.card__btn {
  padding: 8px 16px;
  border-radius: 4px;
}

.card__btn--primary {
  background: #3498db;
  color: white;
}
</style>

核心特点:

2. CSS Modules:自动化的局部作用域

import styles from './Button.module.css';

function Button() {
  return (
    <button className={styles.primary}>
      Click me
    </button>
  );
}
/* Button.module.css */
.primary {
  background: #3498db;
  color: white;
}
/* 编译后生成:.Button_primary__d4f2a */

原理:编译构建时自动重命名类选择器,实现自动隔离

优势:

3. 预处理器的嵌套规则

// SCSS方式实现隔离
.widget {
  // 只在 .widget 内部应用
  button {
    background: #3498db;
    color: white;
    
    &:hover {
      background: #2980b9;
    }
  }
}

编译后输出:

.widget button {
  background: #3498db;
  color: white;
}
.widget button:hover {
  background: #2980b9;
}

适用场景:

4. CSS-in-JS:运行时样式隔离

// 使用 styled-components 实现隔离
import styled from 'styled-components';

const StyledButton = styled.button`
  background: ${props => props.primary ? '#3498db' : '#e0e0e0'};
  color: ${props => props.primary ? 'white' : 'black'};
  /* 其他样式 */
`;

// 使用
<StyledButton primary>提交</StyledButton>

核心特性:

流行库:styled-components, Emotion, JSS

5. Vue 的 scoped

<template>
  <button class="btn">点我</button>
</template>

<style scoped>
.btn {
  background: #3498db;
  color: white;
}
</style>

输出效果:

<button class="btn" data-v-497f297a>点我</button>

<style>
.btn[data-v-497f297a] {
  background: #3498db;
  color: white;
}
</style>

原理:添加组件唯一属性选择器实现样式隔离

6. Shadow DOM:原生的隔离解决方案

<template id="user-card">
  <style>
    button {
      background: #3498db;
      color: white;
    }
  </style>
  <button>点我</button>
</template>

<script>
class UserCard extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    const template = document.getElementById('user-card');
    shadow.appendChild(template.content.cloneNode(true));
  }
}
customElements.define('user-card', UserCard);
</script>

特点:

7. CSS Containment:未来新标准

.isolated-component {
  contain: style layout paint;
}

作用

注意

此功能仍在发展中,请勿在生产环境使用,但代表未来方向

8. Iframe 隔离:终极隔离方案

<!DOCTYPE html>
<html>
<head>
  <style>
    iframe {
      border: 2px solid #3498db;
      border-radius: 8px;
    }
  </style>
</head>
<body>
  <h2>主应用区域</h2>
  
  <!-- 完全隔离的微前端应用 -->
  <iframe 
    src="widget.html"
    title="隔离组件"
    width="400"
    height="300"
  ></iframe>
</body>
</html>

特点:

样式隔离技术对比分析

技术 隔离级别 学习曲线 性能影响 适用场景
命名约定 小型项目
CSS Modules React/Vue 组件库
预处理器嵌套规则 传统项目
CSS-in-JS 非常高 中高 动态主题应用
Vue scoped Vue.js 项目
Shadow DOM 完全隔离 Web 组件
CSS Containment 中高 未来 Web 应用
Iframe 完全隔离 第三方插件/微前端应用

扩展资源: