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

Make theme.json cross-platform (web & mobile) #24165

Closed
oandregal opened this issue Jul 23, 2020 · 9 comments
Closed

Make theme.json cross-platform (web & mobile) #24165

oandregal opened this issue Jul 23, 2020 · 9 comments
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change)

Comments

@oandregal
Copy link
Member

The experimental-theme.json specification structures the way themes provide styling information for blocks, among other things. However, as it currently stands, the value of the style declarations are evaluated as text that is passed down to the CSS output unmodified.

Take this example:

"core/heading/h1": {
    "styles": {
        "color": {
            "background": "red",
            "text": "var(--wp--preset--color--primary)",
            "link": "blue",
        },
        "typography": {
            "fontSize": "calc(1px * var(--wp--preset--font-size--huge))"
        }
    }
}

When processed (and the core, theme, and user data is merged) it'll be converted to a CSS stylesheet like this:

h1 {
    background: red;
    color: var(--wp--preset--color--primary);
    --wp--link--color: blue;
    font-size: calc(1px * var(--wp--preset--font-size--huge);
}

Note how the values of the style declarations are exactly the same. This works fine for the web, as long as it is a valid CSS declaration that browsers understand. However, this is problematic for supporting Global Styles on mobile (see). Issues that we have are:

  • Functions as calc are not supported.
  • CSS Custom Properties are not supported (var(--wp--preset--color--primary) but also attaching a new value for --wp--link--color per node).

Related context

For context, I also wanted to share some other things that are relevant to styles on mobile:

  • Not all CSS properties have mobile equivalents.
  • Mobile styles are attached to a component, we can't do "make all buttons red". At the moment, the mobile team is using react context to pass values, etc.
  • Current block styles are created based on the *.native.scss files + some attributes of the block (background color). Ex: create a post in a site you can access from mobile, add a button and change the background color to a custom color. Save and check that the mobile app shows the same color.
  • There's a related action item which is to to create a new endpoint for mobile to have access to the global styles data. I'll leave that for a different issue/PR for the mobile team to own.

Next steps

There are some areas I'd welcome some feedback:

  1. What style properties does mobile need to support for each block?

Colors seem to be the first target the mobile team is considering for block level styles. What about the others style properties that we have, would we be interested in supporting them in the future or aren't they relevant for the mobile app? I'm thinking on things like spacing/padding that are highly tied to the available canvas/viewport. For reference, this is the full list of style attributes we currently aim to support: colors (text, background, links, gradients), typography (font-size, font-family, font-weight, line-height), spacing (margin, padding). cc @pinarol

  1. We need to restrict the style declarations in theme.json to a subset of CSS, so we can reference every style prop to a raw value mobile can use. What would be the more complex declaration we want to support?
  • What would be the more complex use case we want to support in theme.json? Would it be enough for themes if we provide a mechanism that can substitute this declaration: calc(1px * var(--wp--preset--font-size--huge))? I mean, unit conversion + reference some variable stored somewhere. cc @kjellr

  • Can we use css-wide keywords such as initial, inherit, unset? cc @pinarol

@oandregal oandregal added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Jul 23, 2020
@mtias mtias mentioned this issue Jul 23, 2020
82 tasks
@kjellr
Copy link
Contributor

kjellr commented Jul 23, 2020

What would be the more complex use case we want to support in theme.json? Would it be enough for themes if we provide a mechanism that can substitute this declaration: calc(1px * var(--wp--preset--font-size--huge))? I mean, unit conversion + reference some variable stored somewhere. cc @kjellr

Yeah, a calc() that references another variable is probably the most common complex use case. You'll also need to make sure that complex gradients will work correctly too (We've already run into numerous issues with those). In general, I'd expect most of the standard CSS functions to work in this context.

I can imagine the image filters and transform functions would be very beneficial to have access to when it comes to image-based blocks. But I know those get pretty complicated.

One thing for sure: If we're limiting these to a subset of CSS, we should be sure to implement errors/warnings for theme authors when an unsupported value is entered.

@pinarol
Copy link
Contributor

pinarol commented Jul 24, 2020

Colors seem to be the first target the mobile team is considering for block level styles. What about the others style properties that we have, would we be interested in supporting them in the future or aren't they relevant for the mobile app? I'm thinking on things like spacing/padding that are highly tied to the available canvas/viewport. For reference, this is the full list of style attributes we currently aim to support: colors (text, background, links, gradients), typography (font-size, font-family, font-weight, line-height), spacing (margin, padding). cc @pinarol

Ideally we want to unlock all the block settings for mobile users. Having said that we sometimes hit the wall to make everything WYSIWYG, but we are trying our best to make it so.

Colors

Colors is the first thing we'll be adapting. We already have colors in some of our blocks like Button, Cover. We are using themes endpoint to resolve colors from the palette. And we want to bring colors into Group, Paragraph/Heading very soon.

Background ✔️
Text ✔️
Gradient ✔️
Link ✔️

Spacing
Margin✔️
Padding✔️

I don't have a good understanding about all the use cases for this one. Currently there's only 1 example which is Cover: Add Padding Styles. And this one looks as something we'd definitely be interested in brining to mobile.

I have 2 concerns about this one though.

  1. What's the unit of the space, px? em? Is the unit configurable by users or theme authors? I don't think we can render em on mobile 🤔

  2. calc() usage and possibility of relative values.

