Exploring Material UI Styled Components: Mastering the Art of Styling Child Elements

Context

In my React project, I am utilizing the styled() utility function provided by Material UI to apply styles to my components. The issue arises when trying to style an imported component that has already been styled with this utility function. Despite defining new styles in the parent component, the styling from the base component remains unchanged. Here is an example to illustrate this:

import { styled } from "@mui/material";

function App() {
  const StyledChild = styled(Child)(({ theme }) => {
    console.log("called from App");

    return {
      backgroundColor: "black"
    };
  });

  return <StyledChild />;
}

function Child() {
  const Div = styled("div")(({ theme }) => {
    console.log("called from Child");

    return {
      backgroundColor: "red"
    };
  });

  return <Div>hello world</Div>;
}

export default App;

The console output shows:

called from App

called from Child

codesandbox

Problem Statement

Despite attempting to style the imported component in the parent component, as demonstrated in the codesandbox example, only the original base styling of backgroundColor: 'red' is retained. The newly defined styling of backgroundColor: 'black' does not override it, even though the console logs indicate otherwise.

Inquiry

  • How can a component that has already been styled be effectively restyled?
  • Why does the solution provided above fail to work as expected? Shouldn't the use of the styled() utility function result in the applied styling as defined in the returned object?

Update

After further investigation, it seems that even removing the initial style of Child does not allow the parent-level styling to take effect.

import { styled } from "@mui/material";

function App() {
  const StyledChild = styled(Child)(({ theme }) => {
    console.log("called from App");

    return {
      backgroundColor: "black"
    };
  });

  return <StyledChild />;
}

function Child() {

  return <div>hello world</div>;
}

export default App;

Even without the inclusion of backgroundColor: "black" at the parent level, the styling does not change, leading to a revised question title - How can styling be applied to a child component at the parent level?

Answer №1

After spending a few days troubleshooting the issue, I finally pinpointed the root cause and came up with a viable solution. Hopefully, this will help others facing a similar problem in the future.

The initial issue was that the parent's styling was not affecting the child component. The culprit turned out to be missing code in the child component:

