@scope emulation with revert-layer

| permalink | css

@scope is a CSS feature not yet fully supported by all browsers.

However, I want to use this feature today to set typography styles and only apply them between the .prose and .not-prose classes as inspired by Tailwind.

@scope (.prose) to (.not-prose) {
  /* define scoped style here */
}

It turned out that it is possible to emulate this using layers and the trusty revert-layer keyword.

To do so, I placed all prose styles inside it's own layer, and then removed style from everything else using revert-layer, essentially nuking the entire (web)site from orbit.

/* setup */
@layer prose {

  /* max out specificity, acts like a layer-scoped !important */
  :not(#_#_#_#_#_#_#_#_#_#_) {
    /* remove style outside .prose */
    &:not(.prose, .prose *) {
      &, &::before, &::after {
        all:revert-layer;
      }
    }

    &.not-prose {
      /* remove style from .not-prose itself */
      &,
      /* remove style from children of .not-prose, support 3x nesting */
      :where(
        & :not(.prose):not(& .prose *),
        & & :not(.prose):not(& & .prose *),
        & & & :not(.prose):not(& & & .prose *)
      ) {
        &, &::before, &::after {
          all:revert-layer;
        }
      }
    }
  }
}

/* use */
@layer prose {
  /* define scoped style here */
}

Currently I'm using a slightly modified version of this technique for my website via my own DryKit framework.

Limitations/Cons:

At the end of the day, this is still just an interim solution while the real CSS @scope feature is being rolled out to all browsers.