Search code examples
htmlcssbackground-imagebackground-color

background-color defined in parent and its child, nither of them succeed


Having this html:

        body {
            font-family: Arial, Helvetica, sans-serif;
        }

        header {
            background-color: rgb(93, 43, 78);
            background-image: -webkit-linear-gradient(right, rgb(93, 43, 78), rgb(8, 2, 50)); /* no color in background */
        }

        header nav {
            background-color: red; /* neither here, still white background */
        }

        header ul {
            list-style: none;
        }

        header li {
            float: left;
            color: black;
        }

        p {
            clear: both;
        }
<html>
<body>
    <header>
        <nav>
            <ul>
                <li>test item1</li>
                <li>test item2</li>
            </ul>
        </nav>
    </header>
    <section>
        <br />
        <p>some text</p>
    </section>
</body>
</html>

I am not able to see background nither for the header parent element, nor for the nav child element (of the header). Both are trying to make a background with some color or effect, but neither of them succeed. Why?


Solution

  • This is one of the problems with using float... it takes the element out of the flow so the parent have no content and therefore no height. The workaround is the "clearfix" hack - basically, it forces the parent to take the height of its children.

    You can create a clearfix class and apply it to the parent of any floated elements:

    .clearfix::after {
      content: "";
      clear: both;
      display: table;
    }
    

    Expand to see a working example:

    body {
      font-family: Arial, Helvetica, sans-serif;
    }
    
    header {
      background-color: rgb(93, 43, 78);
      background-image: -webkit-linear-gradient(right, rgb(93, 43, 78), rgb(8, 2, 50));
      /* no color in background */
    }
    
    header nav {
      background-color: red;
      /* neither here, still white background */
    }
    
    header ul {
      list-style: none;
    }
    
    header li {
      float: left;
      color: black;
    }
    
    p {
      clear: both;
    }
    
    .clearfix::after {
      content: "";
      clear: both;
      display: table;
    }
    <html>
    
    <body>
      <header>
        <nav class="clearfix">
          <ul>
            <li>test item1</li>
            <li>test item2</li>
          </ul>
        </nav>
      </header>
      <section>
        <br />
        <p>some text</p>
      </section>
    </body>
    
    </html>

    Flexbox - a modern alternative to float

    However a better options these days is to use flexbox - you can achieve a similar effect but without the hack, and it is also more flexible (as the name suggests!)

    You just need to make the direct parent of the elements (in this case the ul) display: flex and it will automatically place the elements into the available space horizontally, e.g.

    Simple Flexbox example using your code

    body {
      font-family: Arial, Helvetica, sans-serif;
    }
    
    header {
      background-color: rgb(93, 43, 78);
      background-image: -webkit-linear-gradient(right, rgb(93, 43, 78), rgb(8, 2, 50));
      /* no color in background */
    }
    
    header nav {
      background-color: red;
    
    }
    
    header ul {
      list-style: none;
      display: flex;
    }
    
    header li {
      color: black;
    }
    
    p {
      clear: both;
    }
    <html>
    
    <body>
      <header>
        <nav>
          <ul>
            <li>test item1</li>
            <li>test item2</li>
          </ul>
        </nav>
      </header>
      <section>
        <br />
        <p>some text</p>
      </section>
    </body>
    
    </html>

    This is just the tip of the iceberg when it comes to the abilities of flexbox. Take a look at the references below to see what you can do!

    More about flexbox