Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support multiple values in theme.json presets for progressive enhancement #53548

Open
cbirdsong opened this issue Aug 10, 2023 · 0 comments
Open
Labels
[Package] Style Engine /packages/style-engine [Type] Enhancement A suggestion for improvement.

Comments

@cbirdsong
Copy link

cbirdsong commented Aug 10, 2023

What problem does this address?

Currently, you provide a single value when registering size and color presets, which means it's not possible to provide fallback values for older browsers or devices.

{
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Orange",
          "slug": "orange",
          "color": "#f15a2e"
        },
      ],
    },
    "typography": {
      "fontSizes": [
        {
          "name": "Small",
          "slug": "sm",
          "size": "clamp(1.00rem, calc(0.94rem + 0.28vw), 1.25rem)"
        },
      ],
    },
    "spacing": {
      "spacingSizes": [
        {
          "name": "10",
          "slug": "10",
          "size": "clamp(0.25rem, calc(0.03rem + 0.87vw), 0.81rem)"
        },
      ],
    },
  }
}
--wp--preset--color--orange: #f15a2e;
--wp--preset--font-size--sm: clamp(1.00rem, calc(0.94rem + 0.28vw), 1.25rem);
--wp--preset--spacing--10: clamp(0.25rem, calc(0.03rem + 0.87vw), 0.81rem);

In this example, browsers without support for clamp() would not have any spacing or font size value applied for the sm/10 presets.

In practice, support for clamp() is closely aligned with support for custom properties so this isn't a widespread problem right now, but anyone who wants to use newer CSS features like expanded color spaces, relative viewport units and container units is unable to provide a reasonable fallback using progressive enhancement.

It's also important to note that in the case of color this is not a problem that will go away as browsers are updated. A device with a screen that doesn't support the Display-P3 color space will always work best with a fallback in good ol' rgb() or hex even if the browser understands color(). (more on this below)

What is your proposed solution?

Allow registration of multiple values for a preset, and output all of them. This way, browsers and devices that don't or can't use newer values for whatever reason will still get a reasonable facsimile of the experience as designed:

{
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Orange",
          "slug": "orange",
          "color": [
            "#f15a2e",
            "color(display-p3 0.96 0.43 0.27)"
          ]
        }
      ]
    },
    "typography": {
      "fontSizes": [
        {
          "name": "Small",
          "slug": "sm",
          "size": [
            "1.1rem",
            "clamp(1.00rem, calc(0.94rem + 0.28vw), 1.25rem)",
            "clamp(1.00rem, calc(0.94rem + 0.28cqi), 1.25rem)"
          ]
        }
      ]
    },
    "spacing": {
      "spacingSizes": [
        {
          "name": "10",
          "slug": "10",
          "size": [
            "0.33rem",
            "clamp(0.25rem, calc(0.03rem + 0.87vw), 0.81rem)",
            "clamp(0.25rem, calc(0.03rem + 0.87cqi), 0.81rem)"
          ]
        }
      ]
    }
  }
}
--wp--preset--color--orange: #f15a2e;
--wp--preset--color--orange: color(display-p3 0.96 0.43 0.27);
--wp--preset--font-size--sm: 1.1rem;
--wp--preset--font-size--sm: clamp(1.00rem, calc(0.94rem + 0.28vw), 1.25rem);
--wp--preset--font-size--sm: clamp(1.00rem, calc(0.94rem + 0.28cqi), 1.25rem);
--wp--preset--spacing--10: 0.33rem;
--wp--preset--spacing--10: clamp(0.25rem, calc(0.03rem + 0.87vw), 0.81rem);
--wp--preset--spacing--10: clamp(0.25rem, calc(0.03rem + 0.87cqi), 0.81rem);

This is very simple, but it wouldn't work well for color spaces, since browsers that understand color() running on a device that only has an SRGB gamut will attempt to map a Display P3 value to SRGB instead of falling back to the SRGB value. That may end up being a color that is ugly at best or makes content illegible at worst, which is obviously not ideal when a preselected SRGB version of the color is available.

A potential way to work around this would be supporting an object for colors that specifies the color space, then outputs the additional spaces in color-gamut media queries:

{
  "settings": {
    "color": {
      "palette": [
        {
          "name": "Orange",
          "slug": "orange",
          "color": {
            "srgb": "#f15a2e",
            "p3": "color(display-p3 0.96 0.43 0.27)"
          }
        }
      ]
    }
  }
}
--wp--preset--color--orange: #f15a2e;
@media (color-gamut: p3) {
  --wp--preset--color--orange: color(display-p3 0.96 0.43 0.27);
}

(The color stuff may be best as a separate issue.)

@jordesign jordesign added [Type] Enhancement A suggestion for improvement. [Package] Style Engine /packages/style-engine labels Aug 11, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Style Engine /packages/style-engine [Type] Enhancement A suggestion for improvement.
2 participants