1

I'm trying to use style-components to style the underline of a select component. I sucessfully styled the underline of an Input component. I'm aware that Select is a wrapper of Input but for some reason the same code does not work for Select.

import Select from "@material-ui/core/Select";
import styled from "styled-components";

const StyledSelect = styled(Select)`
  && {
    && .MuiInput-underline {
      border-bottom: 2px solid green;
    }
    /* default */
    .MuiInput-underline:before {
      border-bottom: 2px solid green;
    }
    /* hover (double-ampersand needed for specificity reasons. */
    && .MuiInput-underline:hover:before {
      border-bottom: 2px solid lightblue;
    }
    /* focused */
    .MuiInput-underline:after {
      border-bottom: 2px solid red;
    }
  }
`;

export default StyledSelect;

codesandbox

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198

1 Answers1

1

The main issue is that you are targeting the MuiInput-underline class as if it is a descendant of the Select, but the root div (the one that the styled-components class name will be applied to) of the Select is the element with the MuiInput-underline class.

Below is an example of the correct syntax:

import Select from "@material-ui/core/Select";
import styled from "styled-components";

const StyledSelect = styled(Select)`
  /* default */
  &.MuiInput-underline:before {
    border-bottom: 2px solid green;
  }
  /* hover */
  &.MuiInput-underline:hover:before {
    border-bottom: 2px solid lightblue;
  }
  /* focused */
  &.MuiInput-underline:after {
    border-bottom: 2px solid red;
  }
`;

export default StyledSelect;

Edit TextField underline styled-components

I also made a change to index.js to wrap everything in <StylesProvider injectFirst>. This should generally be used when you are using styled-components with Material-UI so that the Material-UI styles come first in the <head> instead of last. Then the styled-components styles will come after the Material-UI styles and win when specificity is otherwise the same. This avoids needing to double up class names (e.g. using &&) as much to increase specificity.

import React from "react";
import ReactDOM from "react-dom";
import Demo from "./demo";
import { StylesProvider } from "@material-ui/core/styles";

ReactDOM.render(
  <StylesProvider injectFirst>
    <Demo style={{ width: "200px" }} value={1} />
  </StylesProvider>,
  document.querySelector("#root")
);

Related answer: Material-UI 4.1.2 Styling Select SelectInput

Ryan Cogswell
  • 75,046
  • 9
  • 218
  • 198