Перейти к содержимому

Стили и CSS

Astro был разработан, чтобы сделать стилизацию и написание CSS простым делом. Пишите свой собственный CSS напрямую внутри Astro-компонента или импортируйте вашу любимую CSS-библиотеку, например Tailwind. Продвинутые языки стилизации, такие как Sass и Less, также поддерживаются.

Стилизация компонента в Astro так же проста, как добавление тега <style> в ваш шаблон компонента или страницы. Когда вы размещаете тег <style> внутри Astro-компонента, Astro автоматически обнаружит CSS и обработает ваши стили.

src/components/MyComponent.astro
<style>
h1 { color: red; }
</style>

Правила CSS в теге <style> Astro по умолчанию автоматически обладают ограниченной областью видимости. Подобные стили компилируются таким образом, что применяются только к HTML-коду внутри этого же компонента. CSS, написанный внутри Astro-компонента, автоматически инкапсулируется в рамках этого компонента.

Вот этот CSS:

src/pages/index.astro
<style>
h1 {
color: red;
}
.text {
color: blue;
}
</style>

Компилируется в этот:

<style>
h1[data-astro-cid-hhnqfkh6] {
color: red;
}
.text[data-astro-cid-hhnqfkh6] {
color: blue;
}
</style>

Локальные стили не распространяются за пределы компонента и не влияют на остальные части вашего сайта. В Astro можно безопасно использовать селекторы с низкой специфичностью, такие как h1 {} или p {}, поскольку в финальной сборке они будут автоматически преобразованы с учётом ограниченной области видимости.

Локальные стили также не применяются к другим Astro-компонентам внутри вашего шаблона. Если вам нужно стилизовать дочерний компонент, рекомендуется обернуть его в <div> (или другой элемент), который затем можно стилизовать.

Специфичность локальных стилей сохраняется, что позволяет им корректно работать вместе с другими CSS-файлами или CSS-библиотеками, при этом сохраняя чёткие границы, предотвращающие применение стилей за пределами компонента.

Хотя мы рекомендуем использовать локальные стили для большинства компонентов, иногда могут возникнуть ситуации, когда требуется написать глобальный CSS. Можно отключить автоматическую ограниченную область видимости с помощью атрибута <style is:global>.

src/components/GlobalStyles.astro
<style is:global>
/* Без ограниченной области видимости, стили доставляются в браузер как есть.
Применяется ко всем тегам `<h1>` на вашем сайте. */
h1 { color: red; }
</style>

Вы также можете сочетать глобальные и локальные правила CSS в одном теге <style>, используя селектор :global(). Это становится мощным инструментом для применения стилей к дочерним элементам вашего компонента.

src/components/MixedStyles.astro
<style>
/* Стили только для этого компонента. */
h1 { color: red; }
/* Смешанный режим: применяется только к дочерним элементам `h1`. */
article :global(h1) {
color: blue;
}
</style>
<h1>Заголовок</h1>
<article><slot /></article>

Это отличный способ стилизации таких элементов, как посты блога или документы с контентом из CMS, где содержимое находится вне Astro. Однако будьте осторожны: компоненты, внешний вид которых меняется в зависимости от наличия определённого родительского компонента, могут вызвать сложности при отладке.

Локальные стили следует использовать как можно чаще. Глобальные стили стоит применять только при необходимости.

Если вам нужно динамически комбинировать классы на элементе, используйте служебный атрибут class:list в .astro файлах.

src/components/ClassList.astro
---
const { isRed } = Astro.props;
---
<!-- Если `isRed` истинно, класс будет "box red". -->
<!-- Если `isRed` ложно, класс будет "box". -->
<div class:list={['box', { red: isRed }]}><slot /></div>
<style>
.box { border: 1px solid blue; }
.red { border-color: red; }
</style>
Подробнее о class:list читайте в справочнике директив (EN).

Добавлено в: astro@0.21.0

Тег <style> в Astro может использовать любые CSS-переменные, доступные на странице. Вы также можете передавать CSS-переменные напрямую из метаданных компонента с помощью директивы define:vars.

