1

I have a Polymer v2 web component defined below. In the main page I include a CSS file which defines style named n-action-button. When I open the main page in FireFox or IE the style is applied to the web component, but when I do the same in Chrome the content of the web component is not styled.

Everything was working fine when the application was using Polymer v1 library. It has changed when I upgraded to Polymer v2. I've read in docs on the net that externally-defined styles should be applied to web components. I have no idea why it isn't working under Google Chrome browser.

<link rel="import" href="../polymer/polymer-element.html">
<dom-module id="login-form">
  <template>
        <h1>
            Use your username &amp; password to sign in.
        </h1>
        <form id="form" method="post" action="j_security_check">
            <input id="username" name="j_username" type="text" placeholder="username"/>
            <input type="submit" id="submit" value="Log In" class="n-action-button">
        </form>
  </template>
  <script>
    class LoginForm extends Polymer.Element {
      static get is() { return 'login-form'; }
    }
    window.customElements.define(LoginForm.is, LoginForm);
  </script>
</dom-module>

EDIT: The style looks like this:

.n-action-button,
.n-action-button:hover,
.n-action-button:focus,
.n-action-button:active,
.n-action-button:visited,
.n-action-button[disabled],
.z-button.n-action-button,
.z-button.n-action-button:hover,
.z-button.n-action-button:focus,
.z-button.n-action-button:active,
.z-button.n-action-button:visited,
.z-button.n-action-button[disabled] {
    display: inline-block;
    color: #fff;
    text-shadow: none;
    text-decoration: none;
    padding: 15px 30px;
    line-height: 22px;
    -webkit-border-radius: 6px;
    -moz-border-radius: 6px;
    border-radius: 6px;
    border: 0;
    -webkit-transition: color .25s, background .25s;
    -moz-transition: color .25s, background .25s;
    -o-transition: color .25s, background .25s;
    transition: color .25s, background .25s;
}

.n-action-button,
.n-action-button:visited,
.z-button.n-action-button,
.z-button.n-action-button:visited {
    background: #49b87b;
}

.n-action-button:hover,
.n-action-button:focus,
.n-action-button:active,
.z-button.n-action-button:hover,
.z-button.n-action-button:focus,
.z-button.n-action-button:active {
    color: #fff;
    background: #4bbe7f;
}

.n-action-button[disabled],
.z-button.n-action-button[disabled],
.z-button.n-action-button[disabled]:hover,
.z-button.n-action-button[disabled]:focus,
.z-button.n-action-button[disabled]:active {
    color: #fff;
    background: #b1b1b1;
}
Lukasz
  • 7,572
  • 4
  • 41
  • 50
  • 1
    How do you define that style? Support for /deep/ and similar has been deprecated (and AFAIK removed, or about to be removed, from chrome). Yes, it's a pain for styling but you should go with variables – Adriano Repetti Aug 20 '17 at 11:31
  • @AdrianoRepetti see my edit. I double-checked I'm not using /deep/ anywhere – Lukasz Aug 20 '17 at 11:34
  • 1
    Well, at least as far as I know, it should NOT work. One point of web components is exactly to do not break them with some global css style or conflicting declarations. You have few ways to style your components, if it's not a library then you can put styling in a shared style component which you inherit everywhere. – Adriano Repetti Aug 20 '17 at 12:50
  • @AdrianoRepetti OK, I get it now. Thanks. – Lukasz Aug 23 '17 at 09:54

2 Answers2

1

This is likely because of Shadow DOM's style encapsulation. Polymer 1 defaults to Shady DOM (polyfill for Shadow DOM) for all browsers, but in Polymer 2, Shadow DOM is the default if supported by the browser, falling back to Shady DOM only if necessary (which is the case for IE and Firefox).

You could force Shady DOM in Polymer 2 by specifying an attribute on the <script> tag for the webcomponents.js script:

<script src="webcomponentsjs/webcomponents-lite.js" shadydom></script>

demo

A good reference might be Polymer's upgrade guide regarding Shadow DOM.

tony19
  • 125,647
  • 18
  • 229
  • 307
  • Thanks. Now I understand, I guess I would prefer to have the styles included in my web component avoiding Shadow DOM. – Lukasz Aug 23 '17 at 09:53
1

Global styles should NOT influence element inside your shadow dom. I'm afraid but your approach only worked before because of the limitations of the polyfills. Now with polymer 2 you get true shadow dom and encapsulation.

So for encapsulation to work you have to expose css mixins and globally set those.

Example:

<link rel="import" href="../polymer/polymer-element.html">
<dom-module id="login-form">
    <template>
        <style>
            #submit {
                background: #49b87b;
                display: inline-block;
                color: #fff;
                text-shadow: none;
                text-decoration: none;
                padding: 15px 30px;
                line-height: 22px;
                -webkit-border-radius: 6px;
                -moz-border-radius: 6px;
                border-radius: 6px;
                border: 0;
                -webkit-transition: color .25s, background .25s;
                -moz-transition: color .25s, background .25s;
                -o-transition: color .25s, background .25s;
                transition: color .25s, background .25s;
                @apply --submit;
            }
            #submit:hover, #submit:focus, #submit:active {
                color: #fff;
                background: #4bbe7f;
                @apply --submit-hover;
            }
            #submit[disabled], #submit[disabled]:hover, #submit[disabled]:focus, #submit[disabled]:active {
                color: #fff;
                background: #b1b1b1;
                @apply --submit-disabled;
            }
        </style>

        <h1>
                Use your username &amp; password to sign in.
        </h1>
        <form id="form" method="post" action="j_security_check">
                <input id="username" name="j_username" type="text" placeholder="username"/>
                <input type="submit" id="submit" value="Log In" class="n-action-button">
        </form>
    </template>
    <script>
        class LoginForm extends Polymer.Element {
            static get is() { return 'login-form'; }
        }
        window.customElements.define(LoginForm.is, LoginForm);
    </script>
</dom-module>

so then in your html you could just override certain values if you need them. styles.html

<custom-style>
  <style is="custom-style">
    html {
      --submit: {
                color: orange;
            };
      --submit-hover: {
                color: orange;
                background: grey;
            };
      --submit-disabled: {
                color: green;
                background: grey;
            };
    }
  </style>
</custom-style>
daKmoR
  • 1,774
  • 12
  • 24
  • Looks like a more preferable direction for me. I'm marking this as a Accepted Answer, although @tony19 made also a really valuable answer. – Lukasz Aug 23 '17 at 09:56