Napište své CSS pomocí JavaScriptu

Někdy stačí k programování použít správný nástroj. Může to být framework, knihovna nebo jak se to stává v mém případě CSS preprocesor. Pravděpodobně si to neuvědomujete, ale LESS nebo SASS mají spoustu omezení. To se mi podařilo změnit napsáním vlastního CSS preprocesoru. Přestal jsem psát CSS a vše přesunul do světa JavaScriptu. Tento článek je o AbsurdJS:malém modulu Node.js, který úplně změnil můj pracovní postup.

Koncept

Pokud píšete hodně CSS, pravděpodobně používáte preprocesor. Populární jsou dva – LESS a SASS. Oba nástroje přijímají něco, co vypadá jako CSS, dělají nějaké kouzlo a exportují normální, čisté CSS. Udělal jsem jen výměnu nástroje a vstupního formátu. Nechtěl jsem vymýšlet nový jazyk nebo syntaxi, protože to souvisí se spoustou věcí, jako je analýza a kompilace. Naštěstí je tu Node.js a rozhodl jsem se ho použít. Také jsem měl spoustu projektů typu LESS, což znamená, že už používám Node.js ke kompilaci svých stylů. Bylo mnohem jednodušší vyměnit modul místo přidání něčeho úplně nového.

\

Vstup

Myslím, že nejblíže formátu CSS je JSON - to je to, co AbsurdJS přijímá. Tato transformace má samozřejmě své nevýhody. Některé vlastnosti musíte dát do uvozovek a samozřejmě hodnoty. To vyžaduje trochu více času během psaní, ale jak uvidíte níže, stojí to za to.

Na začátku byl ... soubor JavaScript

Takto vypadá jednoduchý soubor LESS:

.main-nav {
    background: #333;
    color: #000;
    font-weight: bold;
    p {
        font-size: 20px;
    }
}

A zde je jeho ekvivalent AbsurdJS. Je to jednoduchý modul Node.js:

module.exports = function(api) {
    api.add({
        ".main-nav": {
            background: "#333",
            color: "#000",
            "font-weight": "bold",
            p: {
                "font-size": "20px"
            }
        }
    })
}

Funkci module.exports byste měli přiřadit . Přijímá odkaz na API, které má několik metod, ale nejdůležitější je add . Jednoduše předejte objekt JSON a bude převeden na CSS.

Ke kompilaci souboru less potřebujeme nainstalovat kompilátor LESS přes npm install -g less a spusťte

lessc .\css.less > styles.less.css

S AbsurdJS je to téměř stejné. Instalace je opět přes správce balíčků uzlů - npm install -g absurd .

absurd -s css.js -o styles.absurd.css

Přijímá zdroj a výstup; výsledek je stejný.

Pravda

Můžete mít opravdu krásné a pěkně vypadající soubory LESS nebo SASS, ale záleží na konečném zkompilovaném CSS. Bohužel výsledek není vždy nejlepší.

Kombinování

Uveďme si následující příklad:

.main-nav {
    background: #333;
}
.main-content {
    background: #333;
}

Pokud to předáte současným preprocesorům, dostanete nakonec to samé. Pokud však používáte AbsurdJS takto:

module.exports = function(api) {
    api.add({
        ".main-nav": {
            background: "#333"
        },
        ".main-content": {
            background: "#333"
        }
    })
}

Po kompilaci získáte

.main-nav, .main-content {
    background: #333;
}

SASS má funkci nazvanou zástupné symboly který dělá to samé. Přichází však s vlastními problémy. Zástupné symboly nemohou přijímat parametry a měli byste je opakovat v každém selektoru, který chcete kombinovat. Moje řešení pouze analyzuje pravidla a kombinuje je. Uveďme si trochu složitější příklad:

{
    ".main-nav": {
        background: "#333",
        ".logo": {
            color: "#9f0000",
            margin: 0
        }
    },
    ".main-content": {
        background: "#333"
    },
    section: {
        color: "#9f0000",
        ".box": {
            margin: 0
        }
    }
}

Výsledkem je

.main-nav, .main-content {
    background: #333;
}
.main-nav .logo, section {
    color: #9f0000;
}
.main-nav .logo, section .box {
    margin: 0;
}
section .box {
    padding: 10px;
    font-size: 24px;
}

