🚀 Быстрый совет по Svelte: стилизуйте содержимое слота с помощью :global

Эта статья изначально была опубликована на моей странице Dev.to

👋 Привет, мир!

Вот пикантный 🌶 Быстрый совет для вас, надеюсь, вам понравится 🤩

Вы когда-нибудь сидели и чесали затылок, спрашивая: «Как мне избавиться от этой проклятой маржи в моем <slot> контенте?» или какая-то другая проблема со стилем слотов?

Ну, я знаю, что у меня есть, так что, может быть, у вас тоже? 🧐

Проблема

Допустим, у вас есть компонент <Box>, в который вы передаете контент, и иногда этот контент имеет поля, которые вам действительно не нужны. Вы бы предпочли, чтобы ваш компонент box удалял поля содержимого, которое передается ему, независимо от того, каким может быть это содержимое.

Что ж, поскольку Svelte по умолчанию привязывает стили к компоненту, это не так просто, как может показаться на первый взгляд.

Компонент

Итак, предположим, что ваш симпатичный компонент <Box> выглядит примерно так:

<!-- Box.svelte -->
<section>
  <slot></slot>
</section>
<style>
  section {
    background: PaleTurquoise;
    padding: 1rem;
  }
</style>

Теперь предположим, что вы используете его примерно так:

<!-- App.svelte -->
<script>
  import Box from "./Box.svelte"
</script>
<Box>
  <p>This paragraph should not have a top margin!</p>
  <p>This is a paragraph with top and bottom margins</p>
  <p>This paragraph should not have a bottom margin!</p>
</Box>
<style>
  p {
    margin: 2rem 0;
  }
</style>

Теперь, когда вы визуализируете это, вы видите что-то вроде этого, что на самом деле не то, что вы хотели:

Ты смотришь на это чудовище, выкрикиваешь какие-то ругательства 🤬 и думаешь, как, черт возьми, ты собираешься исправить эту ситуацию.

Что ж, не бойся, дорогой читатель, ибо ты наткнулся на решение своей экзистенциальной боли и страдания!

Решение

Решение простое и элегантное; мы будем использовать модификатор :global в нашем <Box> CSS для удаления верхнего/нижнего полей.

Вот как мы собираемся это сделать, просто добавьте эти два правила в ваш CSS для Box.svelte вот так:

section :global(> :first-child) {
  margin-top: 0;
}
section :global(> :last-child) {
  margin-bottom: 0;
}

Теперь вы должны увидеть свой компонент <Box> во всей его красе без отступов!

🎉 Ура!! Мы сделали это! Настоящий переломный момент, я знаю!

Это создаст некоторые стили, которые по-прежнему привязаны к компоненту:

Вы увидите, что стиль абзаца переопределяется стилем :first-child, потому что он более «конкретный», что позволяет вам применять стили к содержимому слота, а также переопределять любые стили, которые вам нужны в родительском компоненте.

Круто правда!? 🤓

Последний компонент

Вот наш компонент во всей красе:

<section>
  <slot></slot>
</section>
<style>
  section {
    background: PaleTurquoise;
    padding: 1rem;
  }
  section :global(> :first-child) {
    margin-top: 0;
  }
  section :global(> :last-child) {
    margin-bottom: 0;
  }
</style>

Проверьте Svelte REPL здесь, чтобы поиграть с этим.

🎬 Плавник

Вы также можете использовать модификатор :global, чтобы делать много других интересных вещей, это всего лишь один конкретный пример, чтобы заставить ваш мозг работать 🧠

Спасибо, что дочитали до сих пор 🙏, надеюсь, вам понравилось!

Есть другие советы, идеи, отзывы или исправления? Дай мне знать в комментариях! 🙋‍♂️

Вы можете найти меня в Twitter (@danawoodman) или Github (danawoodman)

Фото автора Joshua Aragon на Unsplash