skip to Main Content

When using Styled Components with MUI System Props I found that the styled component styling takes precedence, for example in the snippet below the box would render with justify content set as space-around:

const CustomBox = styled(Box)(() => ({
  display: 'flex',
  justifiyContent: 'center'
}));

function MyComponent() (
  <CustomBox justifyContent='space-around'>
    <span className='some-icon'></span>
    <span>some text</span>
  </CustomBox>
)

I could manage this "the styled components way" and pass a prop to CustomBox, but I find it counter-intuitive that the MIUI system prop looks like a local override, but is overriden by the component it’s being applied to.

Is there some configuration available in MUI that would make MUI System Props take precedence over Styled Components stylings?

2

Answers


  1. The styles attached with styled is overridden by the sx prop on the component. Usually this can be used to add any additional local styles to a styled component with MUI.

    Unless specified to disable it, styled also add support for the sx prop by default if used with a base JSX component such asdiv, for quick style overrides.

    More examples on a demo: stackblitz

    const CustomBox = styled(Box)({
      display: 'flex',
      justifyContent: 'center',
    });
    
    const MyComponent = () => {
      return (
        <CustomBox sx={{ justifyContent: "flex-start" }}>
          <span className="some-icon"></span>
          <span>some text</span>
        </CustomBox>
      );
    };
    
    Login or Signup to reply.
  2. If you want the props passed to the CustomBox to win over your style overrides, then you should take the props into account in your styling:

    import * as React from "react";
    import Box from "@mui/material/Box";
    import { styled } from "@mui/material/styles";
    const CustomBox = styled(Box)(({ display, justifyContent }) => ({
      display: display === undefined ? "flex" : display,
      justifyContent: justifyContent === undefined ? "center" : justifyContent
    }));
    export default function BoxSx() {
      return (
        <>
          <CustomBox>
            <span>Span 1 - no changes</span>
            <span>Span 2 - no changes</span>
          </CustomBox>
          <CustomBox justifyContent="space-around">
            <span>Span 1 - justifyContent="space-around"</span>
            <span>Span 2 = justifyContent="space-around"</span>
          </CustomBox>
          <CustomBox
            justifyContent="space-around"
            sx={{ justifyContent: "space-between" }}
          >
            <span>Span 1 - sx justifyContent="space-between"</span>
            <span>Span 2 = sx justifyContent="space-between"</span>
          </CustomBox>
          <CustomBox display="none">
            <span>Span 1 - display="none"</span>
            <span>Span 2 - display="none"</span>
          </CustomBox>
        </>
      );
    }
    

    Edit CustomBox

    As far as why the props don’t automatically take precedence — the props change the default styling for the Box and that default styling is what the styled API is then overriding. Since the styled API gives you access to those props, it allows you to decide how those props interact with your styling.

    In contrast, the sx prop provides styles that are applied with a different precedence than the default styles, so providing justifyContent within sx wins over both the props and styles provided via styled.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search