marpit icon indicating copy to clipboard operation
marpit copied to clipboard

[Next-gen framework] `<style scoped>` vs `@scope`

Open yhatt opened this issue 7 months ago • 0 comments

<style scoped> is a helpful Marpit specific syntax to overload theme styles within the current <section> element.

However, scoped attribute had been obsoleted, and currently any browsers are not supported. As a result, Marpit has been introduced it as an unique syntax, so Marpit and Marp ecosystem break a compatibillty with HTML specification.

We may have to re-cosnider how to work style scoping, to match the syntax with the modern HTML and CSS.

How to treat <style scoped> in regular Markdown converter?

Let's consider the following Marpit Markdown:

<style>
section {
  background: yellow;
}

h1 {
  color: red;
}
</style>

<style scoped>
section {
  background: aqua;
}

h1 {
  color: blue;
}
</style>

# Page 1

---

# Page 2

In Marpit, the first page will be rendered as aqua background and blue text by the scoped style, and second page will be yellow background and red text by the global style.

This Markdown will transform to HTML like following. Please note that this conversion process is incuding slide support (<section>), but not including Marpit specific <style scoped> support.

<section>
  <style>
  section {
    background: yellow;
  }
  
  h1 {
    color: red;
  }
  </style>

  <style scoped>
  section {
    background: aqua;
  }
  
  h1 {
    color: blue;
  }
  </style>

  <h1>Page 1</h1>
</section>
<section>
  <h1>Page 2</h1>
</section>

When render this HTML on the browser, <style scoped> will treat as global style because scoped attribute is not supported. Thus, every <section> has aqua bg and blue text.

https://jsfiddle.net/mw6azyjs/1/

We want to adopt better syntax for scoping that is compatible with standard HTML and CSS if possible.

@scope at-rule

@scope at-rule, supported by current version of Chromium and WebKit, can scope target of selectors based on the position of <style> element.

An above HTML with scoped styles can replace with @scope at-rule as following:

<section>
  <style>
  section {
    background: yellow;
  }
  
  h1 {
    color: red;
  }
  </style>

  <style>
  @scope {
    :scope {
      background: aqua;
    }
  
    h1 {
      color: blue;
    }
  }
  </style>

  <h1>Page 1</h1>
</section>
<section>
  <h1>Page 2</h1>
</section>

In this case, the result of render in supported browsers will be equivalent to Marpit's result that has included pre-processed style for <style scoped>.

https://jsfiddle.net/mw6azyjs/2/ (Recommend to see in Chrome or Safari)

The current Marpit cannot use @scope at-rule in this usage due to incompatibility with pre-process for scoping. Nevertheless, supporting @scope at-rule will be hopeful for compatibility with HTML and CSS, and useful as equivalent syntax to existing <style scoped>

yhatt avatar May 20 '25 16:05 yhatt