Dynamický jazyk pro tvorbu stylesheetů.

LESS rozšiřuje CSS o dynamické prvky jako jsou proměnné, mixiny, výpočty a funkce. LESS běží jak na klientské straně (Chrome, Safari, Firefox), tak na straně serveru, s Node.js a Rhino.

verze 4.1.2

Vytvořte kód v LESS:

@base: #f938ab;

.box-shadow(@style, @c) when (iscolor(@c)) {
  box-shadow:         @style @c;
  -webkit-box-shadow: @style @c;
  -moz-box-shadow:    @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
  .box-shadow(@style, rgba(0, 0, 0, @alpha));
}
.box { 
  color: saturate(@base, 5%);
  border-color: lighten(@base, 30%);
  div { .box-shadow(0 0 5px, 30%) }
}

Připojte less.js ke svým stylům:

<link rel="stylesheet/less" type="text/css" href="styles.less">
<script src="less.js" type="text/javascript"></script>

Proměnné

Proměnné vám umožní specifikovat často používané hodnoty na jednom místě a následně je jen využívat v stylesheetu. Změny těchto hodnot jsou tak záležitostí editace jednoho řádku.

  // LESS

@color: #4D926F;

#header {
  color: @color;
}
h2 {
  color: @color;
}
/* Výsledné CSS */

#header {
  color: #4D926F;
}
h2 {
  color: #4D926F;
}

Mixiny

Mixiny umožňují vložit všechny vlastnosti třídy do jiné třídy, a to jednoduše specifikací jejího názvu uvnitř jiné třídy. Berte je jako proměnné, ovšem pro celé třídy. Mixiny se rovněž mohou chovat jako funkce a pracovat s argumenty, viz následující ukázka.

// LESS

.rounded-corners (@radius: 5px) {
  border-radius: @radius;
  -webkit-border-radius: @radius;
  -moz-border-radius: @radius;
}

#header {
  .rounded-corners;
}
#footer {
  .rounded-corners(10px);
}
/* Výsledné CSS */

#header {
  border-radius: 5px;
  -webkit-border-radius: 5px;
  -moz-border-radius: 5px;
}
#footer {
  border-radius: 10px;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
}

Vnořená pravidla

Místo vytváření selektorů s dlouhými názvy ke specifikaci dědičnosti můžete v Less použít vnoření selektorů do jiných. Díky tomu bude zápis přehlednější a stylesheet kratší.

// LESS

#header {
  h1 {
    font-size: 26px;
    font-weight: bold;
  }
  p { font-size: 12px;
    a { text-decoration: none;
      &:hover { border-width: 1px }
    }
  }
}

/* Výsledné CSS */

#header h1 {
  font-size: 26px;
  font-weight: bold;
}
#header p {
  font-size: 12px;
}
#header p a {
  text-decoration: none;
}
#header p a:hover {
  border-width: 1px;
}

Funkce & Výpočty

Jsou všechny elementy ve vašich stylech v určité proporci k jiným elementům? Pomocí výpočtů v Less můžete přidávat, odečítat, dělit a násobit hodnoty a barvy. Získáváte tedy výkonný nástroj pro vytvoření komplexních vztahů mezi vlastnostmi jednotlivých selektorů. Funkce vám umožňují pracovat s JavaScriptem a manipulovat s hodnotami, jak potřebujete.

// LESS

@the-border: 1px;
@base-color: #111;
@red:        #842210;

#header {
  color: @base-color * 3;
  border-left: @the-border;
  border-right: @the-border * 2;
}
#footer { 
  color: @base-color + #003300;
  border-color: desaturate(@red, 10%);
}

/* Výsledné CSS */

#header {
  color: #333;
  border-left: 1px;
  border-right: 2px;
}
#footer { 
  color: #114411;
  border-color: #7d2717;
}

Použití na klientské straně

Připojte stylesheety .less s atributem rel nastaveným na "stylesheet/less":

<link rel="stylesheet/less" type="text/css" href="styles.less">

Stáhněte si less.js z odkazu nahoře na stránce a vložte jej do hlavičky <head> na své stránce, tedy:

<script src="less.js" type="text/javascript"></script>

Ujistěte se, že jste stylesheety připojili před skriptem.

Sledovací režim

Sledovací režim je vlastnost na klientské straně, která umožňuje automaticky načítat styly v případě, že se změnily.

Pro zapnutí této vlastnosti, přidejte za adresu v prohlížeči výraz '#!watch' a znovu načtěte stránku. Téhož docílíte zavoláním less.watch() z konzoly.

Použití na straně serveru