src/components/DefineVars.astro
---
const foregroundColor = "rgb(221 243 228)";
const backgroundColor = "rgb(24 121 78)";
---
<style define:vars={{ foregroundColor, backgroundColor }}>
h1 {
background-color: var(--backgroundColor);
color: var(--foregroundColor);
}
</style>
<h1>Hello</h1>
Подробнее о define:vars читайте в справочнике директив (EN).

В Astro HTML-атрибуты, такие как class, не передаются дочерним компонентам автоматически.

Вместо этого необходимо:

  1. Принять проп class в дочернем компоненте
  2. Применить его к корневому элементу
  3. При деструктуризации переименовать его, так как classзарезервированное слово в JavaScript.

При использовании стратегии локальных стилей по умолчанию необходимо также передавать атрибут data-astro-cid-*. Это можно сделать, передав остальные пропсы (...rest) в компонент. Если вы изменили scopedStyleStrategy на 'class' или 'where', передача ...rest не требуется.

src/components/MyComponent.astro
---
const { class: className, ...rest } = Astro.props;
---
<div class={className} {...rest}>
<slot/>
</div>
src/pages/index.astro
---
import MyComponent from "../components/MyComponent.astro"
---
<style>
.red {
color: red;
}
</style>
<MyComponent class="red">Этот текст будет красным!</MyComponent>

Вы можете задавать стили HTML-элементам напрямую через атрибут style, используя CSS-строку или объект со свойствами CSS:

src/pages/index.astro
// Эти примеры эквивалентны:
<p style={{ color: "brown", textDecoration: "underline" }}>Мой текст</p>
<p style="color: brown; text-decoration: underline;">Мой текст</p>

Подключение глобальных внешних стилей возможно двумя способами:

  • Импорт через ESM для файлов в исходном коде проекта
  • Абсолютная ссылка для файлов в директории public/ или внешних ресурсов
Подробнее об использовании статических ресурсов (EN), размещённых в директориях public/ или src/.

Вы можете импортировать таблицы стилей в метаданных Astro-компонента, используя синтаксис ESM-импорта. Импорт CSS работает аналогично другим ESM-импортам в Astro-компоненте и должен:

  • Указываться относительно компонента
  • Располагаться в верхней части скрипта компонента
  • Быть объявлен вместе с другими импортами
src/pages/index.astro
---
// Astro автоматически соберет и оптимизирует этот CSS за вас
// Это работает и с файлами препроцессоров: .scss, .styl и др.
import '../styles/utils.css';
---
<html><!-- Здесь ваша страница --></html>

Импорт CSS через ESM поддерживается в любом JavaScript-файле, включая JSX-компоненты (React, Preact и др.). Это особенно полезно для создания детализированных стилей отдельных компонентов React.

Возможно, вам потребуется загрузить стили из внешнего npm-пакета. Это особенно актуально для таких утилит, как Open Props. Если пакет рекомендует указывать расширение файла (например, package-name/styles.css вместо package-name/styles), импорт будет работать так же, как с локальными стилями:

src/pages/random-page.astro
---
import 'package-name/styles.css';
---
<html><!-- Здесь ваша страница --></html>

Если ваш пакет не рекомендует указывать расширение файла (например, package-name/styles), сначала потребуется обновить конфигурацию Astro!

Допустим, вы импортируете CSS-файл normalize из пакета package-name (без указания расширения файла). Чтобы гарантировать корректный пререндеринг страницы, добавьте package-name в массив vite.ssr.noExternal:

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
ssr: {
noExternal: ['package-name'],
}
}
})

Теперь вы можете свободно импортировать package-name/normalize. Astro обработает и оптимизирует этот файл, как и любую другую локальную таблицу стилей.

src/pages/random-page.astro
---
import 'package-name/normalize';
---
<html><!-- Здесь ваша страница --></html>
Заголовок раздела Подключение статической таблицы стилей через тег &lt;link&gt;

Для загрузки CSS-файлов также можно использовать элемент <link>. Укажите в нём:

  • Абсолютный путь к файлу в директории /public
  • Или URL внешнего ресурса
src/pages/index.astro
<head>
<!-- Локальная таблица стилей: /public/styles/global.css -->
<link rel="stylesheet" href="/styles/global.css" />
<!-- Внешняя таблица стилей -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css" />
</head>

