material-ui icon indicating copy to clipboard operation
material-ui copied to clipboard

[RFC] CSS variables naming for components

Open siriwatknp opened this issue 1 year ago • 2 comments

Motivation

With the support in most modern browsers, CSS variables are an important key to improving the customization and styling experience (compare the at Grid v2 and Grid v1 to see the differences).

With the growing list of components, we need a guide/pattern to define those variables for consistency across MUI products.

Questions

1. Does the variable need a prefix?

The current variables in Joy UI and Material UI do not have prefixes.

  • https://mui.com/material-ui/react-grid2/
    --Grid-columns: ...;
    
  • https://mui.com/joy-ui/react-button/
    --Button-gap: ...;
    

At this point, I don't see a need for the prefix.

2. The structure of the variable?

I think the PascalCase should be used as a starting point to differentiate from the CSS theme variables.

Option 1 (current):

A pascal case starts with the parent component name, then the slot name (or a child component of the same category) and the last part is the modifier (quite similar to BEM).

// defined on the List component
--List-radius: ...;
--List-item-radius: ...; // used by ListItem
--List-decorator-size: ...; // used by ListItemDecorator

Option 2:

Starts with the full component name (a pascal case) and uses the specific component name.

// defined on the List component
--List-radius: ...;
--ListItem-radius: ...; // used by ListItem
--ListItemDecorator-size: ...; // used by ListItemDecorator

3. What should be the prefix for private variables?

use cases for private variables:

  • Some component contains some private variables that take care of some calculation and are then used by the public variables.
  • Act as an intermediate variables for setting default value and lets parent components override the value.

Options:

  • Option 1: --private-... https://github.com/mui/mui-x/issues/5463
  • Option 2: --unstable-...
  • Option 3: --internal-...

Feel free to comment or suggest more options.

siriwatknp avatar Dec 14 '22 09:12 siriwatknp

@siriwatknp can you add some benchmark of how the CSS variables look like in other frameworks?

From a first glance

Option 2: "Starts with the full component name (a pascal case) and uses the specific component name."

sounds great.

  1. What should be the prefix for private variables?

Can you elaborate on the need of private CSS variables?

mnajdova avatar Dec 14 '22 12:12 mnajdova

Can you elaborate on the need of private CSS variables?

For example, the Tooltip contains --unstable_Tooltip-arrow-rotation to calculate the inset value for different placements.

// the Tooltip arrow styles
'--unstable_Tooltip-arrow-rotation': 0,
width: 'var(--Tooltip-arrow-size)',
height: 'var(--Tooltip-arrow-size)',
boxSizing: 'border-box',
// use psuedo element because Popper controls the `transform` property of the arrow.
'&:before': {
  ...
  transformOrigin: 'center center',
  transform: 'rotate(calc(-45deg + 90deg * var(--unstable_Tooltip-arrow-rotation)))',
},
'[data-popper-placement*="bottom"] &': {
  top: 'calc(0.5px + var(--Tooltip-arrow-size) * -1 / 2)', // 0.5px is for perfect overlap with the Tooltip
},
'[data-popper-placement*="top"] &': {
  '--unstable_Tooltip-arrow-rotation': 2,
  bottom: 'calc(0.5px + var(--Tooltip-arrow-size) * -1 / 2)',
},
'[data-popper-placement*="left"] &': {
  '--unstable_Tooltip-arrow-rotation': 1,
  right: 'calc(0.5px + var(--Tooltip-arrow-size) * -1 / 2)',
},
'[data-popper-placement*="right"] &': {
  '--unstable_Tooltip-arrow-rotation': 3,
  left: 'calc(0.5px + var(--Tooltip-arrow-size) * -1 / 2)',
},

siriwatknp avatar Dec 15 '22 06:12 siriwatknp

I can take this up and then I'll raise a PR and let you guys know. Is that okay or do you have any other suggestions or feedback? @siriwatknp @mnajdova

EswaramoorthyS avatar Dec 23 '22 10:12 EswaramoorthyS

I can take this up and then I'll raise a PR and let you guys know. Is that okay or do you have any other suggestions or feedback? @siriwatknp @mnajdova

Thanks for your interest! let's wait for a few weeks until we are all agreed on the format. I will tag you when it is ready to submit a PR!

siriwatknp avatar Jan 03 '23 04:01 siriwatknp

Jun and I agreed on using <ComponentName>-<slot><Property> (e.g., Slider-trackRadius) for CSS variable naming when it includes slots. Otherwise, it will be <ComponentName>-<property> (e.g., ListItem-radius)

I am taking this task.

hbjORbj avatar Feb 21 '23 11:02 hbjORbj

As a note on why using <ComponentName>-<slot><Property> instead of <ComponentName>-<slot>-<property>:

The variables are mostly hoisted at the root slot, so I don't see why we need to separate the slot with -.

const Root = styled('div')({
  '--ComponentName-radius': '...',
  '--ComponentName-trackRadius': '...',
})

const Track = styled('div')({
  borderRadius: 'var(--ComponentName-trackRadius'),
})

siriwatknp avatar Feb 22 '23 09:02 siriwatknp

@hbjORbj @siriwatknp may I take this up if we have come to a decision on the naming convention. Thanks

varunmulay22 avatar Mar 05 '23 09:03 varunmulay22