danielx
danielx

Reputation: 1793

hidden attribute on custom elements with shadow DOM rendering in Chrome

When using shadow DOM rendering in polymer instead of shady DOM I've noticed that custom elements can not be hidden with the global attribute hidden.

This only seems to affect Chrome since it the elements gets hidden in both Safari and Firefox (IE unknown).

Here is a example for the Chrome browser using iron-icon

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Demo</title>

  <script src="https://polygit.org/components/webcomponentsjs/webcomponents-lite.js"></script>

  <script>
    // Setup Polymer options
    window.Polymer = {
      dom: 'shadow'
    };
  </script>

  <link rel="import" href="https://polygit.org/components/polymer/polymer.html">
  <link rel="import" href="https://polygit.org/components/iron-icon/iron-icon.html">
  <link rel="import" href="https://polygit.org/components/iron-icons/iron-icons.html">
</head>
<body>
  <my-app></my-app>
  <dom-module id="my-app">
    <template>
      <p>
        hidden: <iron-icon icon="bug-report" hidden></iron-icon>
      </p>
      <p>
        visible: <iron-icon icon="check"></iron-icon>
      </p>
    </template>
    <script>
      Polymer({is: 'my-app'});
    </script>
  </dom-module>
</body>
</html>

https://jsbin.com/xetiboboya/4/edit?html,output

When changing window.Polymer.dom to shady it correctly hides the iron-icon element.

Explicitly setting a style for iron-icon with a hidden attribute works as well.

iron-icon[hidden] {
  display: none;
}

Upvotes: 2

Views: 2232

Answers (1)

Supersharp
Supersharp

Reputation: 31171

It's because Polymer adds, in the Shadow DOM of <iron-icon>, a <style> element with a CSS rule that overrides the hidden attribute.

<style>
   :host { 
       display: inline-flex;
   }
</style>

This rule is itself overridden by the one you added.

I1.attachShadow( { mode: 'open' } )
  .innerHTML = `icon 1
<style>
    :host { 
        display: inline-flex ;
        color: red ;
    }
</style>`

I2.attachShadow( { mode: 'open' } )
  .innerHTML = `icon 2
<style>
    :host { 
        display: inline-flex ;
        color: red ;
    }
</style>`
#I1[hidden] {
    display: none ;
}
<iron-icon id=I1 hidden></iron-icon>
<iron-icon id=I2 hidden></iron-icon>

Update

Also, because of the shadow mode, Shadow DOM is created for your <my-app> elements that blocks the global [hidden] { display: none !important; } CSS rule, added by Polymer iron-flex-layout.html file.

shadow mode actually applies only in browsers implementing Shadow DOM (Chrome, Opera), that's why the rendering is different on Firefox or Safari.

Look at the amended JSBin : https://jsbin.com/qolegopago/edit?html,output

Upvotes: 3

Related Questions