Поскольку этот метод использует директорию public/, он пропускает стандартную обработку CSS, сборку и оптимизацию, которые предоставляет Astro. Если вам нужны эти преобразования, используйте метод импорта стилей, описанный выше.

Компоненты Astro иногда должны учитывать несколько источников CSS. Например, ваш компонент может:

  • Импортировать внешнюю таблицу стилей
  • Содержать собственный тег <style>
  • И рендериться внутри макета, который тоже импортирует CSS

Когда конфликтующие CSS-правила применяются к одному элементу, браузеры сначала используют специфичность, а затем порядок появления для определения конечного стиля.

Если одно правило более специфично чем другое, его значение будет иметь приоритет — независимо от порядка расположения:

src/components/MyComponent.astro
<style>
h1 { color: red }
div > h1 {
color: purple
}
</style>
<div>
<h1>
Этот заголовок будет фиолетовым!
</h1>
</div>

Если два правила имеют одинаковую специфичность, приоритет определяется по порядку появления — будет применено значение последнего правила:

src/components/MyComponent.astro
<style>
h1 { color: purple }
h1 { color: red }
</style>
<div>
<h1>
Этот заголовок будет красным!
</h1>
</div>

Правила CSS в Astro применяются в следующем порядке:

  1. Теги <link> в <head> (наименьший приоритет)
  2. Импортированные стили
  3. Локальные стили (наибольший приоритет)

В зависимости от значения scopedStyleStrategy (EN), локальные стили могут увеличивать специфичность класса, но не всегда.

Однако локальные стили всегда имеют самый поздний порядок появления. Поэтому они будут иметь приоритет над другими стилями с такой же специфичностью. Например, если импортированный стиль конфликтует с локальным стилем, будет применено значение локального стиля:

src/components/make-it-purple.css
h1 {
color: purple;
}
src/components/MyComponent.astro
---
import "./make-it-purple.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Этот заголовок будет красным!
</h1>
</div>

Локальные стили будут перезаписаны, если импортированный стиль имеет более высокую специфичность. В этом случае приоритет отдаётся стилю с наибольшей специфичностью:

src/components/make-it-purple.css
#intro {
color: purple;
}
src/components/MyComponent.astro
---
import "./make-it-purple.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1 id="intro">
Этот заголовок будет фиолетовым!
</h1>
</div>

При импорте нескольких таблиц стилей в компоненте Astro CSS-правила обрабатываются в порядке их импорта. Более высокая специфичность всегда определяет, какие стили отображать, независимо от времени обработки CSS. Но если конфликтующие стили имеют одинаковую специфичность, побеждает последний импортированный:

src/components/make-it-purple.css
div > h1 {
color: purple;
}
src/components/make-it-green.css
div > h1 {
color: green;
}
src/components/MyComponent.astro
---
import "./make-it-green.css"
import "./make-it-purple.css"
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Этот заголовок будет фиолетовым!
</h1>
</div>

Хотя теги <style> имеют ограниченную область видимости и применяются только к компоненту, который их объявляет, импортированный CSS может «просачиваться». Импорт компонента применяет любой CSS, который он импортирует, даже если компонент никогда не используется:

src/components/PurpleComponent.astro
---
import "./make-it-purple.css"
---
<div>
<h1>Импортирую фиолетовый CSS.</h1>
</div>
src/components/MyComponent.astro
---
import "./make-it-green.css"
import PurpleComponent from "./PurpleComponent.astro";
---
<style>
h1 { color: red }
</style>
<div>
<h1>
Этот заголовок будет фиолетовым!
</h1>
</div>

Таблицы стилей, загруженные через теги <link>, обрабатываются в порядке их подключения, перед любыми другими стилями в Astro-файле. Следовательно, эти стили будут иметь более низкий приоритет, чем импортированные таблицы стилей и локальные стили:

src/pages/index.astro
---
import "../components/make-it-purple.css"
---
<html lang="ru">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
<link rel="stylesheet" href="/styles/make-it-blue.css" />
</head>
<body>
<div>
<h1>Этот заголовок будет фиолетовым!</h1>
</div>
</body>
</html>

Astro поддерживает популярные CSS-библиотеки, инструменты и фреймворки, включая Tailwind и другие!