function Child({ ...others }) { //function component
. Additionally, I needed to include {...others} as an attribute within the component itself. Here is the complete solution:

import { styled } from "@mui/material";

function App() {
  const StyledChild = styled(Child)(({ theme }) => {
    console.log("called from App");

    return {
      backgroundColor: "black"
    };
  });

  return <StyledChild />;
}

function Child({ ...others }) {
  const Div = styled("div")(({ theme }) => {
    console.log("called from Child");

    return {
      backgroundColor: "red"
    };
  });

  return <Div { ...others }>hello world</Div>;
}

export default App;

It seems that the parent styling is applied through classes internally (any documentation links on this would be appreciated). These classes must be added as attributes of the Child element for the styling to work correctly.

Visit codesandbox for the solution

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Reposition a div using jQuery when window is resized

I'm currently facing a challenge with the web project I am working on for my company. The code snippet I have looks like this: //CSS .home-panel{ z-index: 0; width: 1800px; height: 2100px; background: gray; transform: skew(0deg,-55deg) ...

Struggling to make divs disappear using the .each() method following an ajax call?

Currently, my divs are loaded one by one on page load and everything is working perfectly. However, I encounter an issue when making an AJAX request and then using append(data) to the same container. In this scenario, my code ends up looping through all of ...

The AutoComplete feature in Formik Field from Material UI component is not showing the InitialValues

Having an issue with displaying the initialValues in the AutoComplete component from the Material UI library when used in a Formik Field. Even though values are passed as initial, they do not render in the component, although if the form is submitted, they ...

Animation in Three.JS not visible in Chrome version 61 on Mac OS X Sierra

I've been going through some beginner tutorials for three.js and I'm facing an issue where I only see a red background when I try to run the code I created in Atom on Chrome (Version 62.0.3202.75 (Official Build) (64-bit)), Mac OS X (macOS Sierra ...

Retrieve every video on React.js channel from YouTube

Currently, I am working on integrating react-youtube into my React App with the goal of accessing all videos from a specific YouTube channel. The challenge I am facing is that I need to display these videos as thumbnails, exactly how they are listed in the ...

The loading bar function seems to be malfunctioning when paired with the navbar element <nav> in an HTML document

Can you assist me with a coding issue I am facing? I have implemented a loadingbar on my webpage similar to YouTube, and it works perfectly on the page itself. However, when I try to integrate it with a navigation bar, it stops working. Below is the code ...

None of the angular directives are functioning properly in this code. The function attached to the submit button is not executing as expected

I've experimented with various Angular directives in this code, but none seem to be functioning properly. I'm wondering if a library file is missing or if there's some issue within the code itself, potentially related to the jQuery file. The ...

Double invocation of useEffect causing issues in a TypeScript app built with Next.js

My useEffect function is set up with brackets as shown below: useEffect(() => { console.log('hello') getTransactions() }, []) Surprisingly, when I run my app, it logs "hello" twice in the console. Any thoughts on why this might be ...

Hovering over a link causes malfunction in CSS drop-down menu

I have been struggling for hours to make this drop-down menu work, but it just won't cooperate. I want the list menu .dropdown to appear when you hover over .droptoggle. I'm including the entire page because I can't figure out what's wr ...

Having trouble with installing "npm install semantic-ui-react semantic-ui-css"? Any ideas on how to fix it?

Encountered an error while trying to install Semantic UI React and Semantic UI CSS: npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: [email protected] npm ERR! Found: [ema ...

Set navigation to switch to `position: fixed` after scrolling a certain distance

I'm currently working on adjusting the navigation to have a position: fixed right below the black header. I suspect that there might be some necessary tweaks needed in the JavaScript code, but I'm unsure about the specific changes required at thi ...

Testing the isAllowed function in React Number Format unit test.IsAllowed unit

I am currently utilizing the React Number Format library to handle number inputs in my application. <TargetRow> <NumberFormat type="text" isNumericString={true} ...

Stop child element from extending parent container dimensions

I am facing a scenario where I have a fixed-position container element with two children. Both children contain text. The challenge is to dynamically adjust the width of the container based on one child's content, while ensuring that the other child&a ...

I can't figure out why my CSS transition isn't functioning properly in React 18

I've attempted multiple times to implement a transition on eventBody, but it still isn't functioning correctly. Here's the snippet of code: export function Event({ event }: EventProps) { const [showDropDown, setShowDropDown] = useStat ...

Set a looser Cross-Origin Resource Policy to avoid blocking a particular resource

I am in the process of building a fullstack app using PHP, React JS, and graphQL. I attempted to deploy the app to 000webhost but encountered an error. Upon checking the network, I noticed that I received a 200 status response, however, the data is being r ...

Utilizing chart.js data source plugin in React application (react2chartjs)

Upon receiving inspiration from a question regarding importing data from Excel and presenting it as charts using ChartJs (Import data from Excel and use in Chart.js), I was able to successfully achieve this goal. However, my attempt to replicate this proce ...

Once I incorporated Bootstrap into my project, I noticed a noticeable white space between the div elements

Welcome to My Code Playground I was sailing smoothly with my project until I decided to include Bootstrap. Seems like there's something missing in the details, so here I am reaching out. If you spot the issue, please feel free to correct my code. &l ...

Update the default monospaced font in Draft.js

Is it possible to change the default system monospace font in Draft Editor to Consolas using Draft.css or global css classes? ...

Is TypeScript React.SFC encountering incompatibility issues with types?

Trying to figure out TypeScript but struggling to get rid of these persistent errors. I've tried multiple approaches and resorted to using any wherever possible, but the errors still persist: (9,7): Type '(props: IRendererProps & { children? ...

The display of the page disintegrates during the rendering process in <Rails>

While experimenting with Rails, I created a sample app but encountered a problem with the page format when it is rendered. The text fields shift out of place and the overall format gets ruined. You can check out the issue on this site, just click the butto ...