Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I set svelte style css attribute values using variables passed in to a component

Tags:

syntax

svelte

I want to create a svelte component that receives the name and path of an image. I want to have the component set the image as the "background-image" using CSS.

I've tried the following which does not seem to work...

Component called in App.svelte:

<Image image_url='./images/image1.jpg' />

Image.Svelte

<script>
export let image_url;
</script>

<style>
.image{
    position:relative;
    opacity: 0.70;
    background-position:bottom;
    background-size: cover;
    background-repeat: no-repeat;
    background-attachment: fixed;
    background-image: url({image_url});
    min-height: 100%;
}
</style>

<div class="image">
  <p>some text</p>
</div>

When I inspect the component the css for background_image is:

background-image: url({image_url});

Is it possible to have the variable converted in the CSS?

like image 529
bejames Avatar asked Jul 24 '19 02:07

bejames


People also ask

Can CSS pass variables?

The var() function is used to insert the value of a CSS variable. CSS variables have access to the DOM, which means that you can create variables with local or global scope, change the variables with JavaScript, and change the variables based on media queries.

What is $$ in Svelte?

Svelte will generate the code to automatically update them whenever data they depend on is changed. Note: Svelte uses the $: JavaScript label statement syntax to mark reactive statements.

How do you specify variables in CSS?

To declare a variable in CSS, come up with a name for the variable, then append two hyphens (–) as the prefix. The element here refers to any valid HTML element that has access to this CSS file. The variable name is bg-color , and two hyphens are appended.

What does $: mean in Svelte?

3. $: marks a statement as reactive. Any top-level statement (i.e. not inside a block or a function) can be made reactive by prefixing it with the $: JS label syntax. Reactive statements run after other script code and before the component markup is rendered, whenever the values that they depend on have changed.


1 Answers

No. Component styles are shared between all instances of a component, either because they're statically extracted to a .css file, or because they're injected into a single <style> element that all components reference. If it were possible to put variables directly inside the component's <style>, it would mean that Svelte would need to create encapsulated styles per-instance, which would be detrimental to performance and would consume a lot more memory.

There are two ways to approach this. The first is to use inline styles for anything that can change per-instance:

<script>
export let image_url;
</script>

<style>
.image{
    position:relative;
    opacity: 0.70;
    background-position:bottom;
    background-size: cover;
    background-repeat: no-repeat;
    background-attachment: fixed;
    /* background-image: url({image_url}); */
    min-height: 100%;
}
</style>

<!-- <div class="image"> -->
<div class="image" style="background-image: url({image_url});">
  <p>some text</p>
</div>

The second, particularly if you need to use values in multiple places, is to use CSS variables:

<script>
export let image_url;
</script>

<style>
.image{
    position:relative;
    opacity: 0.70;
    background-position:bottom;
    background-size: cover;
    background-repeat: no-repeat;
    background-attachment: fixed;
    /* background-image: url({image_url}); */
    background-image: var(--image);
    min-height: 100%;
}
</style>

<!-- <div class="image"> -->
<div class="image" style="--image: url({image_url});">
  <p>some text</p>
</div>
like image 57
Rich Harris Avatar answered Oct 05 '22 22:10

Rich Harris