Skip to content

Alt om WordPress, webutvikling — og mer til

📱 JavaScript: hvordan oppdage skjermbredde, @media-spørring-ekvivalenten i kode

📱 JavaScript: hvordan oppdage skjermbredde, @media-spørring-ekvivalenten i kode

Noen ganger er layouten allerede på plass, CSS-mediespørringer er satt opp, men du trenger å oppdage atferd ved et spesifikt brytepunkt direkte i JavaScript. Å vise en popup bare på mobile enheter, omorganisere et rutenett ved endring av vindusstørrelse, utløse en animasjon når skjermen er «smal»: alt dette krever at skriptet forstår gjeldende vindusbredde.

Problemet er at utviklere ofte tar den tunge ruten: de analyserer window.innerWidth, legger til throttle på resize, sammenligner med magiske tall og ender opp med skjør kode som lever adskilt fra CSS-brytepunktene. Likevel har nettlesere lenge hatt en metode som fungerer med de samme medieuttrykkene som CSS.

Nedenfor finner du tre praktiske tilnærminger: fra den moderne matchMedia (fungerer som @media i CSS) til en jQuery-variant for eldre prosjekter. Med live-eksempler du kan kopiere og kjøre med en gang.

💡 Hurtigoversikt:

  • matchMedia: en innebygd metode som aksepterer et CSS-medieuttrykk og rapporterer om det for øyeblikket matcher; ideell for å synkronisere JS-logikk med CSS-brytepunkter
  • resize + matchMedia: en kombinasjon som reagerer på endringer i nettleservinduet; skriptet får beskjed om kryssing av et brytepunkt umiddelbart, uten periodisk polling av innerWidth
  • jQuery-variant: for prosjekter der jQuery allerede er på siden; samme resize, men uten innebygd matchMedia; sammenligning gjøres via $(window).width()

MatchMedia: den eneste sannhetskilden for skjermbredde

Den største ulempen med window.innerWidth er at den ikke vet noe om CSS-brytepunktene dine. Du setter 768px i mediespørringer, skriver så if (window.innerWidth < 768) i JS, og til slutt ødelegger avrunding eller rullefeltet synkroniseringen.

window.matchMedia() løser dette problemet radikalt: den aksepterer den samme strengen for medieuttrykk som CSS-regelen @media. Resultatet er et MediaQueryList-objekt med en .matches-egenskap (true / false). Ingen magiske tall, ingen mismatch med layouten.

Grunnleggende syntaks:

1const mq = window.matchMedia("(min-width: 768px)");
2
3if (mq.matches) {
4 console.log("Tablet or wider — 768px+");
5} else {
6 console.log("Mobile resolution — less than 768px");
7}

Det samme kallet matchMedia("(min-width: 768px)") evalueres av nettleseren ved hjelp av de samme reglene som @media (min-width: 768px) i CSS. Hvis sidepanelet skjules ved dette brytepunktet i CSS, «ser» JS det samme og kan for eksempel skjule mobilmenyen.

I tillegg til .matches gir MediaQueryList-objektet en .media-egenskap (den opprinnelige spørrestrengen) og en addEventListener-metode for å abonnere på endringer. Dette betyr at når du først har deklarert et brytepunkt i en konfigurasjon, kan du bruke det både i CSS og JS uten å duplisere magiske tall: bare trekk ut 768 til en konstant og sett den inn begge steder.

Reagere på resize uten throttle og workarounds

Å sjekke «akkurat nå» er bare halve jobben. Den virkelige magien begynner når skriptet får beskjed om kryssing av et brytepunkt i det øyeblikket vinduet endres.

MediaQueryList har en change-hendelse som utløses nøyaktig når .matches-verdien veksler. Ikke ved hver piksel under resize, men bare når grensen krysses:

1const mq = window.matchMedia("(min-width: 500px)");
2
3mq.addEventListener("change", function (e) {
4 if (e.matches) {
5 console.log("Screen expanded to 500px or more");
6 } else {
7 console.log("Screen narrowed to less than 500px");
8 }
9});

For bakoverkompatibilitet med eldre nettlesere kan du oppnå samme resultat gjennom en generell resize-handler på window:

1window.addEventListener("resize", function () {
2 if (window.matchMedia("(min-width: 500px)").matches) {
3 console.log("Screen width — at least 500px");
4 } else {
5 console.log("Less than 500px");
6 }
7});
Nettleserkonsoll som viser skjermbreddemeldinger under endring av størrelse

Forskjellen er enkel: changeMediaQueryList er en hendelsesdrevet tilnærming (ingen ekstra kall under resize innenfor et intervall), mens resizewindow er en fallback som er kjent for enhver utvikler.

Breddeintervall: mellom to brytepunkter

En vanlig oppgave er «fra 769px til 1024px». matchMedia fungerer som CSS også her: kombiner min-width og max-width i ett enkelt uttrykk:

1window.addEventListener("resize", function () {
2 if (
3 window.matchMedia("(min-width: 769px)").matches &&
4 window.matchMedia("(max-width: 1024px)").matches
5 ) {
6 console.log("Tablet range: 769px – 1024px");
7 } else {
8 console.log("Outside the tablet range");
9 }
10});

Eller som ett enkelt uttrykk (nettlesere forstår sammensatte mediespørringer akkurat som i CSS):

1const tablet = window.matchMedia("(min-width: 769px) and (max-width: 1024px)");
2
3tablet.addEventListener("change", function (e) {
4 console.log(e.matches ? "Entered tablet range" : "Left tablet range");
5});

