skip to Main Content

I have an HTML custom element that inherits from HTMLElement. The template contains:

<input type="text" part="input"/>

Sample CSS:

  my-element::part(input) {
    padding-right: 1px;
  }

Sample JavaScript (inside class MyElement {}):

  this.input.style.paddingRight = "25px";

The Style inspector in DevTools (Rules in Firefox) crosses out the ::part declaration for padding-right and shows:

  element.style {
    padding-right:25px;
  }

But the computed value inspector shows padding-right:1px and it’s rendered as 1px.

The JS code is running after the page fully loads. I don’t see a straightforward way around this behavior. If I modify a CSS property for this element in JS, then I cannot declare it CSS. At least not with padding.

Why does a pseudo-element of the custom element take precedence over the element’s own style?

The fact that the Style/Rules inspector disagrees with the Computed inspector makes me think this is a bug in both browsers, but I’m no expert. I have not yet tried this on browserstack to check other platforms. Right now I’m focused on working around this unexpected behavior.

It’s a bit of work to create a working demo snippet, and the behavior is the same across Firefox and Chrome in Win11, so I’ll wait until someone requests it.

2

Answers


  1. The ::part pseudo-element works in conjunction with browser rendering layers and the cascade order of styles.
    To fix this you can force higher specificity in JavaScript code:

    this.input.style.setProperty('padding-right', '25px', 'important');
    

    This code will ensure that the inline style with !important takes precedence over the ::part pseudo-element styles.

    Login or Signup to reply.
  2. I can’t replicate your findings, there must be something else in your code

    Needing !important is almost always a red flag for CSS issues

    <style>
      my-element::part(input){
        background: green;
      }
      my-element::part(input2){
        padding-right: 1px;
      }
    </style>
    <my-element>
      <template shadowrootmode="open">
        <style>
          input{
            padding-right:25px;
          }
          span{
            background:pink
          }
        </style>
        <input part="input input1"><span>25px padding-right after input1</span>
        <br>
        <input part="input input2"><span>1px padding-right after input2</span>
      </template>
    </my-element>

    input1:


    input2


    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search