Frontend styling¶
Choose the right styling layer¶
Easy8 has more than one styling layer. Identify which layer the screen already uses before you add styles.
- Design System components (see Design system) are styled through their props. Do not restyle them from your plugin.
- Existing legacy screens, ERB views, and
easy_uiintegrations use the legacy Easy styles underapp/frontend/src/shared/stylesheets/easy/. - Vuetify overrides live under
app/frontend/src/shared/stylesheets/vuetify/. - Tailwind utility classes are available globally, but only those used in
app/frontend/src. Classes that appear only in your plugin are not compiled. See Tailwind utilities.
Extend the layer the screen already uses; do not move a screen to another styling system just because you touch it.
Main locations¶
app/frontend/src/<module>/stylesheets/: styles owned by a frontend module.app/frontend/src/shared/stylesheets/easy/_base.scss: main legacy Easy stylesheet entrypoint.app/frontend/src/shared/stylesheets/easy/_common-assets.scss: shared legacy exports for variables, abstracts and themes.app/frontend/src/shared/stylesheets/easy/variables/: legacy Easy variables.app/frontend/src/shared/stylesheets/easy/themes/: themes and brand values.app/frontend/src/shared/stylesheets/vuetify/: Vuetify overrides.app/frontend/src/shared/stylesheets/tailwind/index.css: Tailwind theme and source scanning.
General rules¶
- Keep styles in the same layer as the feature you are editing.
- Keep selectors as flat as possible. Prefer classes over long descendant chains.
- Avoid
!importantunless you are fixing a real override problem that cannot be solved cleanly. - Reuse existing variables, mixins, and placeholders before introducing new values or abstractions.
- Keep feature-specific rules close to the owning component, page, or pattern.
- Do not add or extend custom styles in Vue
<style>blocks, including<style scoped>. Put new declarations in the owning module's external SCSS files. Shared components follow the external stylesheet structure of their owning shared layer. - Follow naming already used in the edited area instead of forcing a new naming convention into old code.
Tailwind utilities¶
Tailwind v4 is compiled through PostCSS and loaded on every page: the base layout includes vite_stylesheet_tag 'tailwind.css', so utilities are available without importing anything.
The theme lives in app/frontend/src/shared/stylesheets/tailwind/index.css. It disables Tailwind's own source detection (source(none)) and scans app/frontend/src explicitly, so a class only survives the build if it appears literally in that tree. A class used only in your modification plugin is stripped; style the plugin with its own stylesheet or with a class that the core already uses. Do not build class names dynamically (`gap-ms${size}`), because they will be stripped.
What the utilities resolve to¶
The Tailwind theme maps to the legacy Easy variables (--easy__*), not to the Design System tokens.
--spacing-ms1: var(--easy__spacing--ms-1); /* gap-ms1, p-ms1, m-ms1 ... */
--color-front: var(--easy__color--front); /* bg-front, text-front ... */
--color-font-muted: var(--easy__color--text-muted);
There is no --Scale-Size-* or --Content-* utility, so a Design System component styled with utilities mixes two token families.
Choosing¶
Use a Design System component and its props where one fits. For the layout left over:
| Use | When |
|---|---|
| Tailwind utilities | The surrounding module already uses them, the component sits on legacy or easy_ui foundations, or you need a handful of one-off layout declarations. |
| Module-owned SCSS | Custom CSS is clearer than utilities, for example for component states, media or container queries, or substantial layout such as a scrollable feed. Put the rules in app/frontend/src/<module>/stylesheets/, namespace them under the module root class or another unique module-owned class for teleported content, and use the token family established by the module. |
Load module styles through the module's existing Vite asset path. For a new microapp, import its SCSS aggregate from the module's JavaScript or TypeScript entrypoint, normally under app/frontend/entrypoints/. For an existing module, extend its current loader and styles/ or stylesheets/ structure, including source main or index imports and standalone stylesheet entrypoints loaded with vite_stylesheet_tag.
SCSS reuse¶
The codebase uses modern Sass module syntax with @use and @forward.
- Use
@mixinwhen the style needs configuration or reusable generated output. - Use placeholders with
@extend %placeholderfor fixed shared declaration groups. - Prefer extending placeholders, not concrete HTML selectors or unrelated component classes.
- When working in legacy Easy styles, look for reusable assets in
utils/abstracts/and shared exports from_common-assets.scss. - Many legacy pattern files expose
@mixin styles; wire them through the owning entrypoint instead of scattering duplicate imports.
Themes and branding¶
To change colours, fonts or logos, see Theme and custom branding.