Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

material-ui makeStyles: how to style by tag name?

I want to add a rule for all <p> in the current component. I couldn't find information anywhere (material-ui documentation, Stack Overflow, etc.) on how to add CSS rules by tag name.

Is it not supported?

I'm trying to do something like this:

const useStyles = makeStyles((theme: Theme) =>
    createStyles({
        'p': {
            margin: 0,
        },
        someClass: {
            fontSize: 14,
        },
    })
);

EDIT:

Using Ryan's solution works, but creates a new problem:

import React from 'react';
import { makeStyles, Theme, createStyles } from '@material-ui/core';

const useStyles = makeStyles((theme: Theme) =>
    createStyles({
        root: {
            '& p': {
                margin: 0,
            },
        },
        // I want this rule to override the rule above. It's not possible in the current configuration, because `.root p` is more specific than `.title`
        // This problem originates from the fact that I had to nest the rule for `<p>` inside a CSS class
        title: {
            margin: '0 0 16px',
        },
    })
);

export default () => {
    const classes = useStyles({});

    return (
        <div className={classes.root}>
            <p className={classes.title}>My title</p>
            <p>A paragraph</p>
            <p>Another paragraph</p>
        </div>
    );
};
like image 960
Liran H Avatar asked Apr 21 '20 13:04

Liran H


People also ask

How do you give a style in material UI?

Luckily, Material-UI provides a solution for this: makeStyles . Using makeStyles , you can add CSS in JS without making your code look messy. First, you need to import makeStyles in your app. Next, pass all the CSS you need in your app as an object to makeStyles and store it inside a variable, useStyles .

How do you override MUI styles?

Overriding styles with class names If you want to override a component's styles using custom classes, you can use the className prop, available on each component.


1 Answers

Since you want this scoped to your component, you need a class to apply to your component (e.g. classes.root in the example below). Then you can target all p elements within that using & p. If you then need to override the p tag styling for another CSS class within your component, you can use another nested rule to target p tags that also have that class (e.g. classes.title in the example).

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

const useStyles = makeStyles(theme => ({
  root: {
    "& p": {
      margin: 0,
      "&$title": {
        margin: "0 0 16px"
      }
    }
  },
  title: {}
}));
export default function App() {
  const classes = useStyles();
  return (
    <div className="App">
      <p>This paragraph isn't affected.</p>
      <p>This paragraph isn't affected.</p>
      <div className={classes.root}>
        <p className={classes.title}>My title</p>
        <p>A paragraph</p>
        <p>Another paragraph</p>
      </div>
    </div>
  );
}

Edit Target nested tags in JSS

Related documentation: https://cssinjs.org/jss-plugin-nested?v=v10.1.1#use--to-reference-selector-of-the-parent-rule

like image 158
Ryan Cogswell Avatar answered Oct 11 '22 05:10

Ryan Cogswell