Sam YC
Sam YC

Reputation: 11637

react jss how to style custom html tag

I am using material-ui, see the sample code below:

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';

const useStyles = makeStyles((theme) => ({
  root: {
    '& > *': {
      margin: theme.spacing(1),
    },
  },
}));

export default function ContainedButtons() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <Button variant="contained">Default</Button>
      <Button variant="contained" color="primary">
        Primary
      </Button>
      <Button variant="contained" color="secondary">
        Secondary
      </Button>
      <Button variant="contained" disabled>
        Disabled
      </Button>
      <Button variant="contained" color="primary" href="#contained-buttons">
        Link
      </Button>
    </div>
  );
}

This is first time I use jss, I try to play around with & > * to understand how it works, I guess it is some sort of css selector, but check through the doc here and here, I am confused with below:

  1. * and > are valid css selector, I can understand, but what is & meaning there?

  2. I want to limit the css selector to be applied to button only, should I use & > button or & > Button? Both are working, but I am confused, in the end, what to be displayed to browser is button, so it is better to use & > button?

Upvotes: 3

Views: 1332

Answers (1)

Steve Cruz
Steve Cruz

Reputation: 186

Question 1: JSS and other third-party React libraries such as styled-components port SCSS (Sass) functionalities to provide extended CSS features for CSS-in-JS.

You have not seen & in CSS because it is a SCSS (Sass) feature. Sass is a preprocessor scripting language that extends the normal CSS with more features:

  • It allows you to use nesting when styling your components or html elements.
  • & is the parent selector. It references the HTML element where it is nested.

In this case & references root since it is directly nested inside it. & > * applies the styling to all elements (*) that are direct descendants (>) of root (&).

root: {
  '& > *': {
    margin: theme.spacing(1),
  }
}

Example: & can make you life easier, a good example is applying a hover state to a button.

In normal CSS you would do this:

button {
  background-color: tomato;
}

button:hover {
  opacity: 0.5;
}

With SCSS you could use nesting and the parent selector (&) to do this:

button {
  background-color: tomato;
  &:hover {
  opacity: 0.5;
  }
}
  1. Reference: https://cssinjs.org/from-sass-to-cssinjs
  2. Reference: https://sass-lang.com/documentation/style-rules/declarations#nesting
  3. Reference: https://sass-lang.com/documentation/style-rules/parent-selector
  4. Reference: https://styled-components.com/docs/faqs#can-i-nest-rules

Question 2: In ReactJS components start with an uppercase letter while HTML Elements start with a lowercase letter. So Button is a React component and button is the vanilla HTML element.

You can create a Button component that is made of a button with an img and a p inside.

& > Button will select all Button react components that are direct descendant of & (The value of & depends on the rest of your code, with the information I gave you above you'll be able to figure it out) while & > will select all button HTML elements that are direct descendants of &.

Example: Imagine a situation where you have div that contains a Button React Component (has a button HTML element in its composition) and a ToggleButton React Component (has a button HTML element in its composition):

  • If you use & > Button, you only will select the button HTML element in the Button that is a direct descendant of the div (&).
  • If you use & > button, you only will select the button HTML element in Button and in ToggleButton that are direct descendants of the div (&).

Upvotes: 3

Related Questions