Astro работает с Tailwind 3 и 4. Вы можете:

Для апгрейда с Tailwind 3 до 4 потребуется:

  1. Добавить поддержку Tailwind 4
  2. Удалить поддержку Tailwind 3

В Astro >=5.2.0 используйте команду astro add tailwind для вашего менеджера пакетов, чтобы установить официальный плагин Tailwind для Vite. Для более ранних версий Astro следуйте инструкциям в документации Tailwind, чтобы вручную добавить плагин @tailwindcss/vite.

Окно терминала
npx astro add tailwind

Затем импортируйте tailwindcss в src/styles/global.css (или любой другой выбранный вами CSS-файл), чтобы сделать классы Tailwind доступными для вашего Astro-проекта. Этот файл с импортом будет создан автоматически, если вы использовали команду astro add tailwind для установки Vite-плагина.

src/styles/global.css
@import "tailwindcss";

Импортируйте этот файл на страницах, где должен применяться Tailwind. Обычно это делается в компоненте макета, чтобы стили Tailwind были доступны на всех страницах, использующих этот макет:

src/layouts/Layout.astro
---
import "../styles/global.css";
---

Выполните следующие шаги для обновления существующего проекта Astro с Tailwind v3 (использующего интеграцию @astrojs/tailwind) до Tailwind 4 (с плагином @tailwindcss/vite).

  1. Добавьте поддержку Tailwind 4 через CLI для последней версии Astro или вручную установите Vite-плагин.

  2. Удалите интеграцию @astrojs/tailwind из вашего проекта:

    Окно терминала
    npm uninstall @astrojs/tailwind
  3. Удалите интеграцию @astrojs/tailwind из файла astro.config.mjs:

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import tailwind from '@astrojs/tailwind';
    export default defineConfig({
    // ...
    integrations: [tailwind()],
    // ...
    });
  4. Затем обновите проект в соответствии с руководством по обновлению до Tailwind v4.

Для добавления (или сохранения) поддержки Tailwind 3 вам потребуется установить как tailwindcss@3, так и официальную интеграцию Astro @astrojs/tailwind. Ручная установка этих зависимостей требуется только для совместимости с устаревшей версией Tailwind 3 и не нужна для Tailwind 4. Также вам понадобится устаревшая конфигурация Tailwind:

  1. Установите Tailwind и интеграцию Astro Tailwind в зависимости вашего проекта с помощью предпочитаемого менеджера пакетов:

    Окно терминала
    npm install tailwindcss@3 @astrojs/tailwind
  2. Импортируйте интеграцию в ваш файл astro.config.mjs и добавьте её в массив integrations[]:

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import tailwind from '@astrojs/tailwind';
    export default defineConfig({
    // ...
    integrations: [tailwind()],
    // ...
    });
  3. Создайте файл tailwind.config.mjs в корневой директории вашего проекта. Вы можете использовать следующую команду для генерации базового конфигурационного файла:

    Окно терминала
    npx tailwindcss init
  4. Добавьте следующую базовую конфигурацию в ваш файл tailwind.config.mjs:

    tailwind.config.mjs
    /** @type {import('tailwindcss').Config} */
    export default {
    content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
    theme: {
    extend: {},
    },
    plugins: [],
    };
Связанная инструкция: Style rendered Markdown with Tailwind Typography (EN)

Astro поддерживает CSS-препроцессоры, такие как Sass, Stylus и Less, через Vite.

Окно терминала
npm install sass

Используйте <style lang="scss"> или <style lang="sass"> в файлах .astro.

Окно терминала
npm install stylus

Используйте <style lang="styl"> или <style lang="stylus"> в файлах .astro.

Окно терминала
npm install less

Используйте <style lang="less"> в файлах .astro.

Окно терминала
npm install lightningcss

Обновите вашу конфигурацию vite в astro.config.mjs:

astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
vite: {
css: {
transformer: "lightningcss",
},
},
})

Вы также можете использовать все перечисленные CSS-препроцессоры в компонентах JS-фреймворков! Следуйте рекомендациям соответствующего фреймворка:

  • React / Preact: import Styles from './styles.module.scss';
  • Vue: <style lang="scss">
  • Svelte: <style lang="scss">

