Miért jó CSS preprocesszort használni egy igazán ütős reszponzív weboldal készítésekor?  előnézeti képe

Miért jó CSS preprocesszort használni egy igazán ütős reszponzív weboldal készítésekor?

| Olvasási idő: 4 perc

Mert nagyon egyszerűvé teszi a munkánkat! Egészen pontosan mivel is? Ezt fogom megmutatni ebben a bejegyzésben.

A munkafolyamataimat szeretem a lehető legkevesebb külső eszközzel kiegészíteni, a "kevesebb több" elv híve vagyok. Azonban olykor találok olyan segítőket, amik egyértelműen megérik a beállítás és betanulás okozta plusz vesződséget, mert hosszú távon megkönnyítik és hatékonyabbá teszik a munkát. 

Többször előfordult már, hogy a kiválasztott brand szín nem tetszett a megrendelőnek. Ilyenkor mi a teendő? Elő a .css fájl, majd egy keresés-és-csere kombinációval a korábbi színkódot lecserélem az újra. Ha esetleg a különféle színvariánsokat is cserélnem kell (linkek, hátterek, stb.), akkor ugyanígy keresés-és-csere, ismételve minden színvariációra, majd mentés, és ezt követően máris kész a változtatás - elég macerás, ha egy szín több verziójával is dolgozunk. 

Mi lenne, ha azt mondanám, van egy egyszerűbb módszer? Nos, igen, jól sejted, itt jön képbe a SASS, ami egy CSS preprocesszor (jaj!). A segítségével "felokosíthatjuk" a .css fájljainkat: megadhatunk bennük változókat, számításokat végezhetünk, mixineket (stílusblokkok újrahasznosítható összessége) használhatunk - ezek mind megkönnyítik a munkát. Hogy miért? 

Tegyük fel, van egy oldalunk, a .css fájljának egy részlete látható alább: 

css
article { // a cikk 
    max-width: 800px; // maximális szélesség 800px;
    margin: auto; //margók: automatikusak
    display: block; // block típusú elemként jelenik meg 
    // a margin: auto; és a display: block; együtt az egész block típusú elemet középre igazítják
}
article p { // a cikken belüi bekezdés
    color: #333; // a szöveg színe sötétszürke
    font-size: 14px; // a betűméret 14px
    margin-left: 21px; // a bal margó 21px
    margin-right: 21px; // a jobb margó 21px
} 
article p a { // a cikken belüli hivatkozás (a, mint anchor = horgony)
    color: #22aadd; // a link színe világoskék
    text-decoration: none; // szöveg díszítés nincs (az alapértelmezett aláhúzás helyett)
    border-bottom: 1px solid #22aadd; // a link alatt 1 pixeles, folytonos, világoskék színű keret lesz 
}
article p a:hover { // a cikken belüli hivatkozás akkor, amikor az egér a hivatkozás felett áll
    color: #18779b; // a link színe sötétebb világoskék
}

A // részek ki vannak kommentelve, azokat nem veszi figyelembe a böngésző, viszont nekünk segít az értelmezésben. A fenti részlet elég átlátható, viszont vannak benne ismétlések, amiket keresés-és-cserével kellene cserélnünk egy változás esetében. Írjuk át ezt a kódot (az áttekinthetőség miatt) SCSS (a SASS CSS-re hasonlító szintaxisa) formába, hogy lássuk, mit is könnyít meg a munkán a SASS.

scss
$max-width: 800px; 
$text-color: #333;
$brand-color: #22aadd;
$font-size: 14px;
article { // a cikk 
    max-width: $max-width; // maximális szélesség - a változó fenti értéke esetén - 800px;
    margin: auto; //margók: automatikusak
    display: block; // block típusú elemként jelenik meg 
    // a margin: auto; és a display: block; együtt az egész block típusú elemet középre igazítják
    p { // a cikken belüi bekezdés
        color: $text-color; // a szöveg színe sötétszürke
        font-size: $font-size; // a betűméret 14px
        margin-left: $font-size*1.5; // a bal margó 14px*1.5 = 21px
        margin-right: $font-size*1.5; // a jobb margó 14px*1.5 = 21px
        a { // a cikken belüli hivatkozás (a, mint anchor = horgony)
            color: $brand-color; // a link színe világoskék
            text-decoration: none; // szöveg díszítés nincs (az alapértelmezett aláhúzás helyett)
            border-bottom: 1px solid $brand-color; // a link alatt 1 pixeles, folytonos, világoskék színű keret lesz 
            &:hover { // a szülő selectort helyettesíti be a & helyére, ebben az esetben tehát: article p a, vagyis a végeredmény article p a:hover lesz
                color: darken($brand-color, 15%); // a link színe a brand színének 15%-kal sötétített verziója
            }
        }
    }
}

