全局样式 #

一、createGlobalStyle 基础 #

1.1 基本使用 #

jsx
import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }

  body {
    font-family: 'Inter', sans-serif;
    background: #ffffff;
    color: #333333;
    line-height: 1.5;
  }

  h1, h2, h3, h4, h5, h6 {
    font-weight: 600;
  }

  a {
    text-decoration: none;
    color: inherit;
  }
`;

function App() {
  return (
    <>
      <GlobalStyle />
      <YourApp />
    </>
  );
}

1.2 全局样式位置 #

text
全局样式注入位置
┌─────────────────────────────────────────────────────────────┐
│                                                             │
│  <html>                                                     │
│    <head>                                                   │
│      <style data-styled="global">                           │
│        /* 全局样式注入在这里 */                              │
│      </style>                                               │
│    </head>                                                  │
│    <body>                                                   │
│      <div id="root">                                        │
│        <App>                                                │
│          <GlobalStyle />                                    │
│          ...                                                │
│        </App>                                               │
│      </div>                                                 │
│    </body>                                                  │
│  </html>                                                    │
│                                                             │
└─────────────────────────────────────────────────────────────┘

二、CSS 重置 #

2.1 现代重置 #

jsx
import { createGlobalStyle } from 'styled-components';

const Reset = createGlobalStyle`
  *,
  *::before,
  *::after {
    box-sizing: border-box;
  }

  * {
    margin: 0;
    padding: 0;
  }

  html {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }

  body {
    min-height: 100vh;
    line-height: 1.5;
  }

  img,
  picture,
  video,
  canvas,
  svg {
    display: block;
    max-width: 100%;
  }

  input,
  button,
  textarea,
  select {
    font: inherit;
  }

  p,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    overflow-wrap: break-word;
  }

  #root {
    isolation: isolate;
  }
`;

2.2 完整重置 #

jsx
const FullReset = createGlobalStyle`
  html,
  body,
  div,
  span,
  applet,
  object,
  iframe,
  h1,
  h2,
  h3,
  h4,
  h5,
  h6,
  p,
  blockquote,
  pre,
  a,
  abbr,
  acronym,
  address,
  big,
  cite,
  code,
  del,
  dfn,
  em,
  img,
  ins,
  kbd,
  q,
  s,
  samp,
  small,
  strike,
  strong,
  sub,
  sup,
  tt,
  var,
  b,
  u,
  i,
  center,
  dl,
  dt,
  dd,
  ol,
  ul,
  li,
  fieldset,
  form,
  label,
  legend,
  table,
  caption,
  tbody,
  tfoot,
  thead,
  tr,
  th,
  td,
  article,
  aside,
  canvas,
  details,
  embed,
  figure,
  figcaption,
  footer,
  header,
  hgroup,
  main,
  menu,
  nav,
  output,
  ruby,
  section,
  summary,
  time,
  mark,
  audio,
  video {
    margin: 0;
    padding: 0;
    border: 0;
    font-size: 100%;
    font: inherit;
    vertical-align: baseline;
  }

  article,
  aside,
  details,
  figcaption,
  figure,
  footer,
  header,
  hgroup,
  main,
  menu,
  nav,
  section {
    display: block;
  }

  *[hidden] {
    display: none;
  }

  body {
    line-height: 1;
  }

  ol,
  ul {
    list-style: none;
  }

  blockquote,
  q {
    quotes: none;
  }

  blockquote:before,
  blockquote:after,
  q:before,
  q:after {
    content: '';
    content: none;
  }

  table {
    border-collapse: collapse;
    border-spacing: 0;
  }
