继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Svelte 最新中文文档教程(13)—— 样式

冴羽
关注TA
已关注
手记 69
粉丝 78
获赞 269

前言

Svelte,一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1

image.png

Svelte 以其独特的编译时优化机制著称,具有轻量级高性能易上手等特性,非常适合构建轻量级 Web 项目,也是我做个人项目的首选技术栈。

目前 Svelte 基于 Svelte 5 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Svelte,为爱发电翻译了官方文档。

我同时搭建了 Svelte 最新的中文文档站点:https://svelte.yayujs.com ,如果需要辅助学习,也可以入手我的小册《Svelte 开发指南》,语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。

欢迎围观我的“网页版朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。

作用域样式

Svelte 组件可以包含一个 <style> 元素,其中包含属于该组件的 CSS。这些 CSS 默认是有作用域的,这意味着样式不会影响到组件外部的页面元素上。

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

<style>
  p {
    /* 这只会影响本组件中的 <p> 元素 */
    color: burlywood;
  }
</style>

优先级

每个作用域选择器都会因为添加作用域类(例如 .svelte-123xyz)而获得 0-1-0 的优先级增加。这意味着(例如)在组件中定义的 p 选择器会优先于全局样式表中定义的 p 选择器,即使全局样式表是后加载的。

在某些情况下,作用域类必须多次添加到选择器中,但在第一次出现之后,它会以 :where(.svelte-xyz123) 的形式添加,以避免进一步增加优先级。

作用域关键帧

如果组件定义了 @keyframes,名称将会使用相同的哈希方法限定在组件作用域内。组件中的任何 animation 规则也会相应地进行调整:

<style>
  .bouncy {
    animation: bounce 10s;
  }

  /* 这些关键帧只能在这个组件内部访问 */
  @keyframes bounce {
    /* ... */
  }
</style>

全局样式

:global(…)

要在全局范围内为单个选择器应用样式,请使用 :global(...) 修饰符:

<style>
  :global(body) {
    /* 应用于 <body> */
    margin: 0;
  }

  div :global(strong) {
    /* 应用于属于本组件的 <div> 元素内的
       所有 <strong> 元素,无论这些 <strong>
       属于哪个组件 */
    color: goldenrod;
  }

  p:global(.big.red) {
    /* 应用于属于本组件的所有带有
       `class="big red"` 的 <p> 元素,
       即使该类是以编程方式添加的(比如通过库) */
  }
</style>

如果你想创建全局可访问的 @keyframes,你需要在关键帧名称前加上 -global-

编译时 -global- 部分会被移除,然后在代码的其他地方可以直接使用 my-animation-name 来引用该关键帧。

<style>
  @keyframes -global-my-animation-name {
    /* 代码写在这里 */
  }
</style>

:global

要将样式全局应用于一组选择器,可以创建一个 :global {...} 块:

<style>
  :global {
    /* 应用于你应用中的每个 <div> */
    div { ... }

    /* 应用于你应用中的每个 <p> */
    p { ... }
  }

  .a :global {
    /* 应用于属于本组件中 .a 元素内的
       任何组件中的所有 `.b .c .d` 元素 */
    .b .c .d {...}
  }
</style>

[!NOTE] 上面的第二个示例也可以写成等效的 .a :global .b .c .d 选择器,其中 :global 之后的所有内容都是未限定作用域的,不过更推荐使用嵌套形式。

自定义属性

你可以将 CSS 自定义属性(静态和动态的)传递给组件:

<Slider
  bind:value
  min={0}
  max={100}
  --track-color="black"
  --thumb-color="rgb({r} {g} {b})"
/>

上面的代码本质上会被转换成这样:

<svelte-css-wrapper style="display: contents; --track-color: black; --thumb-color: rgb({r} {g} {b})">
  <Slider
    bind:value
    min={0}
    max={100}
  />
</svelte-css-wrapper>

对于 SVG 元素,它会使用 <g> 替代:

<g style="--track-color: black; --thumb-color: rgb({r} {g} {b})">
  <Slider
    bind:value
    min={0}
    max={100}
  />
</g>

在组件内部,我们可以使用 var(...) 来读取这些自定义属性(并提供后备值):

<style>
  .track {
    background: var(--track-color, #aaa);
  }

  .thumb {
    background: var(--thumb-color, blue);
  }
</style>

你不必须直接在组件上指定这些值;只要自定义属性在父元素上定义,组件就可以使用它们。通常在全局样式表中的 :root 元素上定义自定义属性,这样它们就可以应用于整个应用程序。

[!NOTE] 虽然额外的元素不会影响布局,但它影响任何使用 > 组合器来直接定位组件容器内元素的 CSS 选择器。

<style> 元素

每个组件只能有一个顶级 <style> 标签。

然而,可以在其他元素或逻辑块内嵌套 <style> 标签。

在这种情况下,<style> 标签将按原样插入到 DOM 中;不会对 <style> 标签进行任何作用域限制或处理。

<div>
  <style>
    /* 这个 style 标签将按原样插入 */
    div {
      /* 这将应用于 DOM 中的所有 `<div>` 元素 */
      color: red;
    }
  </style>
</div>

Svelte 中文文档

本篇已收录在掘金专栏 《Svelte 中文文档》,该系列预计 40 篇。

系统学习 Svelte,欢迎入手小册《Svelte 开发指南》。语法篇、实战篇、原理篇三大篇章带你系统掌握 Svelte!

此外我还写过 JavaScript 系列TypeScript 系列React 系列Next.js 系列冴羽答读者问等 14 个系列文章, 全系列文章目录:https://github.com/mqyqingfeng/Blog

通过文字建立交流本身就是一种缘分。欢迎围观我的“网页版朋友圈”、加入“低调务实优秀中国好青年”前端社群,分享技术,带你成长。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP