Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Svelte facilitate dynamic CSS styling?

Tags:

svelte

In Svelte, how should classes be changed on elements depending upon component state?

For instance, you may wish to apply a class to a button under certain conditions, as in the following example.

<button class="{{class}}">

Right now, this can be achieved by creating a computed property which would return class names, or empty strings, under certain conditions.

However, I am concerned over whether this might be polluting the computed properties namespace. For instance, if there were a status, it might be desired to both set a dynamic text, like statusMessage, and a class, like statusClass.

Is there a better way to do this, or are computed properties the way to go? Is any more explicit support for CSS planned for Svelte?

like image 414
Chris Talman Avatar asked Jul 26 '17 10:07

Chris Talman


3 Answers

Today you can use:

export let whitetext = false;
<div class:whitetext></div>

and then

<MyComponent whitetext={true} />

syntax for simple true/false based classes.

like image 117
wiktus239 Avatar answered Oct 23 '22 16:10

wiktus239


You can use an inline expression, like so:

<button class='{{active ? "active": "inactive"}}'>
  {{active ? 'Selected' : 'Select this'}}
</button>

That's generally better than using a computed property, because it's immediately clear what the possible values are just by looking at the template.

You can also use helper functions, if the expression would become unwieldy — in some situations you might prefer these to computed values:

<button class='{{getClass(status)}}'>{{getText(status)}}</button>

<script>
  export default {
    helpers: {
      getClass(status) {
        // ...
      },
      getText(status) {
        // ...
      }
    }
  };
</script>
like image 13
Rich Harris Avatar answered Oct 23 '22 16:10

Rich Harris


There's no inbuilt way to do use, eg, conditionals {#if} inside class=, per other popular frameworks.

Since inline expressions will become unweildy as soon as you have more than two classes, I'd go stright to helpers in that case. Quick example of a class builder helper:

helpers: {
    getSlideClasses(index, currentIndex) {
        let classes = ['js_slide']
        if ( index === currentIndex ) {
            classes.push('selected')
        }
        if ( index === 0 ) {
            classes.push('first')
        }
        return classes.join(' ')
    }
}

And then:

<div class='{ getSlideClasses(index, currentIndex)}'>
like image 3
mikemaccana Avatar answered Oct 23 '22 18:10

mikemaccana