`;

2.3 Normalize.css #

jsx
const Normalize = createGlobalStyle`
  html {
    line-height: 1.15;
    -webkit-text-size-adjust: 100%;
  }

  body {
    margin: 0;
  }

  main {
    display: block;
  }

  h1 {
    font-size: 2em;
    margin: 0.67em 0;
  }

  hr {
    box-sizing: content-box;
    height: 0;
    overflow: visible;
  }

  pre {
    font-family: monospace, monospace;
    font-size: 1em;
  }

  a {
    background-color: transparent;
  }

  abbr[title] {
    border-bottom: none;
    text-decoration: underline;
    text-decoration: underline dotted;
  }

  b,
  strong {
    font-weight: bolder;
  }

  code,
  kbd,
  samp {
    font-family: monospace, monospace;
    font-size: 1em;
  }

  small {
    font-size: 80%;
  }

  sub,
  sup {
    font-size: 75%;
    line-height: 0;
    position: relative;
    vertical-align: baseline;
  }

  sub {
    bottom: -0.25em;
  }

  sup {
    top: -0.5em;
  }

  img {
    border-style: none;
  }

  button,
  input,
  optgroup,
  select,
  textarea {
    font-family: inherit;
    font-size: 100%;
    line-height: 1.15;
    margin: 0;
  }

  button,
  input {
    overflow: visible;
  }

  button,
  select {
    text-transform: none;
  }

  button,
  [type="button"],
  [type="reset"],
  [type="submit"] {
    -webkit-appearance: button;
  }

  button::-moz-focus-inner,
  [type="button"]::-moz-focus-inner,
  [type="reset"]::-moz-focus-inner,
  [type="submit"]::-moz-focus-inner {
    border-style: none;
    padding: 0;
  }

  button:-moz-focusring,
  [type="button"]:-moz-focusring,
  [type="reset"]:-moz-focusring,
  [type="submit"]:-moz-focusring {
    outline: 1px dotted ButtonText;
  }

  fieldset {
    padding: 0.35em 0.75em 0.625em;
  }

  legend {
    box-sizing: border-box;
    color: inherit;
    display: table;
    max-width: 100%;
    padding: 0;
    white-space: normal;
  }

  progress {
    vertical-align: baseline;
  }

  textarea {
    overflow: auto;
  }

  [type="checkbox"],
  [type="radio"] {
    box-sizing: border-box;
    padding: 0;
  }

  [type="number"]::-webkit-inner-spin-button,
  [type="number"]::-webkit-outer-spin-button {
    height: auto;
  }

  [type="search"] {
    -webkit-appearance: textfield;
    outline-offset: -2px;
  }

  [type="search"]::-webkit-search-decoration {
    -webkit-appearance: none;
  }

  ::-webkit-file-upload-button {
    -webkit-appearance: button;
    font: inherit;
  }

  details {
    display: block;
  }

  summary {
    display: list-item;
  }

  template {
    display: none;
  }

  [hidden] {
    display: none;
  }
`;

三、字体导入 #

3.1 Web 字体 #

jsx
const FontFace = createGlobalStyle`
  @font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url('https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuLyfAZ9hjp-Ek-_EeA.woff2') format('woff2');
  }

  @font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url('https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuGKYAZ9hjp-Ek-_EeA.woff2') format('woff2');
  }

  @font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url('https://fonts.gstatic.com/s/inter/v12/UcCO3FwrK3iLTeHuS_fvQtMwCp50KnMw2boKoduKmMEVuFuYAZ9hjp-Ek-_EeA.woff2') format('woff2');
  }
`;

3.2 本地字体 #

jsx
const LocalFonts = createGlobalStyle`
  @font-face {
    font-family: 'CustomFont';
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: 
      local('CustomFont Regular'),
      local('CustomFont-Regular'),
      url('/fonts/CustomFont-Regular.woff2') format('woff2'),
      url('/fonts/CustomFont-Regular.woff') format('woff');
  }

  @font-face {
    font-family: 'CustomFont';
    font-style: italic;
    font-weight: 400;
    font-display: swap;
    src: 
      local('CustomFont Italic'),
      local('CustomFont-Italic'),
      url('/fonts/CustomFont-Italic.woff2') format('woff2'),
      url('/fonts/CustomFont-Italic.woff') format('woff');
  }
