Stora sajter behöver en arkitektur för CSS

KTH.se är en av de större webbplatserna i Sverige och består av hundratals domäner och miljoner webbsidor. En stor del av dessa ligger i vårt centrala webbpubliceringsssytem som sköter huvuddelen av vår externa webbplats samt intranätet. Till det har även en rad andra webbplatser som ligger i vårt publiceringssystem, fast de utseendemässigt inte ser ut att göra det. Alla använder de dock samma inmatningsmallar i redaktörsgränssnittet.

Vi som bygger tekniken bakom KTH.se är väldigt stolta över vad vi gjort och har delat med oss av vår implementation till andra myndigheter, och pratat om vår lösning på olika konferenser, men vi har aldrig skrivit om hur det fungera här på bloggen, och eftersom vi nu äntligen tar steget in i en webb anpassad för mobiltelefoner är det kanske dags att berätta lite om hur vi hanterar utseendet på sajten.

Tänk före

När man normalt bygger webbplatser så lägger vi stor vikt vid att tänka igenom hur vi bygger, strukturerar och upprätthåller strukturen för kodhanteringen i utvecklingsprojektet. Men det som nästan alltid händer är att när vi kommer till utsidan så skriver vi vår css-kod på ett hafsigt sätt, vilket ofta leder till en css-fil som ganska snabbt börjar lukta illa, vi har alla varit där. För små projekt funkar det kanske, men inte för vår komplexa och dynamiska webbplats.

På kth.se började vi redan för flera år sedan ett jobb med att strukturerar upp vår css, så att vi enkelt skulle kunna veta var en css-regel är definierad, ett jobb som vi verkligen sparat in mycket tid och tagit bort många buggar.

Men innan jag börjar beskriva det behöver du få en grundläggande förståelse för hur vi jobbar med innehållet på sajten.

Vi har egentligen tre typer av delkomponenter på sidan, avdelningar, artiklar och innehållsblock. Avdelningar har två jobb, dels att vara egna sidor, så som KTH:s startsida, eller att vara hållare för en artikel. Du kan jämföra med den här bloggens startsida (avdelning), och ett inlägg (avdelning med artikel i sig). Det som gör vår implementation lite speciell är att vi även har något som vi kallar block. Ett block är t ex en bild, länk, puff eller film, eller sammansättningar av anda block. De funkar lite som widgets i WordPress med med den skillanden att de kan ligga var som helst, i en artikel, eller som del på t ex en startsida. Gemensamt för block är att de är innehållselement som man vill kunna återpublicera på olika ställen på webben. En puff som används på startsidan för att informera om en konferens, kanske man vill ska visas i samband med kalendern också.

Speciellt för oss är att till skillnad från vanliga sajter som har en enkelt upplägg där man skriver  en text och den har ett visst syfte, har vi ett mycket mer dynamiskt upplägg. Vi vet egentligen inte vad något på sidan är och vad det ligger i. En bild kan ligga i en puff som ligger i en lista som ligger i en artikel, samtidigt som samma bildobjekt ligger i ett bildspel på startsidan. Den friheten för våra redaktörer gör också att vi inte kan skriva css lite hur som, då har vi plötsligt en djungel av css, och det vill vi inte ha så klart. Vi måste ha en tanke. Varje objekt måste kunna visas snyggt oberoende av var det presenteras.

Vår implementation

Det viktigaste i vår arkitektur är att varje element inte känner till sin egen context och inte påverkar ytor utanför sig själva. Med det menar jag att om en puff ligger på vår startsida är det inte puffen som bestämmer hur mycket marginal det ska vara till nästa puff utan det som puffen ligger i. Varje element bestämmer inom sig själv hur element inom elementet ska hanteras men inte åt andra håller. För att tala css menar jag att alla element som redaktören kan hantera har padding: 0px, margin: 0px; Det normala är också att element så som block alltid spänner över 100% bredd. Återigen eftersom det inte är blocket som bestämmer hur context ser ut. Det gör det blocket ligger i.

Block
Den minsta delen av en webbsida som vi hanterar så som puffar, bilder, länkar. Block har ingen padding och ingen marginal. Ett block vet inget om sin context där där är publicerad, blocket måste därför kunna rita ut sig själv oberoende av utrymme eller plats på webbsidan.

block

Slot
Delar av sidor så som sidhuvud, artikelytan eller kommentarsdel. Slot:ar hanterar oftas block inom sig och bestämmer då hur mycket marginal det ska vara mellan olika block inom slot:en.

slot

Page
Grundläggade css som rör hela sidor, främst avdelningar. Bestämmer hur mycket marginal det ska vara mellan olika slot:ar

page

 

Site
Den högsta nivån i arkitekturen, om det inte är en vanligt KTH-sida, med KTH:s normala design. På site nivå sätter vi då en css-klass på body-taggen, se t ex vår personaltidning Campi. En sajt har oftast sin egen .css-fil. Dock har alla css-filer för respektive sajt samma grundläggande css som kommer från samma 120 page, slot och blocks-filer.

site

Less ger oss mycket mer

En av de viktigaste verktygen för oss är pre-kompilatorn Less som gör css mer lättanvänt. Less ger möjligheter som likar de man har vid programmering. Du får variabler och funktioner, väldigt begränsat men ändå. Vi har för tillfället ca 120 st less-filer. Förutom att ha filer för variabler (färger, text-storlekar, radavstånd …) och funktioner. Har varje element sin egen less fil, och det är viktigt för då vet vi att reglerna för elementet puff ligger i puff.less – ingen annans stans. Jag vet också att även om min kollega jobbar med startsidan kommer han inte att ändra hur puffar ser ut där. Behöver jag specialbehandla utseendet för ett element, så som puff på startsidan gör vi det också i puff.less, lika så ligger specialregler för responsive design i samma fil.

Här har ni ett exempel på hur less-filen för ett block ser ut, men strukturen ser lika ut för page, slot och site.

// default style for element
.block.teaser {
  .noSpacing;
  .teaserText {
    color: @blue;
  }
}

// overrides for specific context
.startDepartment {
  .block.teaser {
    .teaserText {
      color: @red;
    }
  }
}

// responsive design 
@media only screen and (max-width: @iPadLandscape) {
  .block.teaser {
    .fontSize(15);
  }
}

Så du har tagit dig hela vägen hit, bra jobbat! Har du frågor svara vi gärna på dom!

 

 

 

Lämna ett svar

E-postadressen publiceras inte. Obligatoriska fält är märkta *