Svelte系列 --- 样式

2,825 阅读1分钟

Svelte 在操作样式类方面与 Vue 较为接近,是直接内置了对样式类操作的支持,不过没有 Vue 支持得那么强大。

样式类

<!-- 设置样式类和其他属性一样 -->
{#each ['foo', 'baz', 'bar'] as value}
    <button
	class="{current === value ? 'selected' : ''}"
	on:click="{() => current = value}"
    >
	{value}
    </button>
{/each}
<!-- 上述的书写方式有一种简写方式 -->
{#each ['foo', 'baz', 'bar'] as value}
    <button
        class:selected="{current === value}"
        on:click="{() => current = value}"
    >
       {value}
    </button>
{/each}
<script>
  let value = 0
</script>

<!-- 简写方式不仅仅局限于selected,checked属性, 别的属性也可以使用 -->
今天收入:<input bind:value class:error={isNaN(Number(value))} />

<style>
  .error { border: 1px solid red; }
  input { outline: 0 none; }
</style>

class 简写

<!-- 原始写法 -->
<div class:big={big}>
  <!-- ... -->
</div>

<!-- 如果样式名和变量名同名,可以简写 -->
<div class:big>
  <!-- ... -->
</div>

CSS自定义属性

也就是在css中使用变量,在一定程度上实现了css in js, 这在一键给网页换肤的时候十分有用

这是 v3.38.0 新增的功能

<script>
  let color = 'red';
</script>

<style>
  .btn {
    color: var(--color); /* 使用变量值 */
    border: 1px solid var(--color);
    padding: 3px;
  }
  
  .button {
    color: var(--color);
    border: 1px solid #ccc;
    padding: 3px;
  }
</style>

<!--
  定义局部变量值 
  这个变量`--color`只能在`class`为`btn`的`span`标签的样式设置中使用 
-->
<span class="btn" style="--color: {color}">按钮</span>

<!-- 在这个span中,是没有--color这个变量的,所以color样式并不会生效 -->
<span class="button">button</span>
<!-- 父组件 -->
<script>
  import Btn from './Btn.svelte'
	
  let color = 'blue'
</script>

<!-- 将样式变量传递给子组件 -->
<Btn --color={color} />

<!-- 子组件 -->
<style>
  .btn {
    /* 
      对于样式变量(所有以--开头的变量) 
      svelte的子组件可以直接使用,而不用使用export关键字接收
      如果父组件并没有传递过来这个样式变量,那么这个样式不会生效,但不会报错
    */
    color: var(--color);
    border: 1px solid var(--color);
    padding: 3px;
  }
</style>

<span class="btn">按钮</span>
<!-- 父组件 -->
<script>
  import Btn from './Btn.svelte'
  let color = 'red';
</script>

<style>
  .btn {
    color: var(--color);
    border: 1px solid var(--color);
    padding: 3px;
  }
</style>

<div class="btn" style="--color: {color}">
	<Btn />
</div>

<!----------------------------------------------->

<!-- 
  父组件中定义的变量--color会一直往下传,包括子组件和孙子组件 
  所以CSS 变量会破坏 Svelte 组件局部作用域的特性,使用需要谨慎
-->

<!-- 中间组件 Btn.svelte -->
<span class="btn">
	<Button />
</span>

<script>
  import Button from './Button.svelte'
</script>

<style>
  .btn {
    color: var(--color);
    border: 1px solid var(--color);
    padding: 3px;
  }
</style>

<!----------------------------------------------->

<!-- 子组件 Button.svelte -->
<style>
  .btn {
    color: var(--color);
    border: 1px solid var(--color);
    padding: 3px;
  }
</style>

<span class="btn">按钮</span>

全局样式

<style> 块中的 CSS,其作用域受限于该组件。

这是通过向元素添加一个类来实现的,该类基于组件样式的哈希值而生成的(例如 svelte-123xyz)。

也就是如果多个组件内容是类似的时候,生成的样式的哈希值可能会是一致的

<style>
  p {
    /* 这仅对本组件的 <p> 元素有效果 */
    color: blue;
  }
</style>
<style>
  :global(body) {
    /* 这个样式就是全局的 */
    margin: 0;
  }

  div :global(strong) {
    /* 这将适用于任何组件中属于该组件的<div>元素内的所有<strong>元素 */
    color: goldenrod;
  }
</style>
<style>
  /*
    要使 @keyframes 可以被全局访问,则需要在关键帧名称前添加 -global- 前缀。
    编译时,将自动移除 -global- 部分,然后仅使用代码的其他部分的 my-animation-name 来引用关键帧。
  */
  @keyframes -global-my-animation-name {...}
</style>