`;

3.3 图标字体 #

jsx
const IconFont = createGlobalStyle`
  @font-face {
    font-family: 'IconFont';
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url('/fonts/IconFont.woff2') format('woff2'),
         url('/fonts/IconFont.woff') format('woff');
  }

  .icon {
    font-family: 'IconFont' !important;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
`;

四、全局变量 #

4.1 CSS 自定义属性 #

jsx
const CSSVariables = createGlobalStyle`
  :root {
    --color-primary: #667eea;
    --color-secondary: #764ba2;
    --color-success: #22c55e;
    --color-warning: #f59e0b;
    --color-danger: #ef4444;
    
    --color-text: #333333;
    --color-text-secondary: #6b7280;
    --color-background: #ffffff;
    --color-surface: #f9fafb;
    
    --font-family-main: 'Inter', sans-serif;
    --font-family-heading: 'Poppins', sans-serif;
    --font-family-code: 'Fira Code', monospace;
    
    --font-size-xs: 0.75rem;
    --font-size-sm: 0.875rem;
    --font-size-base: 1rem;
    --font-size-lg: 1.125rem;
    --font-size-xl: 1.25rem;
    
    --spacing-xs: 0.25rem;
    --spacing-sm: 0.5rem;
    --spacing-md: 1rem;
    --spacing-lg: 1.5rem;
    --spacing-xl: 2rem;
    
    --radius-sm: 0.25rem;
    --radius-md: 0.5rem;
    --radius-lg: 1rem;
    --radius-full: 9999px;
    
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
    --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
    --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
    
    --transition-fast: 150ms ease;
    --transition-normal: 300ms ease;
    --transition-slow: 500ms ease;
    
    --z-dropdown: 1000;
    --z-modal: 1050;
    --z-tooltip: 1070;
  }
`;

4.2 暗色模式变量 #

jsx
const ThemeVariables = createGlobalStyle`
  :root {
    color-scheme: light;
    
    --color-background: #ffffff;
    --color-surface: #f9fafb;
    --color-text: #111827;
    --color-text-secondary: #6b7280;
    --color-border: #e5e7eb;
  }

  [data-theme="dark"] {
    color-scheme: dark;
    
    --color-background: #111827;
    --color-surface: #1f2937;
    --color-text: #f9fafb;
    --color-text-secondary: #9ca3af;
    --color-border: #374151;
  }

  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
      color-scheme: dark;
      
      --color-background: #111827;
      --color-surface: #1f2937;
      --color-text: #f9fafb;
      --color-text-secondary: #9ca3af;
      --color-border: #374151;
    }
  }
`;

4.3 使用 CSS 变量 #

jsx
const Button = styled.button`
  padding: var(--spacing-sm) var(--spacing-md);
  background: var(--color-primary);
  color: white;
  border-radius: var(--radius-md);
  font-size: var(--font-size-base);
  transition: all var(--transition-fast);
  
  &:hover {
    opacity: 0.9;
  }
`;

const Card = styled.div`
  padding: var(--spacing-lg);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
`;

五、主题集成 #

5.1 访问主题 #

jsx
import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`
  body {
    background: ${props => props.theme.colors.background};
    color: ${props => props.theme.colors.text};
    font-family: ${props => props.theme.fonts.main};
  }

  h1, h2, h3, h4, h5, h6 {
    font-family: ${props => props.theme.fonts.heading};
  }

  a {
    color: ${props => props.theme.colors.primary};
    
    &:hover {
      color: ${props => props.theme.colors.primaryDark};
    }
  }
`;

function App() {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <YourApp />
    </ThemeProvider>
  );
}

5.2 动态全局样式 #

jsx
const GlobalStyle = createGlobalStyle`
  body {
    background: ${props => props.$isDark ? '#111827' : '#ffffff'};
    color: ${props => props.$isDark ? '#f9fafb' : '#111827'};
    transition: background 0.3s, color 0.3s;
  }
  
  ${props => props.$isDark && `
    ::selection {
      background: rgba(102, 126, 234, 0.3);
    }
  `}
