skip to Main Content

My menu has 2 borders: the main vertical border on the right of the whole menu and the border (top, bottom, left) of the active item. The right border of the active item should be empty. The main border should be interrupted in the same place where the active item right border was interrupted. Note that any of the items could be active, that is why the main border interruption can’t be hardcoded

.container {
  border-right: 1px solid;
  width: 200px;
  padding-top: 20px;
  padding-bottom: 20px;
}

.item {
  padding: 10px;
}

.active {
  border-top: 1px solid;
  border-bottom: 1px solid;
  border-left: 1px solid;
}
<div class="container">
  <div class="item active">
    Test1
  </div>
  <div class="item">
    Test2
  </div>
  <div class="item">
    Test3
  </div>
</div>

enter image description here

5

Answers


  1. To get the expected output rewrite the above styles :

    .container {
      width: 200px;
      padding-top: 20px;
      padding-bottom: 20px;
      border-right:1px solid black
    }
    
    .item {
      width: 179px;
      padding: 10px;
    }
    
    .item:first-child {
      border-right: 1px solid white;  
    }
    
    .active {
      border-top: 1px solid;
      border-bottom: 1px solid;
      border-left: 1px solid;
    }
    <div class="container">
      <div class="item active">
        Test1
      </div>
      <div class="item">
        Test2
      </div>
      <div class="item">
        Test3
      </div>
    </div>
    Login or Signup to reply.
  2. You can’t "interrupt" a border of a container for a specific child.

    The only option is to "hide" that section of the border with a colored border on the child over that border section.

    I’d suggest a positioned pseudo-element with the same background at the background of the container.

    .container {
      border-right: 1px solid;
      width: 200px;
      padding-top: 20px;
      padding-bottom: 20px;
    }
    
    .item {
      padding: 10px;
    }
    
    .item.active {
      border-top: 1px solid;
      border-bottom: 1px solid;
      border-left: 1px solid;
      position: relative;
    }
    
    .item.active::after {
      content: "";
      height: 100%;
      width: 1px;
      position: absolute;
      top: 0;
      right: -1px;
      background: white;
    }
    <div class="container">
      <div class="item active">
        Test1
      </div>
      <div class="item">
        Test2
      </div>
      <div class="item">
        Test3
      </div>
    </div>
    Login or Signup to reply.
  3. To achieve this behavior, set the active element’s background to an opaque color and set the width of active element to:

    containerWidth - padding * 2
    

    With containerWidth being width of the parent container element and padding the padding size of active element. In this case its 180px:

    .container {
      border-right: 1px solid;
      width: 200px;
      padding-top: 20px;
      padding-bottom: 20px;
    }
    
    .item {
      padding: 10px;
    }
    
    .active {
      border-top: 1px solid;
      border-bottom: 1px solid;
      border-left: 1px solid;
      width: 180px;
      background-color: #fff;
    }
    <div class="container">
      <div class="item active">
        Test1
      </div>
      <div class="item">
        Test2
      </div>
      <div class="item">
        Test3
      </div>
    </div>
    Login or Signup to reply.
  4. You can add a box-shadow for the right part to hide the border.

    .container {
      border-right: 1px solid;
      width: 200px;
      padding-top: 20px;
      padding-bottom: 20px;
    }
    
    .item {
      padding: 10px;
    }
    
    .active {
      border-top: 1px solid;
      border-bottom: 1px solid;
      border-left: 1px solid;
      box-shadow: 1px 0px 0px 0px white;
    }
    <div class="container">
      <div class="item active">
        Test1
      </div>
      <div class="item">
        Test2
      </div>
      <div class="item">
        Test3
      </div>
    </div>
    Login or Signup to reply.
  5. You can add the margin-right: -1px; and background: white; into the .active class CSS.

    .container {
      width: 200px;
      padding-top: 20px;
      padding-bottom: 20px;
      position: relative; 
      border-right: 1px solid;
    }
    
    .item {
      padding: 10px;
      position: relative; 
    }
    
    .active {
      border-top: 1px solid;
      border-bottom: 1px solid;
      border-left: 1px solid;
      margin-right: -1px;
      background: white;
    }
    <!DOCTYPE html>
    <html>
      <head>
        <title>Hello World!</title>
        <link rel="stylesheet" href="styles.css" />
      </head>
      <body>
          <div class="container">
            <div class="item active">
              Test1
            </div>
            <div class="item">
              Test2
            </div>
            <div class="item">
              Test3
            </div>
          </div>
          <script>
            const items = document.querySelectorAll('.item');
    
            function RemoveActive() {
                for (let i = 0; i < items.length; i++) {
                    if (items[i].classList.contains('active')) {
                        items[i].classList.remove('active');
                    }
                }   
            }
    
            for (let i = 0; i < items.length; i++) {
                items[i].addEventListener('click', function() {
                    RemoveActive();
                    items[i].classList.add('active');
                })
            }
          </script>
      </body>
    </html>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search