0

I tried to clone one navbar. It's here: navbar

And you can see, when we hover to a section like "BOOK". There is a orange rectangle which appears and higher than navbar. And that div(orange) is between the background of navbar(black) and the text.

I think this is a div but I can not create that div because, if I put a Sibling Element after the .list-item div, after that I hover to it. I cannot see the text 'BOOK' because that div is on the higher layout compare to the .list-item div.

body {
    margin: 0;
 padding: 0;
 font-family: Roboto, sans-serif;
}

header {
 text-align: center;
 padding-bottom: 3rem;
}

nav {
 width: 100%;
 display: flex;
 justify-content: center;
 margin: 0 auto;
 color: white;
 background: black;
}

ul {
    margin: 0;
    padding: 0;
 display: flex;
 width: 85%;
 font-weight: 600;
}

li {
    list-style-type: none;
 cursor: pointer;
 padding: 0 1.6rem;
 line-height: 3;
}

li:hover {
 background-color: tomato;
 transition: 220ms ease;
}

.list-item span {
 padding-right: 0.4rem; 
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
    <link rel="stylesheet" href="style.css">
    <title>Document</title>
</head>
<body>
    <header>
        <h3>
            E-SHOP
        </h3>
    </header>
    <nav>
        <ul>
            <li>
                <div class="list-item">
                    <span>HOME</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>
            <li>
                <div class="list-item">
                    <span>BOOK</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>
            <li>
                <div class="list-item">
                    <span>AUDIO BOOKS</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>
            <li>
                <div class="list-item">
                    <span>CHILDREN'S BOOKS</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>
            <li>
                <div class="list-item">
                    <span>BLOG</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>
            <li>
                <div class="list-item">
                    <span>PAGES</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>
            <li>
                <div class="list-item">
                    <span>SALES OFF</span>
                    <i class="fas fa-angle-down"></i>
                </div>
            </li>                             
        </ul>
    </nav>
</body>
</html>
Ken Hoàng
  • 47
  • 5

2 Answers2

3

You can get this effect using pseudo elements. You can create a triangle by injecting a zero-sized item that has two colored and two transparent borders:

/* Set position to relative so we know where to put our pseudo
   elements */
li {
  /* ... */
  position: relative;
}

/* Create a rectangle bar above the nav element */
li:hover::before {
  content: "";
  position: absolute;
  height: 20px;
  width: 100%;
  top: -20px;
  left: 0;
  background: tomato;
}

/* Create a small triangle flag on the top right */
li:hover::after {
  content: "";
  position: absolute;
  top: -20px;
  right: -20px;
  border: 10px solid green;
  border-right-color: transparent;
  border-top-color: transparent;
}

In your example:

body {
  margin: 0;
  padding: 0;
  font-family: Roboto, sans-serif;
}

header {
  text-align: center;
  padding-bottom: 3rem;
}

nav {
  width: 100%;
  display: flex;
  justify-content: center;
  margin: 0 auto;
  color: white;
  background: black;
}

ul {
  margin: 0;
  padding: 0;
  display: flex;
  width: 85%;
  font-weight: 600;
  margin-top: -20px;
}

li {
  list-style-type: none;
  cursor: pointer;
  padding: 20px 1.6rem 0 1.6rem;
  line-height: 3;
  position: relative;
  transition: 220ms ease;
}

li:hover {
  background-color: tomato;
}

li::after {
  content: "";
  position: absolute;
  top: 0;
  right: -20px;
  border: 10px solid green;
  border-right-color: transparent;
  border-top-color: transparent;
  opacity: 0;
  transition: opacity 220ms ease;
}

li:hover::after,
li:hover::before {
  opacity: 1;
}

.list-item span {
  padding-right: 0.4rem;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
  <link rel="stylesheet" href="style.css">
  <title>Document</title>
</head>

<body>
  <header>
    <h3>
      E-SHOP
    </h3>
  </header>
  <nav>
    <ul>
      <li>
        <div class="list-item">
          <span>HOME</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
      <li>
        <div class="list-item">
          <span>BOOK</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
      <li>
        <div class="list-item">
          <span>AUDIO BOOKS</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
      <li>
        <div class="list-item">
          <span>CHILDREN'S BOOKS</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
      <li>
        <div class="list-item">
          <span>BLOG</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
      <li>
        <div class="list-item">
          <span>PAGES</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
      <li>
        <div class="list-item">
          <span>SALES OFF</span>
          <i class="fas fa-angle-down"></i>
        </div>
      </li>
    </ul>
  </nav>
</body>

</html>
user3297291
  • 22,592
  • 4
  • 29
  • 45
  • but it's seems not smooth because it's actually 2 separate orange parts. – Ken Hoàng Oct 09 '18 at 13:03
  • 1
    I fixed the jitter by using a negative margin to have the `
  • ` stick out of its `
      ` at the top, and removing one of the two pseudo elements. Have a look at the snippet to see the improved result. I kind of wanted to just explain the psuedo elements and let you solve the other issues, but now you can copy paste ;)
  • – user3297291 Oct 09 '18 at 13:11
  • you are very kind!. Thank you so much! – Ken Hoàng Oct 09 '18 at 13:20
  • Because I hard to find the examples of beautiful code. I see some on Youtube but most of them are basic and I think that without examples of code I cannot to be good at css because of less creative. Could you share some source or some some advice to learn css for modern web? – Ken Hoàng Oct 09 '18 at 13:27
  • 1
    I think you're on the right track by looking up examples of cool things you'd like to build, and then try to create them yourself! I like learning by doing and asking questions along the way :) Make sure to research before asking, and to research again *after* getting an answer. E.g.: now that you've seen pseudo elements, [read about them om MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) to find out more cool things you can do. And now that you've seen the "triangle-trick", read [this article](https://css-tricks.com/snippets/css/css-triangle/) to learn *why* it works. – user3297291 Oct 09 '18 at 13:32
  • Thank you so much! – Ken Hoàng Oct 09 '18 at 13:35
  • I still don't understand completely, When I change some code, add content and comment some lines: ` li::after { content: "abcdef"; position: absolute; top: 0; right: -20px; /* border: 5px solid green; border-right-color: transparent; border-top-color: transparent; opacity: 0; transition: opacity 220ms ease; */ } ` I relize that li::after has the width = length of string (abcdef). And what I don't understand is why that String doesn't start at the padding edge ( I see in here https://stackoverflow.com/questions/28080910/what-does-top-0-left-0-bottom-0-right-0-mean ) – Ken Hoàng Oct 09 '18 at 14:44
  • 1
    The property `right` aligns the *right* side of the `li::after` element to the *right* side of its first relatively positioned container. By specifying `right: -20px` you are essentially saying: "I want the right edge of the `li::after` to appear `20px` to the right of the `li`'s right edge" – user3297291 Oct 09 '18 at 14:47
  • Let see the image here https://ibb.co/d5kJjU, I don't understand why the text does not start at padding edge of li – Ken Hoàng Oct 09 '18 at 14:55
  • 1
    If you want to match the pseudo element's left edge to the parent's right edge, you better use `left: 100%`: https://codepen.io/anon/pen/yRMBrW – user3297291 Oct 09 '18 at 15:29