`;

function App() {
  const [isDark, setIsDark] = useState(false);
  
  return (
    <>
      <GlobalStyle $isDark={isDark} />
      <button onClick={() => setIsDark(!isDark)}>
        Toggle Theme
      </button>
    </>
  );
}

六、滚动条样式 #

6.1 自定义滚动条 #

jsx
const ScrollbarStyles = createGlobalStyle`
  ::-webkit-scrollbar {
    width: 8px;
    height: 8px;
  }

  ::-webkit-scrollbar-track {
    background: transparent;
  }

  ::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 4px;
    
    &:hover {
      background: #a1a1a1;
    }
  }

  ::-webkit-scrollbar-corner {
    background: transparent;
  }

  * {
    scrollbar-width: thin;
    scrollbar-color: #c1c1c1 transparent;
  }
`;

6.2 暗色模式滚动条 #

jsx
const DarkScrollbar = createGlobalStyle`
  ${props => props.$isDark && `
    ::-webkit-scrollbar-thumb {
      background: #4b5563;
      
      &:hover {
        background: #6b7280;
      }
    }

    * {
      scrollbar-color: #4b5563 transparent;
    }
  `}
`;

七、选择样式 #

7.1 文本选择 #

jsx
const SelectionStyles = createGlobalStyle`
  ::selection {
    background: rgba(102, 126, 234, 0.2);
    color: inherit;
  }

  ::-moz-selection {
    background: rgba(102, 126, 234, 0.2);
    color: inherit;
  }
`;

7.2 焦点样式 #

jsx
const FocusStyles = createGlobalStyle`
  :focus {
    outline: none;
  }

  :focus-visible {
    outline: 2px solid #667eea;
    outline-offset: 2px;
  }

  button:focus-visible,
  a:focus-visible,
  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible {
    outline: 2px solid #667eea;
    outline-offset: 2px;
  }
`;

八、打印样式 #

8.1 打印优化 #

jsx
const PrintStyles = createGlobalStyle`
  @media print {
    *,
    *::before,
    *::after {
      background: transparent !important;
      color: black !important;
      box-shadow: none !important;
      text-shadow: none !important;
    }

    a,
    a:visited {
      text-decoration: underline;
    }

    a[href]::after {
      content: " (" attr(href) ")";
    }

    abbr[title]::after {
      content: " (" attr(title) ")";
    }

    a[href^="#"]::after,
    a[href^="javascript:"]::after {
      content: "";
    }

    pre,
    blockquote {
      border: 1px solid #999;
      page-break-inside: avoid;
    }

    thead {
      display: table-header-group;
    }

    tr,
    img {
      page-break-inside: avoid;
    }

    p,
    h2,
    h3 {
      orphans: 3;
      widows: 3;
    }

    h2,
    h3 {
      page-break-after: avoid;
    }
  }
`;

九、组合全局样式 #

9.1 模块化组合 #

jsx
const Reset = createGlobalStyle`...`;
const Typography = createGlobalStyle`...`;
const Variables = createGlobalStyle`...`;

function App() {
  return (
    <>
      <Variables />
      <Reset />
      <Typography />
      <YourApp />
    </>
  );
}

9.2 单一入口 #

jsx
const GlobalStyles = createGlobalStyle`
  ${resetStyles}
  ${typographyStyles}
  ${variableStyles}
  ${scrollbarStyles}
  ${selectionStyles}
`;

const resetStyles = css`
  * {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
  }
`;

const typographyStyles = css`
  body {
    font-family: 'Inter', sans-serif;
    line-height: 1.5;
  }
`;

const variableStyles = css`
  :root {
    --color-primary: #667eea;
  }
`;

function App() {
  return (
    <>
      <GlobalStyles />
      <YourApp />
    </>
  );
}

十、总结 #

全局样式要点速查表:

功能 API
创建全局样式 createGlobalStyle\…``
访问主题 ${props => props.theme.xxx}
CSS 变量 :root { --var: value; }
字体导入 @font-face { ... }
CSS 重置 重置默认样式
打印样式 @media print { ... }

下一步:学习 CSS助手函数 掌握样式复用技巧。

最后更新:2026-03-28