A beágyazásokat a preprocesszor "kibontja", és átírja a fent már felírt alakra, valamint az egyes változókat is behelyettesíti és az értéküket írja a helyükre. Ha számolnivaló akad, azt a műveletet is elvégzi, és csak a végeredményt írja be a megadott helyre, de ha színekkel "végzünk műveletet" (pl. a brand szín egy sötétebb árnyalatát használnánk), ezzel is megbirkózik. Ezt követően ha változtatnunk kell bármelyik jellemzőn is, akkor elég csak az .scss fájl fejlécében átírni az értékeket és az "végigfut" a teljes dokumentumon: ha pl. a színeken változtatnánk, akkor az adott szín összes változatát egyszerre változtatja meg. 

Vegyünk egy bonyolultabb példát: gombokat szeretnék készíteni. Erre a legegyszerűbb módszer, ha kettébontom a gomb jellemzőit: egy általános részre, ami az összes gombra igaz lesz, és egy specifikusra, ami az adott színezésű gombra fog vonatkozni: 

css
.btn {
    background: transparent;
    border: 2px solid #222;
    color: #222;
    padding: 0.75em 1em 0.5em 1em;
    text-shadow: none;
    font-weight: 500;
    display: inline-block;
    margin-bottom: 0;
    text-align: center;
    vertical-align: middle;
    touch-action: manipulation;
    cursor: pointer;
    white-space: nowrap;
    font-size: 16px;
    line-height: 1.42857143;
    border-radius: 0px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.btn-danger {
    color: #fff;
    background-color: #c10c10;
    border-color: #c10c10;
}

Ennek hatására lesz egy piros gombom. Rendben, ez így nem tűnik bonyolultnak, viszont több színre is szükségünk lehet, ezért bővítjük a kódot: 

scss
.btn {
    background: transparent;
    border: 2px solid #222;
    color: #222;
    padding: 0.75em 1em 0.5em 1em;
    text-shadow: none;
    font-weight: 500;
    display: inline-block;
    margin-bottom: 0;
    text-align: center;
    vertical-align: middle;
    touch-action: manipulation;
    cursor: pointer;
    white-space: nowrap;
    font-size: 16px;
    line-height: 1.42857143;
    border-radius: 0px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.btn-default {
    color: #fff;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-primary {
    color: #fff;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-success {
    color: #fff;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-warning {
    color: #fff;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-danger {
    color: #fff;
    background-color: #c10c10;
    border-color: #c10c10;
}
.btn-info {
    color: #fff;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}

Látható, hogy elkezdtünk ismételni egy mintázatot: az összes gombnál csak ugyanazokat a tulajdonságokat változtatjuk meg, és az értékek jellemzően megegyeznek (tehát ebben az esetben a border-color mindig ugyanolyan, mint a background-color). Foglalkozzunk egyelőre csak eggyel, a piros gombunkkal! A fenti kódot tovább kell bővíteni, mert nem csak az alapállapotot, hanem azt is le kell szabályoznunk, amikor az egér a gomb felett van (az egyszerűség kedvéért most csak ezt), erre szolgál a :hover selector: 

css
.btn {
    background: transparent;
    border: 2px solid #222;
    color: #222;
    display: inline-block;
    padding: 12px 16px 8px 16px;
    text-shadow: none;
    font-weight: 500;
    margin-bottom: 0;
    text-align: center;
    vertical-align: middle;
    touch-action: manipulation;
    cursor: pointer;
    white-space: nowrap;
    font-size: 16px;
    line-height: 1.42857143;
    border-radius: 0px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.
.
.
.btn-danger {
    color: #fff;
    background-color: #c10c10;
    border-color: #c10c10;
}
.btn-danger:hover {
    color: #fff;
    background-color: #91090c;
    border-color: #79080a;
}
.
.
.

Ez eddig 33 sor, kezdjük el átírni SASS-ba: 

scss
$text-color: #222;
$font-size: 16px; 
$btn-font-weight: 500;
$line-height: 20/14;
$white: #fff;
$color-danger: #c10c10;
// bevezetjük a button-variant mixin-t, aminek 3 paramétere van, sorrendben: $color, $background és $border. A mixinnek ezeket a változókat átadva azokat a mixinben jelölt helyekre helyettesíti be, nekünk elég csak a mixint behivatkozni
@mixin button-variant($color, $background, $border) {
  color: $color;
  background-color: $background;
  border-color: $border;
  &:hover {
    color: $color;
    background-color: $background;
        border-color: darken($border, 12%);
  }
}
.btn {
    background: transparent;
    border: 2px solid $text-color;
    color: $text-color;
    display: inline-block;
    padding: $font-size*0.75 $font-size $font-size*0.5 $font-size;
    text-shadow: none;
    font-weight: $btn-font-weight;
    margin-bottom: 0;
    text-align: center;
    vertical-align: middle;
    touch-action: manipulation;
    cursor: pointer;
    white-space: nowrap;
    font-size: $font-size;
    line-height: $line-height;
    border-radius: 0;
    @include user-select(none);
    &-danger {
      // itt hivatkozzuk be a mixint: 
      @include button-variant($white, $color-danger, $color-danger);
    }
}

Itt a SASS verzió 44 sorra hízott szemben a normál CSS 33 sorával. De mi történik, ha visszahozzuk a többi gombot is? Nézzük (az értékeket nem írtam be, de oda nyugodtan képzeljünk bármilyen tetszőleges értéket): 

css
.btn {
    background: transparent;
    border: 2px solid #222;
    color: #222;
    padding: 0.75em 1em 0.5em 1em;
    text-shadow: none;
    font-weight: 500;
    display: inline-block;
    margin-bottom: 0;
    text-align: center;
    vertical-align: middle;
    touch-action: manipulation;
    cursor: pointer;
    white-space: nowrap;
    font-size: 16px;
    line-height: 1.42857143;
    border-radius: 0px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.btn-default {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-default:hover {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-primary {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-primary:hover {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-success {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-success:hover {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-warning {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-warning:hover {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-danger {
    color: #fff;
    background-color: #c10c10;
    border-color: #c10c10;
}
.btn-danger:hover {
    color: #fff;
    background-color: #91090c;
    border-color: #79080a;
}
.btn-info {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
.btn-info:hover {
    color: #tetszőleges_érték;
    background-color: #tetszőleges_érték;
    border-color: #tetszőleges_érték;
}
scss
$text-color: #222;
$font-size: 16px; 
$btn-font-weight: 500;
$line-height: 20/14;
$white: #fff;
$color-danger: #c10c10;
// bevezetjük a button-variant mixin-t, aminek 3 paramétere van, sorrendben: $color, $background és $border. A mixinnek ezeket a változókat átadva azokat a mixinben jelölt helyekre helyettesíti be, nekünk elég csak a mixint behivatkozni
@mixin button-variant($color, $background, $border) {
  color: $color;
  background-color: $background;
  border-color: $border;
  &:hover {
    color: $color;
    background-color: $background;
        border-color: darken($border, 12%);
  }
}
.btn {
    background: transparent;
    border: 2px solid $text-color;
    color: $text-color;
    display: inline-block;
    padding: $font-size*0.75 $font-size $font-size*0.5 $font-size;
    text-shadow: none;
    font-weight: $btn-font-weight;
    margin-bottom: 0;
    text-align: center;
    vertical-align: middle;
    touch-action: manipulation;
    cursor: pointer;
    white-space: nowrap;
    font-size: $font-size;
    line-height: $line-height;
    border-radius: 0;
    @include user-select(none);
    &-default { // itt hivatkozzuk be a mixint: 
      @include button-variant($white, $color-default, $color-default);
    }
    &-primary {
      @include button-variant($white, $color-primary, $color-primary);
    }
    &-success {
      @include button-variant($white, $color-success, $color-success);
    }
    &-warning {
      @include button-variant($white, $color-warning, $color-warning);
    }
    &-danger {
      @include button-variant($white, $color-danger, $color-danger);
    }
    &-info {
      @include button-variant($white, $color-info, $color-info);
    }
}

CSS: 94 sor, SASS: 58 sor. Látszik, hogy a kód összetettségével elkezdett a korábban bonyolultabb megoldás jelentős egyszerűsítést hozni, és ugyanazt az eredményt majdnem feleannyi sorban tudja produkálni. 

Összefoglalva tehát látható, hogy: 

  • sokkal tömörebb a kód, 
  • a változók egy helyen kerülnek definiálásra, így nem kell emlékeznünk az értékekre, elég csak a változó nevét beírni, 
  • nem kell sokszor ugyanazt (pl.: az article selectort) többször leírnunk, mert a beágyazásoknak köszönhetően ez automatikusan lekezelésre kerül

A cikkben csak a SASS-szal foglalkoztam, mert ez a legelterjedtebb CSS preprocesszor, de létezik több másik is - a teljesség igénye nélkül néhány: LESS, Stylus, CSS-Crush, Myth, Rework.