Search code examples
csssveltesveltekit

How to use media queries in Svelte?


I'm using svelte-kit and I'm quite new to it. On my +page.svelte file, I got:

<script lang="ts">
    const { data } = $props();
</script>

where I'm using data to display a hero image.

<div
    class="h-screen w-full bg-cover bg-no-repeat hero-section"
    style={`background: 
            linear-gradient(180deg, rgba(0, 0, 0, 0.50) 0%, rgba(0, 0, 0, 0.00) 22.16%), 
            linear-gradient(270deg, rgba(0, 0, 0, 0.00) 38.11%, rgba(0, 0, 0, 0.50) 99.84%), 
            url(${data.meta.HeroImage.Source}) lightgray 50% / cover no-repeat;
    `}
></div>

and I want to have different placement of gradient for the mobile screens, let say:

<style>
    @media (max-width: 640px) {
        .hero-section {
            background-image: linear-gradient(0deg, rgba(0, 0, 0, 0) 76.81%, rgba(0, 0, 0, 0.5) 99.83%),
                linear-gradient(180deg, rgba(0, 0, 0, 0) 48.56%, rgba(0, 0, 0, 0.8) 100%),
                url('');
        }
    }
</style>

but as inline background-image overwrites the styles, I could not find a way to make it work. So, question would be, how is it possible in Svelte to use media queries for different screens with dynamic image URL?


Solution

  • You can pass the background image url to CSS using a CSS variable:

    <div
      class="hero-section h-screen w-full bg-cover bg-no-repeat"
      style:--background-image-url="url({data.meta.HeroImage.Source})"
    ></div>
    
    <style>
      .hero-section {
        background:
          linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 22.16%),
          linear-gradient(270deg, rgba(0, 0, 0, 0) 38.11%, rgba(0, 0, 0, 0.5) 99.84%),
          var(--background-image-url) lightgray 50% / cover no-repeat;
      }
      @media (max-width: 640px) {
        .hero-section {
          background-image:
            linear-gradient(0deg, rgba(0, 0, 0, 0) 76.81%, rgba(0, 0, 0, 0.5) 99.83%),
            linear-gradient(180deg, rgba(0, 0, 0, 0) 48.56%, rgba(0, 0, 0, 0.8) 100%),
            var(--background-image-url) lightgray 50% / cover no-repeat;
        }
      }
    </style>