Všechny identické styly jsou sloučeny do jediné definice. Vím, že prohlížeče jsou v dnešní době opravdu rychlé a není to úplně nejdůležitější optimalizace, ale mohla by snížit velikost souboru.

Přepisování

Víte, že pokud máte dva stejné selektory a obsahují definici stejného stylu, druhý přepíše první. Následující kód předaný přes LESS/SASS zůstává stejný:

.main-nav {
   font-size: 20px;
}
.main-nav {
   font-size: 30px;
}

Myslím si však, že to prohlížeči ponechává ještě jednu operaci:musí zjistit, že existuje jiná definice se stejným selektorem a stylem, a vypočítat správnou hodnotu. Není lepší se tomu vyhnout, tak to pošlete přímo:

.main-nav {
    font-size: 30px;
}

AbsurdJS se o to stará a vytváří pouze jednu definici. Vstup může vypadat takto:

{
    ".main-nav": {
        "font-size": "20px"
    },
    ".main-nav": {
        "font-size": "30px"
    }
}

Také to usnadňuje vaše ladicí procesy, protože neexistuje tak dlouhý řetězec přepisů.

Flexibilita

Dobře, máme mixiny, proměnné, zástupné symboly, funkce, ale jakmile je začnete používat k psaní trochu složitějších věcí, zaseknete se. Dáme si mixiny. Chci vytvořit mixin, který definuje další mixin. To v současné době není možné v LESS, protože nemůžete použít mixin definovaný v jiném mixinu. Asi je to problém s rozsahem. SASS má některé nedokonalosti týkající se interpolace proměnných. Celkově je těžké vytvořit dobrou architekturu s menším množstvím kódu. Musíte hodně psát a i tak nemůžete svých cílů skutečně dosáhnout. Hlavním důvodem těchto problémů je skutečnost, že LESS i SASS se musí vypořádat s novou syntaxí, novými pravidly a v podstatě vymyslet nový kompilátor. Pokud však používáme JavaScript, nemusíme na tyto problémy myslet.

AbsurdJS má něco, čemu se říká úložiště . Mohlo by to uložit, co chcete, a zpřístupnit to v jiných souborech. Například:

// B.js
module.exports = function(api) {
    api.storage("theme", function(type) {
        switch(type) {
            case "dark": return { color: "#333", "font-size": "20px" }; break;
            case "light": return { color: "#FFF", "font-size": "22px" }; break;
            default: return { color: "#999", "font-size": "18px" };
        }
    });
}

// A.js
module.exports = function(api) {
    api
    .import(__dirname + "/B.js")
    .add({
        ".main-nav": [
            {
                "font-size": "16px",
                padding: 0,
                margin: 0
            },
            api.storage("theme")("dark")
        ]
    });
}

Na konci dostanete:

.main-nav {
    color: #333;
    font-size: 20px;
    padding: 0;
    margin: 0;
}

Používání úložiště může být trochu ošklivé. Chci říct, že potřebujete pole přiřazené k selektoru a pak volání api.storage . Chvíli jsem to používal, ale později jsem se rozhodl implementovat něco mnohem hezčího. Je to funkce, kterou jsem vždy chtěl – možnost vytvářet si vlastní vlastnosti a ušetřit tuny linek. Vytvořme například novou vlastnost s názvem theme a zpracovat jeho hodnotu.

// B.js - definition of the plugin 
module.exports = function(api) {
    api.plugin('theme', function(api, type) {
        switch(type) {
            case "dark": return { color: "#333", "font-size": "20px" }; break;
            case "light": return { color: "#FFF", "font-size": "22px" }; break;
            default: return { color: "#999", "font-size": "18px" };
        }
    });
}

// A.js - its usage
module.exports = function(api) {
    api
    .import(__dirname + "/B.js")
    .add({
        ".header": {
            theme: "light"
        }
    })
}

Výsledek je opět podobný:

.header {
    color: #FFF;
    font-size: 22px;
}

Závěr

AbsurdJS je něco opravdu jednoduchého, ale vyhýbá se použití oblíbených CSS preprocesorů. Stále má stejnou funkci, jako jsou vnořené selektory, bublání mediálních dotazů, import souborů, proměnné, mixiny atd. Přináší však větší flexibilitu, protože se jedná o čistý JavaScript. Má dokonce podporu GruntJS. Rád bych dostal nějakou zpětnou vazbu a budu rád, když se do projektu zapojíte. Oficiální úložiště je k dispozici zde https://github.com/krasimir/absurd.