Search code examples
htmlcssmaterialize

I cannot overide a style from materialize


I am trying to apply the style to the .lvl-2 to apply an indent to a particular div, but it is getting overriden by something in materialize.

Chrome inspector scrennshots below

the style that overrides

My style in inspector

I have some HTML (below is excerpt it is in a list)

       <li key={elements.index}>
          <div className="row">
            <div className="col red s4">f</div>
            <div className="col blue s8">f</div>
          </div>
          <div className="row">
            <div className="col red s4 lvl-2">indented</div>
            <div className="col green s8">f</div>
          </div>

I have some CSS

li> .lvl-2 {
  padding: 0 0 0 10px;
}

I have also tried being more specific but when I do inspector doesn't see the style at all (which is wierd )

li div> div .lvl-2 {
  padding: 0 0 0 10px;
}

The problem is that when I view in the inspector it say that the style is being overwritten by the style below from materialize

ul:not(.browser-default) {
  padding-left: 0;
  list-style-type: none;
}

Unfortunately if I just override it it won't work because I want different syles on different li's

ul:not(.browser-default) {
  padding: 0 0 0 10px;
  list-style-type: none;
}

Solution

  • Your CSS was incorrect defined, that's the reason why you don't see your style applied.

    With your HTML markup:

    <li key={elements.index}>
      <div className="row">
        <div className="col red s4">f</div>
        <div className="col blue s8">f</div>
      </div>
      <div className="row">
        <div className="col red s4 lvl-2">indented</div>
        <div className="col green s8">f</div>
      </div>
    </li>

    And you want to style .lvl-2, the proper one should be : li .row .lvl-2 {} ,

    Of course the CSS specificity might not be stronger than the one defined in Material UI, in that case you should add more specificity, something like: ul li > .row > .col.lvl-2

    Please, never ever using "!important" unless you're forced to. In this scenario, it's still quite easy to fix and this will save your future-self.

    ========= Updated answer on Nov 18th:

    Let's go through each of your attempt one by one and see what went wrong:

    1)

    li> .lvl-2 {
      padding: 0 0 0 10px;
    }
    

    This means "get all the direct child elements with .lvl-2 class from li", this won't apply because your HTML markup is different.

    To be more specific, your lvl-2 element has a wrapper div with class row, as of now the direct children from li are divs with .row class. The > stands for "get direct child`.

    If you want to use direct selector, the selector should be like li .row > .lvl-2.

    2)

    li div> div .lvl-2 {
      padding: 0 0 0 10px;
    }
    

    Once again, the CSS won't run because your HTML markup is different from what your CSS defines.

    In this case, it means "from any li element, select all divs children, from each selected div, get all direct div children, then get all element with .lvl-2 class from each direct selected div.".

    That might be hard to get the first time, but let me show you the HTML markup which will work in your second attempt.

    <li>
      <div class="wrapper">
        <div class="child">
          <div class="lvl-2">
          </div>
        </div>
      </div>
    </li>
    

    or even another markup

    li
      div
        div
          div
            div.lvl-2
    

    To answer for your question, I think you should read on this article, it will help you easier than my explanation "https://dev.to/emmawedekind/css-specificity-1kca"

    In your scenario, and also from my experience, you should define CSS selectors using class, not with type selectors (e.g like div, li, button).

    • Type selector is the lowest priority in CSS specificity calculation. Use with caution.

    • In term of project scalability, using type selector means you're forcing the element to be that specific type. E.g: li span means only the <span> tag, what happens if another developer or an upcoming request change, that tag needs to be replaced with a div. So saving your future-self, use with classes like li .item, it will both apply either to <li> <span class="item"> or <li> <div class="item">.

    • It reduces confusion as much as possible, and increase readability CSS code. Reading something .list .item always helps a clearer vision than a li span.

    • Most of the time, when your Frontend architect depends on a 3rd party like Bootstrap or Material-UI, they all use class selectors. To override them, the only way is to use class selectors.

    Hope this helps,