Hvilken variant bør du velge? changeMediaQueryList når du trenger å fange det nøyaktige øyeblikket grensen krysses (for eksempel for å omstrukturere DOM-treet). resize + matchMedia når logikken er enklere og du bare trenger å «sjekke nå» uten å abonnere på fremtidige overganger.

JQuery-variant: når matchMedia ikke er tilgjengelig

Hvis prosjektet bruker jQuery og polyfills ikke er et alternativ, oppnås samme resultat ved å sammenligne $(window).width() med en terskelverdi:

1jQuery(document).ready(function ($) {
2 if ($(window).width() > 1000) {
3 console.log("Screen width greater than 1000px");
4 } else {
5 console.log("Screen width 1000px or less");
6 }
7});

Denne koden kjøres én gang ved sideinnlasting. For å spore resize, pakk inn sjekken i en handler:

1jQuery(document).ready(function ($) {
2 function checkWidth() {
3 if ($(window).width() > 1000) {
4 console.log("Width > 1000px");
5 } else {
6 console.log("Width ≤ 1000px");
7 }
8 }
9
10 checkWidth(); // initial run
11 $(window).on("resize", checkWidth);
12});

Men husk: $(window).width() og matchMedia kan avvike med noen få piksler på grunn av rullefeltet. matchMedia jobber med viewporten, akkurat som CSS-regler. Det er derfor jeg anbefaler den innebygde metoden for all ny kode.

MatchMedia vs innerWidth: en kort sammenligning

Kriterium

matchMedia

innerWidth

Synkronisering med CSS

Full (samme uttrykk)

Manuell talljustering

Hendelse ved kryssing av brytepunkt

changeMediaQueryList

Bare resizewindow

Håndtering av rullefelt

Samme som CSS (viewport)

Nettleseravhengig

Mørkt tema / prefers-reduced-motion-deteksjon

Ja (ethvert medieuttrykk)

Nei

⁉️🤔 Ofte stilte spørsmål

Hva er best: matchMedia eller window.innerWidth?

matchMedia er alltid best når logikken er knyttet til CSS-brytepunkter. Den bruker de samme reglene som @media, og eliminerer avvik på en piksel eller to på grunn av rullefeltet eller zoom. innerWidth er bare passende når du trenger den nøyaktige numeriske verdien (for eksempel for å beregne hvor mange elementer som får plass), ikke faktumet «skjerm bredere enn N piksler».

Fungerer matchMedia i eldre nettlesere?

Ja, støtten er bred: alle moderne nettlesere inkludert mobile, og Internet Explorer 10+. IE9 og eldre er forlatt; for dem må du bruke window.innerWidth eller jQuery-varianten fra denne artikkelen. I praksis nærmer andelen IE9 seg null i 2026.

Kan matchMedia sjekke mer enn bare bredde?

Ja, metoden aksepterer ethvert gyldig CSS-medieuttrykk. For eksempel: (orientation: portrait) for enhetsorientering; (prefers-color-scheme: dark) for mørkt tema i operativsystemet; (prefers-reduced-motion: reduce) for en forespørsel om å deaktivere animasjoner. Det fungerer akkurat som i CSS: window.matchMedia("(prefers-color-scheme: dark)").matches returnerer true hvis brukeren har mørkt tema aktivert.

Må jeg fjerne change-handleren når jeg forlater siden?

I moderne kode, nei. Nettleseren rydder minnet automatisk ved sideavlasting. I SPA-er (React, Vue), der en komponent monteres og avmonteres uten sidelasting, må du lagre en referanse til handleren og fjerne den via removeEventListener i componentWillUnmount / onUnmounted; ellers får du minnelekkasjer og gjentatte utløsninger på «døde» komponenter.

Hvorfor viser $(window).width() og matchMedia noen ganger forskjellige bredder?

Fordi de måler forskjellige ting. matchMedia jobber med viewport-bredden (CSS-visningsområdet), den samme som mediespørringer bruker. $(window).width() / window.innerWidth inkluderer bredden på det vertikale rullefeltet, hvis det er til stede. Forskjellen er vanligvis 15-17 px, nøyaktig bredden på rullefeltet. Derav regelen: hvis du knytter logikk til CSS-brytepunkter, bruk matchMedia; hvis du trenger den «sanne» vindusbredden i piksler, bruk innerWidth.

Så hva bør du bruke: den endelige konklusjonen

For ny kode er svaret klart: window.matchMedia(). Den lever i samme kontrakt som CSS-en din, krever ingen manuell talljustering for hvert brytepunkt, og gir en hendelsesmodell av typen «det ble byttet, du vet det» i stedet for konstant breddepolling.

Et typisk scenario der forskjellen merkes umiddelbart: du bygger et produktkort som viser et galleri med fire bilder på desktop, men et sveipbart enkeltbilde på mobil. I CSS har du @media (max-width: 768px) som endrer layouten. I JS, i stedet for if (window.innerWidth <= 768), skriver du matchMedia("(max-width: 768px)"), og nettleseren garanterer at JS-betingelsen utløses nøyaktig når layouten endres. Ingen «nesten som det skulle fungert», ingen feil ved 767px på grunn av rullefeltet.

La jQuery-tilnærmingen med $(window).width() bli igjen for vedlikehold av gamle prosjekter: den fungerer, men tvinger deg til å duplisere brytepunkter i koden og avviker stille fra CSS med bredden på rullefeltet.

Og hvis du vil se alt beskrevet ovenfor i aksjon, her er en 10-minutters veiledning der matchMedia forklares fra kall til hendelsesmodell:

Prøv å erstatte den nærmeste if (innerWidth < 768) med matchMedia("(min-width: 768px)"), så vil du umiddelbart merke hvor mye renere koden blir.