Instalace

Nejjednodušším způsobem, jak nainstalovat LESS na server, je použití nástroje npm, node package manageru:

$ npm install less

Použití

Po instalaci můžete vyvolat kompilátor z nodu například tímto způsobem:

var less = require('less');

less.render('.class { width: 1 + 1 }', function (e, css) {
    console.log(css);
});

výsledkem bude:

.class {
  width: 2;
}

parser a kompilátor lze vyvolat také manuálně:

var parser = new(less.Parser);

parser.parse('.class { width: 1 + 1 }', function (err, tree) {
    if (err) { return console.error(err) }
    console.log(tree.toCSS());
});

Konfigurace

Kompilátoru můžete předat různá nastavení:

var parser = new(less.Parser)({
    paths: ['.', './lib'], // specifikace cesty pro hledání souborů u direktivy @import
    filename: 'style.less' // specifikace jména souboru, pro lepší hlášení chyb
});

parser.parse('.class { width: 1 + 1 }', function (e, tree) {
    tree.toCSS({ compress: true }); // minimalizuje CSS výstup
});

Použití s příkazovým řádkem

Less obsahuje binárku, která vám umožní vyvolat kompilátor z příkazového řádku, například:

$ lessc styles.less

Tím dostanete CSS výstup do stdout, takže jej můžete nasměrovat do libovolného souboru:

$ lessc styles.less > styles.css

Pro výstup minimalizovaného CSS, přidejte přepínač -x. Chcete-li dosáhnout většího zmenšení, použijte YUI CSS Compressor s přepínačem --yui-compress.

Jazyk

Jakožto rozšíření k CSS je s ním LESS nejenom zpětně kompatibilní, ale přidává navíc několik vlastností používajících stávající syntaxi CSS. Díky tomu jste schopni se LESS naučit s lehkostí a v případě jakýchkoli pochyb o správnosti zápisu prostě použít klasické CSS.

Proměnné

Použití proměnných je zřejmé z následující ukázky:

@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header { color: @light-blue; }

Výstup:

#header { color: #6c94be; }

Stejně tak je možné definovat proměnné se jménem:

@fnord: "Jsem fnord.";
@var: 'fnord';
content: @@var;

Po kompilaci vytvoří:

content: "Jsem fnord.";

Poznámka: proměnné v LESS jsou momentálně spíše konstantami, jelikož mohou být definovány pouze jednou.

Mixiny

V LESS je možné vložit sadu vlastností z jedné sady pravidel do jiné sady. Řekněme tedy, že máme následující třídu:

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

A vlastnosti definované v této řídě chceme použít v jiné sadě pravidel. Stačí nám k tomu uvést jméno definované třídy v jiné sadě pravidel, do které chceme definice z dané třídy vložit:

#menu a {
  color: #111;
  .bordered;
}
.post a {
  color: red;
  .bordered;
}

Vlastnosti třídy .bordered se nyní objeví jak v #menu a, tak v .post a:

#menu a {
  color: #111;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
.post a {
  color: red;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

Jako mixin můžete použít jakoukoli class (třídu) nebo id se sadou definic.

Parametrické mixiny

LESS nabízí speciální typ sady pravidel, které mohou být využity jako mixiny tříd, ale navíc akceptují parametry. Zde je konkrétní příklad:

.border-radius (@radius) {
  border-radius: @radius;
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
}

A zde způsob, jakým jej můžeme použít v různých sadách pravidel:

#header {
  .border-radius(4px);
}
.button {
  .border-radius(6px);
}

Parametrické mixiny mohou mít rovněž výchozí hodnoty pro své parametry:

.border-radius (@radius: 5px) {
  border-radius: @radius;
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
}

Výše uvedená pravidla tak můžeme použít následovně:

#header {
  .border-radius;
}

A dostaneme 5px zaoblení rohů ve vlastnosti border-radius.

Rovněž můžete pracovat s parametrickými mixiny, které nevyžadují parametry. To se hodí v případě, že nechcete danou sadu pravidel zobrazit v CSS výstupu, ale jen vložit její vlastnosti do jiné sady pravidel:

.wrap () {
  text-wrap: wrap;
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  word-wrap: break-word;
}

pre { .wrap }

Vytvoří výstup:

pre {
  text-wrap: wrap;
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  word-wrap: break-word;
}

Proměnné s argumenty

@argumenty mají v mixinech speciální význam, obsahují všechny předané argumenty v okamžiku, kde je mixin volán. Využití najdou v případě, kdy nechcete pracovat s jednotlivými parametry:

