Theming mit LESS

Theming ist eine verbreitete Anforderung in Webanwendungen. Oft geht es nur darum die Farben auszutauschen und dafür gibt es in LESS eine sehr schöne Möglichkeit mittels Variablen.

HTML

Zunächst wird das aktive Theme im <body> Tag hinterlegt:

<body class="theme-modern">

oder

<body class="theme-classic">

all.less

In der Hauptprojektdatei, die ich gerne all.less nenne, werden alle Themes eingebunden:

@import 'themes/base.less';
@import 'themes/classic.less';
@import 'themes/modern.less';

base.less

In der base.less finden sich alle generischen Styles und vor allem die Variablen, die Themes später ändern können:

.theme-base(@label-color:red, @link-color:red, @color-special:blue) {
    .header {
        color: @label-color;   
        font-size: 18x;
    }

    .link {
        background: @link-color;
        font-weight: bold;
    }
}

Es wird ein parametrisiertes Mixin theme-base definiert, wodurch damit noch keinerlei CSS erzeugt wird.

classic.less

Das konkrete Theme nutzt nun das Mixin und setzt im “Konstruktor” das Farbschema:

.theme-classic {
   .theme-base(
     @label-color: black;
     @link-color: blue;
   );
 }

Beachtlich ist, dass hier keine CSS-Klassen doppelt definiert, sondern ausschließlich Variablen gesetzt wurden. Auch müssen nicht alle Parameter übergeben werden, da das Mixin theme-base default-Werte angegeben hat.

modern.less

Analog kann man nun andere Themes umsetzen:

.theme-modern {
    .theme-base(
        @label-color:silver;
        @link-color: wheat;
    );

    .header {
        font-size: 16px;
    }
}

Es können natürlich noch beliebige Styles hingezugefügt werden, die über die Mixin-Parametrisierung hinaus gehen.

all.css

Für das obige Beispiel wird folgendes CSS generiert:

.theme-classic .header {
  color: #000000;
  font-size: 18x;
}
.theme-classic .link {
  background: #0000ff;
  font-weight: bold;
}
.theme-modern .header {
  color: #c0c0c0;
  font-size: 18x;
}
.theme-modern .link {
  background: #f5deb3;
  font-weight: bold;
}
.theme-modern .header {
  font-size: 16px;
}

Ich finde das CSS gut lesbar, wenn man es später im Browser debuggen muss, allerdings ist es etwas redundant – was natürlich an festen Werten in der Mixin-Definition liegt.

base-optimized.less

Man kann das nun noch etwas optimieren:

.header {
     font-size: 18x;
}

.link {
     font-weight: bold;   
}

.theme-base(@label-color:red, @link-color:red, @color-special:blue) {
    .header {
        color: @label-color;   
    }

    .link {
        background: @link-color;
    }
}

Ich finde diese Definition einen Tick weniger übersichtlich, als die Ursprungsversion, aber dafür ist das resultierende CSS kompakter, was für die Performance bei größeren Projekten durchaus ein Kriterium sein kann:

.header {
  font-size: 18x;
}
.link {
  font-weight: bold;
}
.theme-classic .header {
  color: #000000;
}
.theme-classic .link {
  background: #0000ff;
}
.theme-modern .header {
  color: #c0c0c0;
}
.theme-modern .link {
  background: #f5deb3;
}
.theme-modern .header {
  font-size: 16px;
}

In diesem trivialen Beispiel sieht die Ersparnis gering aus, aber bei einer realen Anwendung mit vielen Attributen pro Klasse macht sich das dann schnell bemerkbar.

Fazit

LESS macht das Theming wirklich elegant!