Общий стиль с пользовательскими элементами HTML? - PullRequest
0 голосов
/ 31 октября 2018

Я начинаю использовать пользовательские элементы, и одну вещь, которую я не могу понять, - это совместное использование стилей. Например, если у меня есть 2 пользовательских элемента, <element-1> и <element-2>, каждый из которых содержит <button>, и я хочу, чтобы все кнопки имели определенный стиль, например, font-size:20px.

Варианты, которые я рассмотрел:

  1. Используйте пользовательский элемент <stylized-button> вместо <button> в пользовательских элементах. Это проблематично, когда внешний источник <element-1>. Также проблематично, если вам нужны другие стили (например, color:red) только для кнопок <element-1>, а не для кнопок <element-2>.

  2. Насколько я могу судить из документации на полимер [1], у полимера также нет решения для этого.

  3. /dead/ и :shadow показались многообещающими, но больше не поддерживаются.

  4. Аналогично @apply [2] показалось многообещающим, но предложение было снято.

  5. ::part и ::theme [3] кажутся еще более многообещающими, но пока не поддерживаются.

  6. Используйте js для поддержки ::part и ::theme [4]. я думаю, что это было бы очень хрупким без сглаживания всех случаев.

  7. Явно добавьте общий стиль к каждому пользовательскому элементу.

    class Element1 extends HTMLElement {
        constructor() {
            this.shadowRoot.addElement(sharedStyle);
        }
    }
    

    Это кажется очень ограниченным и ручным. Также может повлиять на производительность? Также проблематично, если вы используете внешний источник <element-1>.

Прямо сейчас, я думаю, что # 5 может быть лучшим, так как кажется наиболее общим / простым в использовании без создания специально для него, плюс это сделает переход на № 4 тривиальным, когда он будет реализован. Но мне интересно, есть ли другие подходы или предложения?

[1] https://www.polymer -project.org / 3.0 / docs / devguide / style-shadow-dom

[2] http://tabatkins.github.io/specs/css-apply-rule/

[3] https://meowni.ca/posts/part-theme-explainer/

[4] Наивная реализация и пример ее использования: https://gist.github.com/mahhov/cbb27fcdde4ad45715d2df3b3ce7be40

реализация:

document.addEventListener('DOMContentLoaded', () => {
    // create style sheets for each shadow root to which we will later add rules
    let shadowRootsStyleSheets = [...document.querySelectorAll('*')]
        .filter(element => element.shadowRoot)
        .map(element => element.shadowRoot)
        .map(shadowRoot => {
          shadowRoot.appendChild(document.createElement('style'));
          return shadowRoot.styleSheets[0];
        });

    // iterate all style rules in the document searching for `.theme` and `.part` in the selectors.
    [...document.styleSheets]
        .flatMap(styleSheet => [...styleSheet.rules])
        .forEach(rule => {
          let styleText = rule.cssText.match(/\{(.*)\}/)[1];

          let match;
          if (match = rule.selectorText.match(/\.theme\b(.*)/))
            shadowRootsStyleSheets.forEach(styleSheet => styleSheet.addRule(match[1], styleText));
          else if (match = rule.selectorText.match(/\.part\b(.*)/))
            shadowRootsStyleSheets.forEach(styleSheet => styleSheet.addRule(`[part=${match[1]}]`, styleText));
        });
  });

и использование:

<style>
  .my-element.part line-green {
    border: 1px solid green;
    color: green;
  }

  .theme .line-orange {
    border: 1px solid orange;
    color: orange;
  }

  /*
    must use `.part` instead of `::part`, and `.theme` instead of `::theme`
    as the browser prunes out invalid css rules form the `StyleSheetList`'s. 
  */
</style>

<template id="my-template">
  <p part="line-green">green</p>
  <p class="line-orange">orange</p>
</template>

<my-element></my-element>

<script>
  customElements.define('my-element', class extends HTMLElement {
    constructor() {
      super();
      this.attachShadow({mode: 'open'});
      const template = document.getElementById('my-template').content.cloneNode(true);
      this.shadowRoot.appendChild(template);
    }
  });
</script>

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Если вы используете css, вы можете просто сделать это:

button {

  /* Put Style Here */  

}

Вы также должны добавить ссылку в заголовке на html:

<link rel=“stylesheet” href=“the address”>
0 голосов
/ 01 ноября 2018

Вы можете использовать @import url для импорта внешней таблицы стилей в различные пользовательские элементы.

Теперь вы также можете использовать <link rel="stylesheet"> внутри пользовательского элемента Shadow DOM:

<template id="element-1">
  <style> 
      @import url( 'button-style.css' )
  </style>
  <button>B-1</button>
</template>

<template id="element-2">
  <link rel="stylesheet" href="button-style.css">
  <button>B-2</button>
</template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...