.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
  box-shadow: @arguments;
  -moz-box-shadow: @arguments;
  -webkit-box-shadow: @arguments;
}
.box-shadow(2px, 5px);

Tomu odpovídající výstup:

  box-shadow: 2px 5px 1px #000;
  -moz-box-shadow: 2px 5px 1px #000;
  -webkit-box-shadow: 2px 5px 1px #000;

Práce se vzorky a výrazy

Občas budete potřebovat změnit chování mixinu v závislosti na paramatrech, které mu předáte. Zkusme si jednoduchý příklad:

.mixin (@s, @color) { ... }

.class {
  .mixin(@switch, #888);
}

Nyní řekněme, že chceme, aby se .mixin choval odlišně podle toho, jaká hodnota mu bude předána v parametru @switch. V takovém případě můžeme .mixin definovat takto:

.mixin (dark, @color) {
  color: darken(@color, 10%);
}
.mixin (light, @color) {
  color: lighten(@color, 10%);
}
.mixin (@_, @color) {
  display: block;
}

Pokud nyní spustíme následující:

@switch: light;

.class {
  .mixin(@switch, #888);
}

Dostaneme toto CSS:

.class {
  color: #a2a2a2;
  display: block;
}

Jak vidíte, barva předaná přes .mixin byla zesvětlena. Pokud by hodnota proměnné @switch byla dark, obdrželi bychom ztmavenou barvu.

Podrobnější vysvětlení:

  • První definice mixinu by byla provedena v případě, kdy by jako první argument byla hodnota dark.
  • Druhá definice mixinu vyhovuje, protože očekává hodnotu light.
  • Vyhovuje i třetí definice mixinu, jelikož očekává jakoukoli hodnotu.

Použity jsou tedy jen ty definice mixinu, které vyhovují zadaným hodnotám. Proměnné se vážou na jakoukoli hodnotu. Cokoli jiného, než proměnná, vyhovuje jen v případě, že obsahuje stejnou hodnotu.

Stejně tak můžeme porovnávat aritu (místnost operace), zde je příklad:

.mixin (@a) {
  color: @a;
}
.mixin (@a, @b) {
  color: fade(@a, @b);
}

Pokud nyní zavoláme .mixin s jedním argumentem, dostaneme výsledek odpovídající první definici. Jestliže jej zavoláme se dvěma argumenty, obdržíme druhou definici, konkrétně @a pohaslé na @b.

Strážci

Strážce využijete v případě, kdy chcete párovat na základě výrazů, na rozdíl od jednoduchých hodnot nebo arity. Pokud si rozumíte s funkcionálním programováním, pravděpodobně jste se s nimi již setkali.

Ve snaze zůstat co nejblíže deklarativní povaze CSS, LESS implementuje podmíněné spouštění pomocí hlídaných mixinů místo konstrukcí if/else, ve stylu specifikací @media query.

Začněme s následujícím příkladem:

.mixin (@a) when (lightness(@a) >= 50%) {
  background-color: black;
}
.mixin (@a) when (lightness(@a) < 50%) {
  background-color: white;
}
.mixin (@a) {
  color: @a;
}

Klíčový je zde výraz when, který zavádí posloupnost strážců (zde ovšem jen s jedním strážcem). Pokud nyní spustíme následující kód:

.class1 { .mixin(#ddd) }
.class2 { .mixin(#555) }

Dostaneme tento výsledek:

.class1 {
  background-color: black;
  color: #ddd;
}
.class2 {
  background-color: white;
  color: #555;
}

Kompletní výčet porovnávacích operátorů pro použití se strážci je tento: > >= = =< <. Klíčové slovo true je jediná kladná hodnota, z čehož plyne, že následující dva mixiny jsou ekvivalentní:

.truth (@a) when (@a) { ... }
.truth (@a) when (@a = true) { ... }

Jakákoli jiná hodnota než klíčové slovo true je záporná:

.class {
  .truth(40); // Nevyhovuje žádné z výše uvedených definicí.
}

Strážci mohou být odděleni čárkou ','--pokud je kterýkoli ze strážců vyhodnocen jako kladný, je považován za vyhovujícího:

.mixin (@a) when (@a > 10), (@a < -10) { ... }

Poznámka: argumenty můžete rovněž porovnávat mezi sebou nebo s neargumenty:

@media: mobile;

.mixin (@a) when (@media = mobile) { ... }
.mixin (@a) when (@media = desktop) { ... }

.max (@a, @b) when (@a > @b) { width: @a }
.max (@a, @b) when (@a < @b) { width: @b }

A konečně, chcete-li porovnat mixiny podle typu hodnoty, můžete použít funkci *is**:

.mixin (@a, @b: 0) when (isnumber(@b)) { ... }
.mixin (@a, @b: black) when (iscolor(@b)) { ... }

Zde jsou základní funkce pro ověřování typu hodnoty:

  • iscolor
  • isnumber
  • isstring
  • iskeyword
  • isurl

Chcete-li zjistit, zda je číselná hodnota navíc nějakou specifickou jednotkou, použijte některé z následujících ověření:

  • ispixel
  • ispercentage
  • isem

V neposlední řadě můžete použít klíčové slovo and a vytvořit tak další podmínky uvnitř strážce:

.mixin (@a) when (isnumber(@a)) and (@a > 0) { ... }

A klíčové slovo not k negaci podmínek:

.mixin (@b) when not (@b > 0) { ... }

Vnořená pravidla

LESS vám dává možnost použít vnoření místo nebo v kombinaci s použitím kaskádového zápisu. Řekněme, že máte následujíc zápis CSS:

#header { color: black; }
#header .navigation {
  font-size: 12px;
}
#header .logo {
  width: 300px;
}
#header .logo:hover {
  text-decoration: none;
}

S použitím LESS jej můžete zapsat také následovně:

#header {
  color: black;

  .navigation {
    font-size: 12px;
  }
  .logo {
    width: 300px;
    &:hover { text-decoration: none }
  }
}

Nebo tímto způsobem:

#header        { color: black;
  .navigation  { font-size: 12px }
  .logo        { width: 300px;
    &:hover    { text-decoration: none }
  }
}

Výsledný kód je mnohem stručnější a napodobuje strukturu DOM.

Poznámka: Znak & použijete v případě, kdy chcete vnořený selektor spojit s jeho rodičem místo toho, aby se choval jako následovník. Tato technika najde využití u pseudotříd jako jsou :hover a :focus.

Například:

.bordered {
  &.float {
    float: left;
  }
  .top {
    margin: 5px;
  }
}

Vygeneruje:

.bordered.float {
  float: left;
}
.bordered .top {
  margin: 5px;
}

Výpočty

Jakékoli číslo, barva nebo proměnná mohou být součástí nějakého výpočtu. Zde je několik příklad:

@base: 5%;
@filler: @base * 2;
@other: @base + @filler;

color: #888 / 4;
background-color: @base-color + #111;
height: 100% / 2 + @filler;

Výsledek je takový, jako očekáváte. LESS rozpozná rozdíly mezi definicemi barev a jednotkami. Pokud je ve výpočtu použita jednotka jako v:

@var: 1px + 5;

LESS ji použije i ve výsledné hodnotě. V daném případě vrátí 6px.

Ve výpočtech můžete použít také závorky:

width: (@var + 5) * 2;

V případě složených hodnot jsou pak závorky nutností:

border: (@width * 2) solid black;

Práce s barvami

LESS poskytuje sadu funkcí pro převody barev. Všechny barvy jsou nejprve převáděny do formátu HSL a následně se s nimi manipuluje na úrovní kanálů:

lighten(@color, 10%);     // vrátí barvu, která je o 10% *světlejší* než @color
darken(@color, 10%);      // vrátí barvu, která je o 10% *tmavší* než @color

saturate(@color, 10%);    // vrátí barvu o 10% *více* sytou než @color
desaturate(@color, 10%);  // vrátí barvu o 10% *méně* sytou než @color

fadein(@color, 10%);      // vrátí barvu o 10% *méně* průhlednou než @color
fadeout(@color, 10%);     // vrátí barvu o 10% *více* průhlednou než @color
fade(@color, 50%);        // vrátí barvu @color s 50% průhledností

spin(@color, 10);         // vrátí barvu s o 10 stupňů teplejším odstínem než @color
spin(@color, -10);        // vrátí barvu o 10 chladnější než @color

mix(@color1, @color2);    // vrátí kombinaci barev @color1 a @color2

Použití je v praxi je zřejmé:

@base: #f04615;

.class {
  color: saturate(@base, 5%);
  background-color: lighten(spin(@base, 8), 25%);
}

Z definicí barev můžete rovněž získat jednotlivé informace:

hue(@color);        // vrátí `odstín` barvy @color
saturation(@color); // vrátí `sytost` barvy @color
lightness(@color);  // vrátí 'světlost' barvy @color
alpha(@color);      // vrátí 'alpha' kanál barvy @color

Výše uvedené najde využití v případě, kdy chcete vytvořit novou barvu založenou na jiném barevném kanálu, například:

@new: hsl(hue(@old), 45%, 90%);

@new bude obsahovat odstín barvy @old' a svou vlastní sytost a světlost.

Matematické funkce

LESS poskytuje několik užitečných matematických funkcí:

round(1.67); // vrátí `2`
ceil(2.4);   // vrátí `3`
floor(2.6);  // vrátí `2`

Potřebujete-li převést hodnotu na procentuální vyjádření, učiňte tak s funkcí percentage:

percentage(0.5); // vrátí `50%`

Jmenné prostory

Občas budete chtít své proměnné nebo mixiny seskupit, třeba kvůli lepší orientaci v kódu nebo pro nějaké zapouzdření. V LESS tak můžete učinit velmi intuitivní cestou - řekněme, že chcete seskupit některé mixiny a proměnné do #bundle a nachystat je tak pro pozdější použití nebo distribuci:

#bundle {
  .button () {
    display: block;
    border: 1px solid black;
    background-color: grey;
    &:hover { background-color: white }
  }
  .tab { ... }
  .citation { ... }
}