calc(100% - 30px); //just to note we can use percentages but we can't combine them with px values so any such expression needs to be programmatically calculated on JS side.
calc(2em * 5);

❓ Can I ask what are some common needs behind using calc()? Maybe it is something we wouldn't be interested in supporting anyway. Or if the use case is simple then we can represent the same thing with a different expression?

Typography

This is the most tricky one so let me ask some questions first.

❓Is there a list of font families that are planned to be supported?
❓Is it possible for theme authors (or users?) to add new fonts?

cc @iamthomasbishop

@pinarol
Copy link
Contributor

pinarol commented Jul 24, 2020

Can we use css-wide keywords such as initial, inherit, unset? cc @pinarol

Unfortunately we don't have support for them on mobile.

@oandregal
Copy link
Member Author

@pinarol font-family is on the roadmap, but we haven't gotten into it yet #23204 The idea would be that theme authors can provide their own list, I'm not sure at this point if core should provide a set of defaults or not.

@pinarol
Copy link
Contributor

pinarol commented Aug 6, 2020

The idea would be that theme authors can provide their own list

Supporting a dynamic set of fonts that are determined during runtime is super tricky on mobile, I think we'd never aim towards that target. There are some system fonts available on iOS/Android, and it is possible to bundle additional custom fonts inside the app but it is a static thing, can't change with the theme. Plus, some custom fonts don't play well with accessibility features (like bigger font size settings) and can generate unexpected bugs. Not mentioning the possible licensing issues that can result from using custom fonts.

It may be technically possible to choose a safe set of fonts which are by default supported by iOS/Android/Web and provide that set instead. But I doubt it would be that useful if they don't match the theme. 😬

A more realistic short term goal for mobile may be just allowing to change size related things, like font size, line height etc.

Either ways, I'd prefer prioritizing other aspects of GS on mobile side, like colors (text, background, links, gradients) and spacing (margin, padding). cc @iamthomasbishop if he wants to correct me or add something.

@iamthomasbishop
Copy link

Can I ask what are some common needs behind using calc()?

@pinarol I'm sure there are many more examples that the web folks can speak to, but one way I've used it is to extend something beyond its container's bounds. For example if I want an image that extends 40px beyond its container's bounds, I would say (in CSS) width: calc(100% + 80px); and then offset to the left by -40px w/ margin or translate. I think it's helpful especially when the element's container is dynamic. Hopefully we can find or use a reliable method of translating from calc to whatever is usable on our end — I think that'd be really helpful.

I don't think we can render em on mobile

I think that's right. As far as I can tell, RN only supports "logical pixels", which is essentially the same as "points" on iOS and "dp" (device-independent pixels) on Android. I think we'd need to either find or build a translation mechanism to support em, rem, and so on, but if we can find a way to translate to and from various unit types — well, that would be huge — for spacings and type scale especially, which are foundational.

Colors wrt mobile

I think we're in good shape when it comes to solid colors, bc it seems like we have pretty wide color-type support — hex, rgb, rgba, hsl, etc. Gradients I'm not as sure about. I know we've had some challenges implementing gradients on mobile but I'm not sure if they're because of support constraints or knowledge gaps.

Font-family (mobile)

I agree with just about everything you said above on fonts. The purely dynamic approach is essentially a no-go as far as I can tell. The "bundling additional fonts" approach is compelling, but even if we were to bundle a set of fonts that covers a large portion of the most popular ones, there are a bunch of things that could go wrong (most notably accessibility, dynamic font-size, weights, etc).

Prioritization (mobile)

I agree that we probably want to de-prioritize fonts in the immediate term and focus on colors, gradients, and spacing. It would be wise to have someone on the team do a technical exploration spike soon in order to learn more about our options wrt fonts, but the other things should give us some quick wins in the meantime.

@mtias mtias added the Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change) label Aug 26, 2020
@Tug
Copy link
Contributor

Tug commented Sep 11, 2020

From the look of it, it doesn't look like this theme.json spec would be a major blocker for mobile. Or rather I don't believe changing the spec would help the mobile case much.

Concerning CSS variables their names look quit explicit and match the experimental-theme.json schema so it should not be difficult to find the value of a variable in the config.

However we would not be able to support blocks overwriting those variables. Not sure if this practice is supported/encouraged at this point for the web?

Concerning CSS functions, I don't see any way to support all the features they provide for native, even if we change the spec.

If we're simply multiplying a CSS variable by a constant (like in calc(1px * var(--wp--preset--font-size--huge);) or something simple like that we can probably "pre-compute" the result and use it in our React Native code.
However as soon as we use a percentage or other other types of construct, it becomes dynamic and the formula needs to be given as it is to the CSS engine. So it simply cannot work on native.
In that case, we should probably discourage theme authors from using this kind of formulas.

Though if we look at the implicit block attributes that we plan to have on the web:

  • font-size
  • line-height
  • color
  • weight
  • font family

All can easily have a static value (not use formulas) without degrading the UX

@oandregal
Copy link
Member Author

Given that we've already landed an endpoint #29969 and other things for mobile, can we close this issue? cc @geriux

@geriux
Copy link
Member

geriux commented May 26, 2021

Given that we've already landed an endpoint #29969 and other things for mobile, can we close this issue? cc @geriux

Yes, we can close this one 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json Mobile App - i.e. Android or iOS Native mobile impl of the block editor. (Note: used in scripts, ping mobile folks to change)
Projects
None yet
Development

No branches or pull requests

7 participants