Astro включает PostCSS как часть Vite. Для настройки PostCSS создайте файл postcss.config.cjs в корне проекта. Плагины можно импортировать через require() после их установки (например npm install autoprefixer).

postcss.config.cjs
module.exports = {
plugins: [
require('autoprefixer'),
require('cssnano'),
],
};

Файлы .jsx поддерживают как глобальный CSS, так и CSS-модули. Для использования CSS-модулей применяйте расширение .module.css (или .module.scss/.module.sass при работе с Sass).

src/components/MyReactComponent.jsx
import './global.css'; // включаем глобальный CSS
import Styles from './styles.module.css'; // используем CSS-модули

Vue в Astro поддерживает те же методы, что и vue-loader:

Svelte в Astro также работает ожидаемым образом: Документация по стилям Svelte.

Любые методы стилизации Astro доступны для компонента макета Markdown, но разные методы будут по-разному влиять на стилизацию вашей страницы.

Вы можете применить глобальные стили к содержимому Markdown, добавив импортированные таблицы стилей в макет, который оборачивает содержимое страницы. Также возможно стилизовать Markdown с помощью тегов <style is:global> в компоненте макета. Обратите внимание, что любые добавленные стили подчиняются порядку наследования Astro, и вам следует внимательно проверить отрендеренную страницу, чтобы убедиться, что стили применяются должным образом.

Вы также можете добавить CSS-интеграции, включая Tailwind (EN). Если вы используете Tailwind, для стилизации Markdown вам может пригодиться плагин типографики.

При сборке сайта для продакшена Astro минифицирует и объединяет ваш CSS в чанки. Каждая страница сайта получает собственный чанк, а CSS, общий для нескольких страниц, выделяется в отдельные чанки для повторного использования.

Однако, когда несколько страниц используют общие стили, некоторые общие чанки могут быть очень маленькими. Если отправлять их все отдельно, это приведёт к множеству запросов таблиц стилей и повлияет на производительность сайта. Поэтому по умолчанию Astro добавляет в HTML только те чанки, размер которых превышает 4 КБ, в виде тегов <link rel="stylesheet">, в то время как меньшие чанки встраиваются как <style type="text/css">. Такой подход обеспечивает баланс между количеством дополнительных запросов и объёмом CSS, который можно кэшировать между страницами.

Вы можете настроить минимальный размер (в байтах) для внешнего подключения таблиц стилей с помощью опции сборки Vite assetsInlineLimit. Обратите внимание, что эта опция также влияет на встраивание скриптов и изображений.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
vite: {
build: {
assetsInlineLimit: 1024,
}
};
});

Если вы предпочитаете, чтобы все стили проекта оставались внешними, вы можете настроить опцию сборки inlineStylesheets.

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
build: {
inlineStylesheets: 'never'
}
});

Также можно установить значение 'always' для этой опции, что приведёт к встраиванию всех таблиц стилей.

Для сложных сценариев CSS можно загружать напрямую с диска без обработки и оптимизации Astro. Это может быть полезно, когда требуется полный контроль над определённым фрагментом CSS и необходимо обойти автоматическую обработку стилей в Astro.

Этот подход не рекомендуется большинству пользователей.

src/components/RawInlineStyles.astro
---
// Расширенный пример! Не рекомендуется для большинства пользователей!
import rawStylesCSS from '../styles/main.css?raw';
---
<style is:inline set:html={rawStylesCSS}></style>

Подробности см. в документации Vite.

Для сложных сценариев можно импортировать прямую ссылку на CSS-файл из директории src/ вашего проекта. Это может быть полезно, когда требуется полный контроль над загрузкой CSS-файла на странице. Однако это отключит оптимизацию данного CSS-файла вместе с остальными стилями страницы.

Этот подход не рекомендуется большинству пользователей. Вместо этого размещайте CSS-файлы в директории public/ для получения постоянной ссылки.

src/components/RawStylesUrl.astro
---
// Расширенный пример! Не рекомендуется для большинства пользователей!
import stylesUrl from '../styles/main.css?url';
---
<link rel="preload" href={stylesUrl} as="style">
<link rel="stylesheet" href={stylesUrl}>

Подробности см. в документации Vite.

Внести свой вклад Сообщество Sponsor