Стилизация того, что находится в элементе слота

Мой запрос странный, так как я использовал другой подход, который полностью сработал и намного более чистый. Однако специалист по SEO позвонил мне и сказал, что моя структура не совсем удобна для роботов Google.

Итак, вот ситуация (пожалуйста, не судите об этом, я знаю, что есть другие способы сделать то, что я пытаюсь достичь, вообще не используя дочерние фрагменты):

Это моя составляющая:

class Container extends LitElement {
  static get tagName() {
    return 'container';
  }

  static get styles() {
    return css`
      ${unsafeCSS(styles)}
    `;
  }

  render() {
    return html`
      <article class="o-container">
        <slot></slot>
      </article>
    `;
  }
}

defineOnce(Container.tagName, Container);

export default Container;

Вот как я его использую:

  <footer>
    <div class="o-footer__collection">
      <div class="o-footer__main">
        <h1 class="o-footer__title-desktop">
          me & me
        </h1>
        <button
          class="o-footer__accordion-button"
        >
          <h1 class="o-footer__title">
            you & you
          </h1>
          <span
            class="o-footer__accordion-button-caret o-footer__accordion-button-caret--open"
          >
            blabla
          </span>
        </button>
        <ul
          class="o-footer__main-content-panel o-footer__main-content-panel--open"
        >
          <li
            class="o-footer__main-content-panel-list-item"
          >
            <a
              href="https://google.com"
              target="_blank"
              >Contact</a
            >
          </li>
        </ul>
      </div>
  </footer>

Видите ли, все эти дочерние элементы попадают в slot область компонента. Изначально эти дочерние элементы были частью компонента и имели стиль. Теперь они вне его, и стили больше не применяются. Кто-нибудь знает, как обойти эту проблему? В документации я обнаружил, что вы можете использовать атрибут css :: slotted (), но, видимо, он не работает. Или я, наверное, еще что-то не так сделал? Я также попытался поместить тег стиля в render html, но это оказало лишь незначительное влияние.

Я не знаю, на каком маршруте мне следует сосредоточиться. Любая помощь приветствуется. ИМХО стиль должен быть частью самого компонента, а не зависеть от того, кто его использует. Но этот элемент слота сломал все, хотя остальная конструкция осталась прежней.


person codepleb    schedule 29.05.2019    source источник
comment
где тег ‹container› и где CSS?   -  person Supersharp    schedule 29.05.2019
comment
И веб-компоненты должны использовать тире в имени своего компонента. container недействителен, но my-container, container-one или special-container в порядке.   -  person Intervalia    schedule 29.05.2019


Ответы (1)


Синтаксис :: slotted будет работать с заявлением об отказе, которое я объясню позже. Если вы хотите, чтобы весь текст внутри тегов p в вашем слоте был зеленым, синтаксис будет следующим:

::slotted(p) {
  color: green;
}

Заявление об отказе от ответственности заключается в том, что он не является частью ShadowDom, поэтому он не защищен. то есть основной документ все еще может переопределить css. Элементы внутри слота считаются находящимися в «светлом DOM».

Чтобы контролировать элементы внутри слота, вы можете подойти к этому с помощью одного из событий жизненного цикла. Например:

firstUpdated(changedProperties) {
    requestAnimationFrame(() => {
      const paras = document.querySelector("test-element").querySelectorAll('p');

      [].forEach.call(paras, (e)=>{
        e.style.color = "green";
      });
});

Внутри обработчика firstUpdated вы можете программно стилизовать содержимое слота. Не кадр requestAnimation. Я ссылаюсь на следующее обсуждение на gitHub этого https://github.com/Polymer/lit-html/issues/338. Контекст этого обсуждения - веб-компонент внутри слота другого веб-компонента, но я думаю, что это может быть хорошей практикой, потому что элементы слота могут не отображаться полностью, когда запускается пользовательский компонент firstUpdated.

person Mifo    schedule 30.05.2019
comment
Я знаю, что в этом отношении я сторонник жесткой линии, но использование js для стилизации вряд ли когда-либо уместно, и это всегда жертва производительности и UX. Но все же спасибо за ваш ответ, я также знаю, что на данный момент не все можно сделать с помощью CSS. Сейчас я пробую другой подход, при котором дочерние элементы с прорезями всегда являются базовыми элементами без дочерних элементов. Все еще не так круто, но пока вроде работает. - person codepleb; 03.06.2019