-
Hello, @keeganstreet and I are wondering if Media Queries can be set not as nested conditions when styling properties? We have a base component with a style like this: const baseStyle = stylex.create({
base: {
color: "black",
marginTop: "10px"
}
}) We would like to extend the styles of the base component, and change the margin value when a media query matches. We tried what was recommended in the docs: const extendedStyle = stylex.create({
base: {
marginTop: { default: null, '@media only screen and (max-width: 640px)': '100px' }
}
})
const styles = stylex.props(baseStyle.base, extendedStyle.base) The media query worked, but the problem is that the default also overrides the baseStyle marginTop. The default margin becomes zero when it does not match the media query. We found that we were able to achieve what we wanted by lifting the media query up a level like below: const extendedStyle = stylex.create({
base: {
'@media only screen and (max-width: 640px)': { marginTop: '100px' }
}
}) However, The Stylex eslint throws a warning about this. Is there a better way to achieve we're after? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
I'll start with the solution, which is CSS variables: Create a file next to your base component and export a const baseTokens = stylex.defineVars({
marginTop: "10px",
}); Update the base component to use this variable: const baseTokens = stylex.defineVars({
marginTop: baseTokens.marginTop,
}); Document these "base" tokens for override styles, so this can be done: const extendedStyle = stylex.create({
base: {
marginTop: {
default: baseTokens.marginTop,
'@media only screen and (max-width: 640px)': '100px'
}
}
})'
const styles = stylex.props(baseStyle.base, extendedStyle.base) Why things work this wayChoosing to nest Media Queries and Pseudo Classes within CSS properties and not vice-versa which is how CSS has traditionally done it was a change we put a lot of thought into before making. It was the only way to achieve predictable merging of styles. We made this choice knowing that there would be some scenarios, like yours where it would be a little more cumbersome. Here are the principles behind this decision: ExpectationConsider a base component that uses different values of Now, imagine if you wanted a different set of margins at a different set of conditions than the base component. The current model lets you simply replace all existing "conditions" with your own set of "conditions". With the traditional model, you'd need to define a superset of the "conditions" already used in the base component. This would not only be more cumbersome, but also generate more bloated CSS. With the StyleX model, you can set Inline Styles ModelStyleX is modelled after inline styles. There are no media queries or pseudo classes in inline styles. Instead you have to choose the value of Mixing with Inline StylesWe wanted to keep our options open adding the ability to freely mix StyleX styles and inline styles. Since inline styles have a higher specificity than all CSS styles, inline styles would normally override all media query and pseudo classes, even the styles that are applied later. With the StyleX model, this is a non-issue. If you apply a StyleX React Native / React Strict DOMWe knew we wanted to bring StyleX to React Native. React Native, like inline styles on the web, has no native support for media queries or pseudo classes. React Native also doesn't have support selectors or specificity. Therefore it would be impossible to ensure that Media Queries were applied with a higher specificity than all base styles. (In the traditional model, SimplificationLimiting top level style keys to just CSS properties simplifies the thought process and the actual implementation when it comes to merging styles. CSS Variables can fill in the gapsWhen you do want to merge base styles and media query styles for the same CSS property, it can be done so with relative ease using CSS variables. StyleX just enforces that you be explicit in allowing this kind of merging. This amount of work was always required with the traditional CSS model, but it was implicit. Another exampleAnother example of how CSS variables can be used to customise a property partially is a link component. A base link component may want to allow changing the color of a link only on hover. It can be achieved like this: const baseTokens = stylex.defineVars({
color: {default: 'black', ':hover': baseTokens.hoverColor }
}); And it can be customised with: const extendedStyle = stylex.create({
base: {
[baseTokens.hoverColor]: 'red'
}
}); |
Beta Was this translation helpful? Give feedback.
I'll start with the solution, which is CSS variables:
Create a file next to your base component and export a
VarGroup
called base tokens.Update the base component to use this variable:
Document these "base" tokens for override styles, so this can be done:
Why things…