Styling & Themes

Nijor offers elegant support for styling. By default, styles defined inside a component are fully scoped, meaning they only apply to the HTML elements declared within that component.

In addition to scoped styles, Nijor includes native support for dark mode, multiple custom themes, reactive class binding, and PostCSS integration out of the box.

Component Theming

Modern applications frequently require multi-theme support (e.g., Light, Dark, or Dim modes). While standard CSS media queries are effective, they are bound to the operating system's settings.

Nijor solves this by providing the theme attribute on <style> (or <nstyle> in templates) blocks. An unthemed style block represents the base or default theme. Themed style blocks override specific properties when their target theme is activated.


        <body>
            <div>
                <h1>Theme Explorer</h1>
            </div>
        </body>

        <style>
            /* Base (Default/Light) Theme Styles */
            div {
                margin: 10px;
                padding: 16px;
                background-color: #ffffff;
                border: 1px solid #ddd;
            }

            h1 {
                color: #333333;
            }
        </style>

        <style theme="dark">
            /* Scoped Dark Theme Overrides */
            div {
                background-color: #121212;
                border-color: #333333;
            }

            h1 {
                color: #ffffff;
            }
        </style>

        <style theme="dim">
            /* Scoped Dim Theme Overrides */
            div {
                background-color: #2c3e50;
                border-color: #34495e;
            }

            h1 {
                color: #ecf0f1;
            }
        </style>
    

Managing Active Themes

The built-in nijor/theme module makes controlling active themes incredibly simple. It exports two main helper functions: autoTheme() and setTheme().


        import { autoTheme, setTheme } from "nijor/theme";
    

1. Automatic Theme Control

Call autoTheme() to automatically match the application theme to the user's system preference. If their OS is set to dark mode, Nijor applies the style rules defined under theme="dark"; otherwise, it falls back to the base styles.


        import { autoTheme } from "nijor/theme";

        // Call during application bootstrap (e.g., in App.js)
        autoTheme();
    

2. Manual Theme Toggling

Use setTheme() to programmatically switch themes. This overrides automatic detection and lets you toggle custom themes dynamically:


        import { setTheme } from "nijor/theme";

        setTheme("dark");   // Activate dark theme overrides
        setTheme("dim");    // Activate dim theme overrides
        setTheme("light");  // Force base theme (bypassing auto-detection)
    

To restore system-level automatic theme detection, simply pass "auto":


            setTheme("auto");
        

3. Theme Persistence

Nijor automatically stores the currently active theme in the browser's local storage. This ensures the user's preference persists across page loads. You can read the active selection using:


        const currentTheme = window.localStorage.getItem("theme");
    

Conditional Classes

Nijor provides a elegant syntax to apply CSS classes conditionally using the class:classname attribute. A class is added to the element if the expression inside curly braces evaluates to a truthy value; otherwise, it is omitted.

Static Conditional Example


        <body>
            <button class:active="{isActive}">Save Changes</button>
        </body>

        <script>
            const isActive = true;
        </script>

        <style>
            .active {
                color: #007bff;
                font-weight: bold;
            }
        </style>
    

Reactive Conditional Example

This syntax integrates with Nijor's reactive state variables, allowing you to add and remove classes dynamically in response to state transitions.


        <body>
            <button class:enabled="{$.enabled}" on:click="toggle()">Toggle Power</button>
        </body>

        <script>
            $.enabled = false;

            export function toggle($) {
                $.enabled = !$.enabled;
            }
        </script>

        <style>
            .enabled {
                background-color: #28a745;
                color: white;
            }
        </style>
    

CSS Processing: PostCSS & Tailwind CSS

Nijor features an integrated PostCSS architecture to process application stylesheets during the build step. You can extend this processing by registering plugins inside your project's postcss.config.mjs file.

By default, Nijor pre-configures and runs the following PostCSS plugins to keep your bundles optimized and modern:

postcss-nested: Write clean, nested style declarations.

autoprefixer: Automatically add CSS vendor prefixes for broad browser compatibility.

cssnano: Minify and compress compiled production CSS.

Tailwind CSS Integration: Because Nijor compiles using standard PostCSS, integrating Tailwind CSS is extremely straightforward. Simply install Tailwind via Bun/NPM, add it as a plugin in your postcss.config.mjs, and define your content paths to scan *.nijor files.