How to prevent Theme CSS from overriding Theme App Extension styles?

Hi Shopify developers! :wave:

I’m struggling with a frustrating styling issue in my Theme App Extension and could really use some help.

The Problem

I can’t seem to maintain consistent styling in my app because theme CSS keeps overwriting my styles. For example, this theme selector is overriding my heading styles:

h1, h2, h3, h4, h5, .h0, .h1, .h2, .h3, .h4, .h5 {

font-family: var(–font-heading-family);

font-style: var(–font-heading-style);

font-weight: var(–font-heading-weight);

letter-spacing: calc(var(–font-heading-scale)* .06rem);

color: rgb(var(–color-foreground));

line-height: calc(1 + .3 / max(1, var(–font-heading-scale)));

word-break: break-word;

}

What I’ve Tried

  • Adding my CSS with target: “head”

  • Adding my CSS with target: “body”

  • Both approaches still result in theme styles overriding my app styles

My Question

How can I ensure my Theme App Extension maintains its own styling without being affected by theme CSS? Since every theme is built differently, I need a reliable way to guarantee my app provides a consistent visual experience.

Is there a recommended approach or best practice for handling this? Any help would be greatly appreciated!

One way to ensure you’re overriding other style declarations is to be more specific in yours.
Adding Class or ID or other identifier to the selector makes it more specific. This may require adding a little markup like the span tag in example 2, or the class name to the h2 like example 1.
example 3 uses a possible parent class to increase specificity.

h2.subhead-style {
  font-size: 2rem;
}
h2 span {
  font-size: 2rem;
}
.top_banner h2 {
  font-size: 2rem;
}

will all override a plain h2 because they’re more specific.

h2 {
  font-size: 1rem;
}

hope this helps

1 Like

One possible solution would be to use web components with shadow doms.

class StyledButton extends HTMLElement {
  constructor() {
    super();

    const shadow = this.attachShadow({ mode: 'open' });

    const button = document.createElement('button');
    button.textContent = this.getAttribute('label') || 'Click Me';

    const style = document.createElement('style');
    style.textContent = `
      button {
        background-color: #6200ea;
        color: white;
        border: none;
        padding: 10px 20px;
        font-size: 16px;
        border-radius: 5px;
        cursor: pointer;
      }
      button:hover {
        background-color: #3700b3;
      }
    `;

    shadow.appendChild(style);
    shadow.appendChild(button);
  }
}

customElements.define('styled-button', StyledButton);