Material-ui: MuiFormLabel Focused color problem

Created on 5 May 2018  路  18Comments  路  Source: mui-org/material-ui

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Expected Behavior

When I create a new theme and override focused prop of MuiFormLabel, MaterialUI not used this new class because it create high new class that override my new class.

Current Behavior

Steps to Reproduce (for bugs)

  1. Create a new theme and override MuiFormLabel on color 'focused' prop https://material-ui-next.com/api/form-label/#css-api
  2. Create a component with a Texfield
  3. Apply new theme on your app

https://codesandbox.io/s/52poq578vn

Context

I need to change color label when the input is focus, in beta 41 it is work.

Your Environment

| Tech | Version |
|--------------|---------|
| Material-UI | beta 43+ |
| React | 16.3.2 |
| browser | Chrome, Firefox |

TextField question

Most helpful comment

@luiscdz We have recently documented the specificity change introduced: #11227. It applies to the overrides key too. You have two alternatives:

import React from "react";
import { TextField, createMuiTheme, ThemeProvider } from "@material-ui/core";

const theme = createMuiTheme({
  overrides: {
    MuiInputLabel: { // Name of the component 鈿涳笍 / style sheet
      root: { // Name of the rule
        color: "orange",
        "&$focused": { // increase the specificity for the pseudo class
          color: "blue"
        }
      }
    }
  }
});

function OverridesCss() {
  return (
    <ThemeProvider theme={theme}>
      <TextField value="value" label="label" />
    </ThemeProvider>
  );
}

export default OverridesCss;

https://codesandbox.io/s/q31w90krn9

Capture d鈥檈虂cran 2019-04-04 a虁 10 35 12
Capture d鈥檈虂cran 2019-04-04 a虁 10 35 16

All 18 comments

@luiscdz We have recently documented the specificity change introduced: #11227. It applies to the overrides key too. You have two alternatives:

import React from "react";
import { TextField, createMuiTheme, ThemeProvider } from "@material-ui/core";

const theme = createMuiTheme({
  overrides: {
    MuiInputLabel: { // Name of the component 鈿涳笍 / style sheet
      root: { // Name of the rule
        color: "orange",
        "&$focused": { // increase the specificity for the pseudo class
          color: "blue"
        }
      }
    }
  }
});

function OverridesCss() {
  return (
    <ThemeProvider theme={theme}>
      <TextField value="value" label="label" />
    </ThemeProvider>
  );
}

export default OverridesCss;

https://codesandbox.io/s/q31w90krn9

Capture d鈥檈虂cran 2019-04-04 a虁 10 35 12
Capture d鈥檈虂cran 2019-04-04 a虁 10 35 16

Can I use local override to do the same thing? I've tried the below setup but it gives me this warning: Warning: [JSS] Could not find the referenced rule focused in D8TextField.

Codes here:

const styles = (theme) => {
  return {
    formLabelRoot: {
      '&$focused': { color: 'green' }, // not working
      // color: 'cyan', // this is working
    },
    formLabelFocused: {
      '&$focused': { color: 'pink' }, // not working
      color: 'blue', // not working
    },
  };
};

class D8TextField extends React.Component {
  render() {
    return (
      <TextField
        // ...omitting some props
        InputLabelProps={{
          shrink: true,
          FormLabelClasses: {
            root: classes.formLabelRoot,
            focused: classes.formLabelFocused,
          },
        }}
      />
    );
  }
}

Mui version is 1.0.0-beta.45. By the way, the focused class provided here is applied to the form label (I mean the color: 'blue'), but the color property is still overided by the mui original one. Please check the attached image.
formlabel

Can I use local override to do the same thing?

@marsonmao Yes, you can. formLabelFocused -> focused.

@oliviertassinari Ohh got it! Finally I realized the rule, thanks! But I modified the key name to make it easier to write the style:

    formLabelRoot: { // must provide all of formLabelRoot && '&$formLabelFocused' && formLabelFocused
      '&$formLabelFocused': { color: theme.palette.primary.main },
    },
    formLabelFocused: {
      // color: 'green', // won't affect anything
    },

    <TextField
      InputLabelProps={{
        FormLabelClasses: {
          root: classes.formLabelRoot,
          focused: classes.formLabelFocused,
        },
      }}
    />