Pokud nyní chcete mixovat třídu .button v selektoru #header a, použijete:

#header a {
  color: orange;
  #bundle > .button;
}

Prostor

Prostor v LESS je podobný prostorům v programovacích jazycích. Proměnné a mixiny jsou nejprve vyhledávány lokálně, nejsou-i nalezeny, kompilátor se je pokusí vyhledat v nadřazeném prostoru atd.

@var: red;

#page {
  @var: white;
  #header {
    color: @var; // white
  }
}

#footer {
  color: @var; // red
}

Komentáře

V LESS můžete používat klasické CSS komentáře:

/* Ahoj, jsem klasický komentář v CSS */
.class { color: black }

Navíc jsou v LESS k dispozici i jednořádkové komentáře, ovšem jejich obsah se neobjeví v převedeném CSS výstupu:

// Zdravím, jsem skrytý komentář, neobjevím se v CSS výstupu
.class { color: white }

Import

Importovat můžete soubory .less, přičemž všechny jejich proměnné a mixiny budou dostupné hlavnímu souboru. Koncovka .less je volitelná, takže správné jsou oba zápisy:

@import "lib.less";
@import "lib";

Chcete-li importovat soubor CSS a neaplikovat na něj LESS, použijte souborovou koncovku .css:

@import "lib.css";

