2

I'm looking for a way to replace ::shadow now that it is gone. I've found two topics about it on this website, but both imply to modify the shadow element. here and there

But the point of Web Components is to be able to import any element we found on the Internet in our webpage / app. So, it means that I don't wanna modify anything on these "third parties elements", because there are sources, and if I modify them, it will be overwritten when I later update them.

So, imagine that I download on webcomponents.org an element that creates some sort of button, but I need to change the color of this button because it doesn't fit the style of my page/app. The element creator has put no variable in his CSS, no @apply rule, no imports, nothing. Just the polymer element itself, working properly.

How can I do this without modifying the element's source code?

Community
  • 1
  • 1
SKMTH
  • 552
  • 1
  • 6
  • 22

2 Answers2

2

One option would be to style it imperatively. Get a reference to the element, use the DOM API on it to query its shadow DOM for the inner element you want to modify, then set the style property of that reference.

For example, the <gold-cc-cvc-input> currently has no extension points for styling its credit card icon.

  1. Right-click the icon in Chrome, and inspect it in DevTools. We see the icon has an id of "icon".

  2. Get a reference to <gold-cc-cvc-input id="cvc">, and set the style of the "icon" element. Here, we're using Polymer's automatic node finding to get a reference to the <gold-cc-cvc-input> by its ID (i.e., this.$.cvc) and then a reference to the inner "icon" element (i.e., this.$.cvc.$.icon).

    this.$.cvc.$.icon.style.border = 'solid 2px blue';
    

HTMLImports.whenReady(() => {
  Polymer({
    is: 'x-foo',
    attached: function() {
      this.$.cvc.$.icon.style.border = 'solid 2px blue';
    }
  });
});
<head>
  <base href="https://polygit.org/polymer+1.7.1/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
  <link rel="import" href="gold-cc-cvc-input/gold-cc-cvc-input.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <gold-cc-cvc-input id="cvc"></gold-cc-cvc-input>
    </template>
  </dom-module>
</body>

codepen

tony19
  • 125,647
  • 18
  • 229
  • 307
  • It works! Thanks (again) tony! Though the problem of proceeding this way is that we cannot use css variable :/ – SKMTH Feb 06 '17 at 13:52
  • @SKMTH No problem. You can actually use [`this.getComputedStyleValue('--my-custom-style')`](https://www.polymer-project.org/1.0/docs/api/Polymer.Base#method-getComputedStyleValue) in a Polymer element to imperatively query a CSS variable. – tony19 Feb 06 '17 at 13:56
2

You can style it from your container element, just look at the structure of the 3rd parties element. E.g.<paper-card> is the element you whant to style. paper-cards have divs inside:
shady DOM (Polymer 1.*)

<style>
  paper-card div{
    background-color: red;
    padding: 30px;
  }
</style>

<head>
  <base href="https://polygit.org/polymer+:master/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="paper-card/paper-card.html">
  <style>
    .thirdPartEl div{
      background-color: red;
      padding: 30px;
    }
  </style>
</head>
<body>
  <paper-card heading="I'm unstyled 3rd parties element"></paper-card>
  <paper-card class="thirdPartEl" heading="I'm styled 3rd parties element"></paper-card>
</body>

shadow DOM (Polymer 2.0)
for styling element from outside just use tag name as selector

<style>
  paper-card{
    background-color: red;
    padding: 30px;
  }
</style>

but if you want to style internals, you need custom CSS properties. if these aren't set, you can style them imho only via js at the moment

ddp
  • 122
  • 8
  • The caveat is this doesn't work with shadow DOM. Your solution requires shady DOM (the default in Polymer 1.x, but not the default in 2.x). ([demo](http://codepen.io/tony19/pen/VPdLeR?editors=1000)) – tony19 Feb 04 '17 at 14:46