By the way...I found this part of FormLabel kina weird:

    '&$focused': {
      color: theme.palette.primary[theme.palette.type === 'light' ? 'dark' : 'light'],
    },

Is it a typo? (I mean should it be 'light' : 'dark'?)

@marsonmao I'm happy you have found a solution. No, it's not a typo. Does the specification ask for something else?

@oliviertassinari Ok then it's fine. I was just wondering if the light type should match the light theme, if it's the opposite then it's an intentionally made art decision.

@luiscdz We have recently documented the specificity change introduced: #11227. It applies to the overrides key too. You have two alternatives:

  overrides: {
    MuiFormLabel: {
      root: {
        color: "orange",
        "&$focused": {
          color: "red"
        }
      },
      focused: {
        "&$focused": {
          color: "yellow"
        }
      }
    }
  }

the only part that I didn't try before googling... thanks.

Is there any reason why the focused class doesn't apply styling to focused elements without stating the element with the class currently set as focused, being in focus?

Seems pointlessly redundant, why have a focused class at all and just add the internal state to the original control

@RyRy79261 We handle the focus class like a pseudo class (:focused, :hover, etc.) you have to increase specificity so you can scope the override to a specific state without messing the default one.

@oliviertassinari Thanks for the reply, but I'm failing to understand why the focused class would be assigned to an element that isnt in a focused state thus requiring being that specific.

I'm also struggling to see the scoping issue as applying styles to the root element made no difference, only an element with the class focus, that is also explicitly in focus had the css applied to it.

Is there a situation where an form element has the focus class applied to its label by the default behaviour of focusing on an input without said form element actually being in a state of focused?

I don't understand what you don't understand. The focused class is only applied when the input is focused. If the focused styles color had a specificity of one, it would be overriden when you change the non focused color. The prevent this problem, it has a specificity of two. The CSS specification used the same logic to define the pseudo classes specificity impact.

As an example

There's a label, when the label's input is in focus, the class name focused is added.

If you then unfocus, this class is removed, implying that the focused class is removed, thus the styling defined by the class titled focused should only be applied when the input is focused.

However, the definition here states, that even though that class, called focused, is only applied when that is the state, you then need to specify that the focused element is explicitly in a focused state.

logically:

.focused{
   // Focused styles
}

Actual:

.focused{
   "&$focused":{
       // styles
    }
}

This means that either specifying the state of focused, in a focus class is redundant, or having the focus class to apply in that state is redundant

Actual:

@RyRy79261 That's not how it should be done. It's should be something like this (in equivalent CSS #15140):

.mui-input-label.focused {
  color: red;
}

I have updated my misleading comment, sorry.

@oliviertassinari

Thank you, however my issue is that the code you added there does not render.
jss .focused{ "&$focused":{ // styles } }

Only when I do it like that does it work

@RyRy79261 Check this comment: https://github.com/mui-org/material-ui/issues/11244#issuecomment-386792253.

overrides: {
      MuiButton: {
        root: {
          "&$focused": {
            border: "2px solid #337DFD"
          }
        },

is not working for me. I can't find the styles in Chrome debugger at all, I don't think it's a case of them being overrided by more specific styles.

Help?

@JonasMS Make sure your custom theme is correctly applied.

Just to add a bit of insight here which might be useful for some.

Some of the component might allow for things like this:

// somewhere in the proj
const primaryColor = '#bada55';
const errorColor = '#ba0000';

// theme override:
// ...
MuiInputLabel: {
      root: {
        "&$shrink": {
          color: grey[900],
          "&$focused": {
            color: primaryColor,
          }
        },

        "&$error": {
          color: errorColor,

          "&$focused": {
            // notice this nesting; perfectly legal and overrides default specificity on theme level
            "&$shrink": {
              color: darker(errorColor, 0.5),
            }
          }
        }
      }
    },
// ....

Hope this might help someone.

Was this page helpful?
0 / 5 - 0 ratings