Uvedená direktiva pak zůstane nedotčena a objeví se v CSS výstupu.

Interpolace řetězců

Do řetězců mohou být vloženy proměnné podobným způsobem jako v Ruby nebo PHP s konstrukcí @{name}:

@base-url: "http://assets.fnord.com";
background-image: url("@{base-url}/images/bg.png");

Escapování

Někdy budete potřebovat vyprodukovat CSS výstup, který není kompatibilní se syntaxí CSS, nebo používá proprietární syntaxi, kterou LESS nerozpozná:

Pro výstup takovéto hodnoty ji stačí vložit do řetězce s předponou ~, například takto:

.class {
  filter: ~"ms:alwaysHasItsOwnSyntax.For.Stuff()";
}

Takto escapovaná hodnota se ve výstupu objeví následovně:

.class {
  filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
}

Zpracování JavaScriptu

V souborech .less mohou být vyhodnocovány výrazy psané v JavaScriptu. Chcete-li je použít, zapište je do zpětných apostrofů:

@var: `"ahoj".toUpperCase() + '!'`;

Vytvoří:

@var: "AHOJ!";

Stejně tak můžete používat interpolaci a escapování jako u řetězců:

@str: "ahoj";
@var: ~`"@{str}".toUpperCase() + '!'`;

Vytvoří:

@var: AHOJ!;

Stejně tak je možné přistupovat k JavaScriptovému prostředí:

@height: `document.body.clientHeight`;

Chcete-li parsovat JavaScriptový řetězec jako hexadecimální barvu, použijte funkci color:

@color: color(`window.colors.baseColor`);
@darkcolor: darken(@color, 10%);

Překlady do dalších jazyků

Videonávod / videokurz

Celý český kurz věnovaný LESS najdete zdarma na oceantutorials.com.

O projektu

LESS vytvořil Alexis Sellier, známý též jako cloudhead. Anglický originál stránek lesscss.org přeložil do češtiny Jan Polzer. Jeho články najdete na webu Maxiorel.cz

Narazíte-li na nepřesnosti v dokumentaci, dejte mi prosím vědět.

Původní web používal Ruby a jednoduchý systém Toto, tento web byl předělán na PHP s jednoduchým načítáním souborů v syntaxi markdown.