En gjennomgang av kodeløsningene vi har valgt når vi bygger nettsider som skal virke på flere ulike skjermer.
Vi som bygger nettsidene til nrk.no blir ofte bedt om å dele tips og tricks. Så her er en gjennomgang – med kodeeksempler – av hvordan vi får samme nettside til å passe både for mobiler, brett og PCer – såkalt responsiv design – med spesiell fokus bildeskalering.
Bakgrunn
Etter at Internet Explorer gikk seirende ut av nettleserkrigen med Netscape rundt årtusenskiftet, tenkte mange utviklere at problemene rundt konkurrerende standarder og vanvittige hacks var løst en gang for alle. Mange husker nok fortsatt den tidstypiske merkelappen “denne siden vises best i Internet Explorer, med optimal skjermstørrelse på 1024×768″.
Det ble dessverre en kortvarig glede. Utover 2000-tallet dukket det opp nye populære konkurrenter som Mozilla Firefox og Opera, som gav raskere nettsider og ny spennende funksjonalitet. Dessuten fikk jo folk stadig større og større skjermer – med helt andre formfaktorer enn “normalen».
Adaptiv design etablerte et svar på denne utfordringen, der serveren ble satt til å detektere hva slags nettleser og enhet som ble brukt, for deretter å levere separate løsninger for ulike typer enheter. For øvrig var filosofien den samme som før, at alle brukere med “normalutstyr» skulle få en likest mulig brukeropplevelse.
Mobile brukere ble “skjermet» for unødvendige valg og tilsynelatende irrelevant innhold. Når det første tiåret etter århundreskiftet nærmet seg slutten, slo rådende designfilosofi sprekker på ny. Brukere av Apples iPhone, og senere Googles Android, var ikke tilfreds med nedstrippede mobile nettsider. De ønsket tilgang til alt innholdet, selv om det innebar mye zooming og sveiping på små skjermer med svak hardware og svært variabel nettkapasitet.
Ethan Marcott lanserte begrepet “Responsiv design» i 2010 som en samling teknikker og designfilosofi for å bøte på nettopp dette. I en verden med stadig flere nettleserversjoner, ulike skjermstørrelser, inndata- og navigasjonsmetoder foreslo han å gå tilbake til én løsning for alle nettbrukere – som omfavner forskjellene, i stedet for å kjempe imot dem. Samme innhold leveres til alle. Innholdet brekkes om og tilpasses den teknologien som brukeren har for hånden.
I praksis betyr det at en grafisk designer ikke lenger kan levere fiks ferdige photoshopskisser, uten å ha tenkt gjennom hvordan innholdet skalerer og brekkes om. Som utvikler kan man ikke lenger programmere ferdig en nettside uten å snakke med designeren underveis. Responsiv design har kastet pixelperfeksjonisme på dynga, og åpnet for et internett som kan nytes på enhver skjerm med nettleser og internettilkobling. Den mobile weben antas å passere desktopbruk i løpet av får år. Utviklere oppfordres derfor å jobbe etter prinsippet «mobile first», et uttrykk lansert av Luke Wrobelski, som uttrykk for denne endringen.
Minstekrav til responsive nettsider
For utviklere involverer “hei verden»-eksemplet for responsive nettsider et dykk ned i teknologien med navn “media queries» – en del av CSS3-spesifikasjonen. Her kan utvikleren angi ulike grupper av css-regelsett basert på egenskaper som skjermbredde, pixeltetthet, landskap- eller portrettmodus m.fl.
Dernest trenger utvikleren å bruke en såkalt flytende layout. Det vil si at alle elementer defineres som prosenter av bredden på det elementet den er et barn av, ikke i et absolutt antall pixels som man gjerne gjorde før. Legg for øvrig merke til at nettlesere har ganske god støtte for strekking og interpolering av bilder, slik at bildet nedenfor vil vises i best til tilpassede størrelse.
Til slutt trenger man å legge til en metatag som sier definerer at 100% bredde er det samme som skjermbredden.
So far, so good – for det er nå de ulike problemstillingene virkelig dukker opp: Hvordan skal man brekke om en flerkolonne-layout til én kolonne på mobil? Hvordan brekker man om en bred tabell til en smal skjerm? Hvordan skal man bygge interaksjon med swipe og samtidig støtte navigasjon med mus? Det finnes en rekke problemstillinger, som bl.a. har vært omtalt her på NRKbeta tidligere – og løsningsforslag. Et av de større hindrene man støter på er knyttet til bilder, noe resten av denne artikkelen vil handle om.
Responsive bilder
Årsaken til at bilder utgjør et helt spesifikt problemområde, er at et enkelt bilde kan utgjøre større kilobytevekt, enn resten av HTML, CSS og Javascript for øvrig. På den annen side ønsker man ikke å levere bilder av lav kvalitet til brukere med store flotte skjermer og kraftig bredbånd. Det finnes enn så lenge ingen standardisert måte å løse dette på, så her må man som regel lete litt rundt på nettet eller lage noe selv.
Måling av skjermstørrelse + cookies
Filament group var tidlig ute med å lansere responsive design for bl.a. Boston Globe. Bildene ble lastet ved hjelp av en teknikk der skjermbredden måles vha. javascript i toppen av responsen, for deretter å sette en cookie som kunne leses av bildeserveren etterpå og levere bilder med ulike størrelser. Det viste seg at denne løsningen ikke var god nok, da nettlesere som Chrome, Safari og Firefox bruker en optimaliseringsteknikk kalt spekulativ parsing, som bl.a. leter etter bilder og starter nedlasting av disse før javascript og uttegning starter.
Nytt <picture>-element + polyfill
Scott Jehl, en av utviklerne fra Filament group, har foreslått et nytt -element for å løse problematikken . Elementet har flere likhetstrekk med <iframe>, <audio> og <video>-elementenesom angir et fallbackinnhold; i dette tilfellet en vanlig >img>-tag. Ellers benyttes media queries få å bestemme hvilken url som skal lastes ned.
Ettersom ingen nettlesere støtter denne spesifikasjonen enn så lenge, har han laget en polyfill som kan brukes i dag. Helt problemfritt er det dog ikke, her er noen problemstillinger:
- Dersom man bruker markup-en ovenfor, må alle brukere laste ned to versjoner av samme bilde; først den dårligste, deretter den som er angitt av picture-elementet
- Dersom man plasserer fallback-bildet i en noscript-tag, vil brukeren oppleve at nettsiden “hopper og danser” når bildene lastes inn
- Det er en ganske ganske massiv markup som skal til og det bryter mot prinsippene om å holde innhold, logikk og presentasjon adskilt.
- Mediaqueries tar utgangspunkt i skjermbredde, mens bildene som skal lastes relativt sjelden fyller hele skjermen. Dette fører til at nettleseren laster større bilder enn strengt tatt nødvendig.
Business as usual, men alternativer for retinaskjerm
Apple har tradisjon for å lage nye standarder der de det ikke finnes noen fra før – eller de mener at eksisterende standarder er utilstrekkelige. Første generasjons iPod, iPhone og iPad kan hevdes å være blant de mest suksessrike; kabelstandarder og proprietære formater kanskje mer omdiskuterte. Etter at Apple lanserte høyoppløselige retinaskjermer var de selvsagt interessert i at websider med grafikk var like skarpe som andre elementer bestående av vektorgrafikk. Derfor introduserte de et nytt forslag til standard som legger til et ekstra attributt til bildetagen.
Denne løsningen er mer kompakt enn forslaget med et nytt -element og introduserer ingen ny unødvendig semantikk. På den annen side brukes ikke-standardiserte media-queries for å velge bilde. Det tas heller ikke hensyn til hvilken plass bildet faktisk fyller på skjermen – de fleste bilder fyller sjelden hele skjermbredden.
Måling av bildebredde + base64-placeholder
Da vi skulle lage en løsning for responsive bilder på nrk.no ønsket vi å lage en løsning som kombinerte de ovenstående metodene. Vi satte oss følgende mål:
- Unngå å laste bilder dobbelt
- Ikke laste større bilder enn nødvendig
- Søkemotorsynlighet
- Forhindre at nettsiden “hopper” mens siden laster
- God semantisk struktur
- Adskilt innhold, presentasjon og programlogikk
Markupen nedenfor er et forenklet eksempel. For ekte eksempler, velg en side under f.eks. nrk.no/sport og klikk “view source».
Det første vi gjør er å sørge for semtantisk korrekt markup, ved å nøste bilde og bildetekst sammen med html5-elementene figure og figcaption. Dernest tegner vi ut et placeholderbilde kodet i base64. Dette er et transparent skalert gif-bilde med samme bredde-/høydeforhold som det reelle bildet (f.eks. 16:9, 3:4 el.). Når bildet på et senere tidspunkt byttes med vha litt inline javascript, forhindrer dette at nettsiden “hopper». For besøk fra kilder uten Javascript-støtte, deriblant søkemotorer, leverer vi en mediumstørrelse inne i en noscript-tag. For å unngå at reelle brukere uten javascript skal se et blankt bilde over det vanlige bildet, har vi lagt til følgende snutt i
Selve bildeskiftingen skjer i et funksjonskall som måler bredden på hvert enkelt bilde som skal lastes. Dette krever heldigvis intet massivt bibliotek, annet enn et server-api for justering av bildestørrelser.
Funksjonen getBestCrop er en hjelpefunksjon som finner beste cropid for en gitt bildeid. Bak URL-en http://gfx.nrk.no har vi implementert en tjeneste som leverer utsnitt og variable størrelser (cropId) av høyoppløste bilder (id). Selv om id-ene er krypterte, kunne man ha brukt en annen bildeskaleringsteknologi for å gjøre det samme.
Dersom brukeren endrer størrelsen på skjermen, lytter vi på resize-eventer slik at vi kan laste bedre versjoner av bildet f.eks. når brukeren vipper enheten fra stående til liggende modus.
Men hva med Internet Explorer?
Artikkelen kan gjerne avslutte der den startet. Internet Explorer satte standarden rundt årtusenskiftet, og den gjør det til en viss grad fortsatt.
Heldigvis har Microsoft fått opp farten med å rulle ut nye versjoner. Likevel er det utallige brukere der ute som fortsatt benytter IE7 og IE8. Selve fundamentet bak responsive nettsider, media queries, støttes først fra IE9.
Heldigvis finnes det gode biblitoteker for å simulere media queries også i disse eldre arbeidshestene, dog til en viss pris. Nettsidene blir generelt tregere, og man kan også gå glipp av andre nyttige teknologier (f.eks. flexbox, border-box, pseudoselectorer mfl). Et rammeverk som heter Modernizr er i den sammenheng svært nyttig, da man kan “velge bort» teknologier som nettleseren ikke støtter, og istedet lage alternativer. Så lenge kjernefunksjonaliteten beholdes.
Hva tenker dere om responsive nettsider generelt og responsive bilder spesielt?
Jens Christian
Veldig positiv til dette, og er strengt tatt overrasket over at så mange profesjonelle aktører fortsatt holder seg med nettsider som delvis funker dårlig og delvis ikke funker i det hele tatt på mobil og nettbrett.. (hover-menyer, flash, mm)
Men en annen ting som jeg mener veldig mange webutviklere overser (og som jeg heller ikke kunne se at dere nevner), er det faktum at mange på desktop ikke ønsker å bruke fullt skjermareal. Input-data for valg av visning burde være hvor stort _nettleservinduet_ er, ikke skjermoppløsningen. Hvorfor tvinger brukerne til å kjøre nettsider i fullskjerm?
(undersøkelser av hvordan de fleste bruker nettleseren blir i denne sammenhengen lite relevant, ettersom brukerne ofte er nødt til å kjøre fullskjerm for å få en god opplevelse). Høna eller egget kan man si.
Aksel Nordal (NRK)
Hei og takk for positiv kommentar!
Det er riktig som du sier at responsive nettsider også løser brukeres behov for å vise nettsider i ulike vindusstørrelser. Som utvikler må man unngå å gå i fella og anta at liten skjerm er det samme som mobil – og at en stor skjerm ikke har støtte for touch.
Morten Sickel
Helt enig med Jens Christian – og samtidig er det også fint om mobilbrukere har mulighet til å bruke «PC-siden» og motsatt.
Jeg har både vært i situasjone at det er funksjonalitet eller innhold jeg vet finnes på «PC-siden» som jeg ikke finner på mobilsiden eller at jeg sitter med PC på en langsom og/eller dyr linje og gjerne ser en forenklet side.
Men dette er vel stort sett et tilbakelagt stadium:
xkcd.com/869/
Magnus Eide
Hei
Flott artikkel. Har dere tenkt noe på hvordan nettsidene ser ut å store skjermer, alá 50″ TVer. Nå har mobil nettlesning vært mer eller mindre normalt siden 2007, mens TV-browsing, spesielt gjennom spillkonsoller er på full fart inn. Responsiv design egner seg jo egentlig like fult til å skalere opp, som å skalere ned en nettside.
Hadde vært supert om dere kunne skrevet en lignende artikkel om hvordan dere har tatt i bruk bl.a. ajax, HTML5, history APIen på sportssidene.
Vegard Storstad (NRK)
Hei Magnus,
Absolutt – responsiv design bør også kunne deale med større skjermer.
Vi har ikke til nå prioritert de store flatene du nevner. Rett og slett fordi vi har andre uløste oppgaver som må moderniseres – og som gavner et større publikum pt.
Vi har heller ikke rigget tilstrekkelig med utstyr for å håndtere de mange TV-løsningene som tilbyr nettsurfing fra mediasenter eller smarte TV-er, men dette vil nok endre seg.
Noterer ønsket om å høre mer hvordan vi har implementert nrk.no/sport – uten at jeg på stående fot lover bort tid til en artikkel om det 😉
George Gooding
Bra å se at dere jobber med ny kode til artikkelbildene deres! Eksisterende kode kunne nemlig trengt et semantisk løft…
Når det gjelder den responsive biten, føles det veldig feil å bruke Javascript til å få til dette, men som ting er nå har man kanskje ikke så mye valg.
Aksel Nordal (NRK)
Hei George,
helt enig med deg i at semantisk korrekt markup er best 🙂
Vi jobber med å skifte ut den gamle kodebasen med responsive nettsider av typen som beskrevet i artikkelen. Mens du venter på at den gamle markupen skal forsvinne, kan du jo i mellomtiden se på noen av de sidene som er løftet over på ny mal – f.eks. nrk.no/sport, kan du jo se på nrk.no/ytring, nrk.no/direkte, nrk.no/fordypning for å nevne noen
Bølgeskvulp, uke 15 | Making Waves Blogg
[…] NRK deler sine erfaringer med å gjøre sidene responsive […]
Snart ny versjon av Sumo | Du er kanalsjef!
[…] Det grunnleggende prinsippet er at samme innholdet leveres til alle enheter, men visningen av innholdet tilpasser seg enheten som brukes. I stedet for en «pixel perfect» side, brekkes og tilpasses innholdet den PC’en, nettbrettet eller mobiltelefonen som du har for hånden. Du kjenner kanskje allerede prinsippene fra NRK sin nett-TV, som NRK Beta har skrevet en grundig bloggpost om. […]
Joachim Gresslien
Hei,
Takk for en fin artikkel!
Vi jobber med å utvikle et nytt intranett i Orkla, og i den forbindelse sitter vi og klør oss litt i hodet rundt dette med responsivt design og bilder. Vi fant denne artikkelen, og har noen spørsmål knyttet til NRK sine nettsider:
• Forsiden nrk.no oppfatter ikke jeg at er responsiv på samme måte som f.eks. nrk.no/sport og andre seksjonssider. Er det fordi førstesiden også har en unik mobil variant (m.nrk.no) – mens eksempelvis sportssidene ikke har det?
• På seksjonssider som sporten har dere kun tittel – mens på forsiden har dere både tittel og undertitler/ingresser – handler dette også om responsivitet og at det er mer komplisert med mye tekstinnhold i et responsivt design?
• Hvordan sikrer dere at alle bilder vises i samme «ratio» – er det ved å oppgi alle størrelser i prosent? (ingen faste pixler).
• Jeg kan ikke se at dere har noen «portrettbilder» på nrk.no/sport, men dette er det flere av på nrk.no. Har dette også sammenheng med at det er mer komplisert å ha flere ulike «bilderatioer» når nettsiden er responsiv?
• Har dere etablert noen spesifikke brekningspunkter for nettbrett- og i tilfelle for hvilket formål? (meny, spalter, fonter, bokser etc)
Jeg håper dere har muligheten til å gi oss litt mer innsikt i hvordan dere har jobbet med det responsive designet.
Aksel Nordal
Hei Joachim!
Denne artikkelen er et par år gammel, så utfordringene rundt responsive nettsider har heldigvis blitt færre enn før. Forsiden (dvs. nrk.no/) og undersider (f.eks. nrk.no/sport) leveres av to separate systemer, og det er undersidene artikkelen spesielt gjelder. Forsiden er pt. ikke responsiv, men vi jobber med ny løsning slik at den også blir responsiv om ikke altfor lenge.
For å få til responsive bilder vil jeg anbefale deg å ta en titt på picturefill-biblioteket – github.com/scottjehl/picturefill – og lese denne artikkelen ericportis.com/posts/2014/srcset-sizes/ – som tar for seg hvordan alle moderne nettlesere idag støtter responsive bilder vha srcset og sizes-attributter på img-elementet, gjerne i kombinasjon med picture-elementet. Du vil fortsatt måtte legge til rette for å velge ulike utsnitt (portrett/landskap) i flere forskjellige oppløsninger. Dette må du enten gjøre manuelt, eller lage/finne en smart widget som lar brukerne velge fokuspunkt(er) i CMS-et, og som deretter lager flere versjoner av bildene dine automatisk.
Hva angår brekkpunkter vil jeg anbefale deg om ikke å velge noen faste brekkpunkter, men legge inn brekkpunkter der det er naturlig å brekke avhengig av om det er faktaboks, meny eller bilde (f.eks. tekst til høyre for bilde, eller tekst nedenfor). Det er ellers en god idé å optimalisere for visning for de minste skjermene først, og legge på mediaqueries for større skjermer etterpå.
Thomasd
Jeg holder på med en løsning som skal vise nyheter fra NRK på et område på inforskjermer og vi bruker RSS feeden for å hente nyhetene og URL til bilde fra gfx.nrk.no. Bildet jeg får her er mye større enn jeg trenger for å vise feeden på skjermene, er det mulig å be om en mindre versjon fra denne serveren eller må jeg ordne det med et script og caching på egen server?