# CSS Support

Crane uses **Vite** and **Vue** for builds. CSS is processed by Vite’s pipeline and Vue SFCs. No Crane-specific CSS config; support follows Vite’s defaults and app dependencies.

### Pipeline <a href="#pipeline" id="pipeline"></a>

| Mechanism    | Behavior                                                                                   |
| ------------ | ------------------------------------------------------------------------------------------ |
| **Vue SFCs** | `<style>` in `.vue` files; optional `lang="scss"`, `lang="less"`, or plain CSS             |
| **Imports**  | `.css`, `.scss`, `.sass`, `.less`, `.module.css` imported from JS/TS are processed by Vite |
| **PostCSS**  | If `postcss.config.js` or `postcss.config.cjs` exists in app root, Vite runs it on CSS     |

{% hint style="info" %}
`crane build` does **not** load your app’s `vite.config.js`. All options below rely on Vite’s default behavior and the dependencies you install.
{% endhint %}

Section CSS shares the page with Ecwid’s storefront. To avoid CSS variable clashes, prefix your custom properties — see [#css-variable-conflict-prevention](#css-variable-conflict-prevention "mention").

### Reference <a href="#reference" id="reference"></a>

#### Plain CSS <a href="#plain-css" id="plain-css"></a>

* **Install:** none
* **Files:** `.css`; `<style>` or `<style scoped>` in SFCs
* **Usage:** Import or inline in SFC

```vue
<style scoped>
.card { padding: 1rem; }
</style>
```

```scheme
import './styles.css';
```

#### Sass / SCSS <a href="#sass-scss" id="sass-scss"></a>

* **Install:** `npm install -D sass`
* **Files:** `.scss`, `.sass`; SFC `lang="scss"` or `lang="sass"`
* **Usage:** Import or `<style lang="scss" scoped>`

```vue
<style lang="scss" scoped>
$primary: #3498db;
.card { background: $primary; }
</style>
```

```vue
import './section.scss';
```

Crane uses the modern Sass compiler for internal builds where applicable.

#### Less <a href="#less" id="less"></a>

* **Install:** `npm install -D less`
* **Files:** `.less`; SFC `lang="less"`
* **Usage:** Import or `<style lang="less" scoped>`

```less
<style lang="less" scoped>
@primary: #3498db;
.card { background: @primary; }
</style>
```

```vue
import './section.less';
```

#### PostCSS <a href="#postcss" id="postcss"></a>

* **Install:** Any PostCSS plugins you use (e.g. `autoprefixer`); config in app root
* **Config:** `postcss.config.js` or `postcss.config.cjs` next to `package.json`
* **Usage:** All CSS is run through PostCSS when config exists

```javascript
// postcss.config.js
export default {
  plugins: {
    autoprefixer: {},
  },
};
```

#### CSS Modules <a href="#css-modules" id="css-modules"></a>

* **Install:** none
* **Files:** `*.module.css` (naming convention)
* **Usage:** Import default; use returned object for class names (scoped by Vite)

```css
/* styles.module.css */
.card { padding: 1rem; }
.badge { font-weight: bold; }
```

```typescript
<script setup lang="ts">
import styles from './styles.module.css';
</script>
<template>
  <div :class="styles.card"><span :class="styles.badge">New</span></div>
</template>
```

#### Tailwind CSS <a href="#tailwind-css" id="tailwind-css"></a>

**Tailwind v3 (works with `crane build`):** Use PostCSS. Add `postcss.config.js` in app root and Tailwind directives in your CSS.

* **Install:** `npm install -D tailwindcss postcss autoprefixer` then `npx tailwindcss init -p`
* **Config:** `postcss.config.js` with `tailwindcss` and `autoprefixer`
* **Usage:** In CSS: `@tailwind base;` `@tailwind components;` `@tailwind utilities;` — import that CSS from section client or Vue entry

**Tailwind v4 (Vite plugin):** Requires the `@tailwindcss/vite` plugin in Vite config. `crane build` does not load `vite.config.js`, so for Tailwind processing during `crane build` use the v3 + PostCSS approach above.

#### Bootstrap <a href="#bootstrap" id="bootstrap"></a>

* **Install:** `npm install bootstrap`; for SCSS also `npm install -D sass`
* **Usage:** Import built CSS or Bootstrap SCSS

```vue
import 'bootstrap/dist/css/bootstrap.min.css';
```

```vue
@import 'bootstrap/scss/bootstrap';
```

#### Lightning CSS <a href="#lightning-css" id="lightning-css"></a>

* **Install:** Use as a PostCSS plugin; add to `postcss.config.js`
* **Usage:** Vite runs PostCSS; Lightning CSS runs as part of that pipeline

### Summary table <a href="#summary-table" id="summary-table"></a>

| Approach      | Install                         | Usage / file pattern                            |
| ------------- | ------------------------------- | ----------------------------------------------- |
| Plain CSS     | —                               | `.css`, `<style>` in SFCs                       |
| Sass/SCSS     | `sass`                          | `.scss`/`.sass`, `lang="scss"`                  |
| Less          | `less`                          | `.less`, `lang="less"`                          |
| PostCSS       | plugins + `postcss.config.js`   | All CSS (Vite runs PostCSS when config present) |
| CSS Modules   | —                               | `*.module.css` + default import                 |
| Tailwind v3   | `tailwindcss`, PostCSS          | `postcss.config.js` + `@tailwind` in CSS        |
| Tailwind v4   | `@tailwindcss/vite`             | Vite config only (not applied in `crane build`) |
| Bootstrap     | `bootstrap` (+ `sass` for SCSS) | Import CSS or SCSS                              |
| Lightning CSS | PostCSS plugin                  | Via `postcss.config.js`                         |

### CSS variable conflict prevention <a href="#css-variable-conflict-prevention" id="css-variable-conflict-prevention"></a>

Section CSS is loaded alongside Ecwid’s storefront styles. Custom properties (CSS variables) cascade globally; if you use the same names as Ecwid, load order is not guaranteed and styles can break.

**Rule:** Prefix all your CSS variables with a unique namespace (e.g. agency or project name).

| Do                          | Don’t          |
| --------------------------- | -------------- |
| `--acme-primary`            | `--primary`    |
| `--myapp-spacing`           | `--spacing`    |
| `--acme-section-background` | `--background` |

**Names Ecwid uses (do not define these yourself):**

* **`--global-*`** — theme/site tokens (e.g. `--global-title-font-family-stack`, `--global-body-font-size`, `--global-tile-max-width`, `--global-background-color`, `--global-button-color`, `--global-link-color`).
* **`--ls-*`** — editor UI (e.g. `--ls-color-fg-go-default`, `--ls-color-bg-neutral-top`, `--ls-color-border-neutral-strong`).
* **Unprefixed names** — layout and colors, e.g. `--vh`, `--max-width-regular`, `--max-width-wide`, `--bg-static-light-color`, `--fg-static-dark-color`, `--white-color`, `--button-color`, `--link-color`, `--header-height`, `--cover-height`, `--grid-gap`, `--grid-padding`, `--grid-max-width`.

Prefix your own variables (e.g. `--acme-*`) and avoid defining any of the names above.

**Example — safe:**

```
:root {
  --acme-primary: #ff0000;
  --acme-spacing: 1rem;
  --acme-background: white;
}
.my-section { background: var(--acme-background); }
```

**Example — avoid:**

```
:root {
  --primary: #ff0000;      /* can conflict with Ecwid */
  --spacing: 1rem;
  --background: white;
}
```

Recommendation: use a short, consistent prefix in every variable (e.g. `--acme-*` or `--projectname-*`).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.ecwid.com/site-themes/develop-site-themes/css-support.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
