Home > Blockchain >  How to connect two rectangles together with rounded connections, like tabs?
How to connect two rectangles together with rounded connections, like tabs?

Time:11-29

In the Chrome web browser, tabs have a rounded connection to the white bar beneath them:

enter image description here

enter image description here

I was wondering how to achieve this effect on the following code, preferably with pure CSS.

#bar {
  width: 200px;
  height: 50px;
  background-color: gray;
}

.tab {
  width: 75px;
  height: 25px;
  background-color: lightgray;
  border-radius: 8px 8px 0 0;
  margin-left: 1rem;
}

.flex {
  display: flex;
}
<div class="flex">
  <div class="tab"></div>
  <div class="tab"></div>
 </div>
<div id="bar"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Thank you for any help!

CodePudding user response:

With pure CSS, but two additional tags added for the corners:

#bar {
  width: 200px;
  height: 50px;
  background-color: green;
}

.tab {
  width: 75px;
  height: 25px;
  background-color: blue;
  border-radius: 8px 8px 0 0;
  margin-left: 1rem;
  position:relative;
}

.flex {
  display: flex;
}
.curved-corner-bottomleft::before {
    bottom: 0;
    left: 0;
    box-shadow: -5px 5px 0 0 red;
}
.curved-corner-bottomright::before {
    bottom: 0;
    right: 0;
    box-shadow: 5px 5px 0 0 red;
}
.curved-corner-bottomleft::before, 
.curved-corner-bottomright::before {
    content: "";
    display: block;
    width: 200%;
    height: 200%;
    position: absolute;
    border-radius: 50%;
}
.curved-corner-bottomleft,
.curved-corner-bottomright {
    width: 10px;
    height: 10px;
    overflow: hidden;
    position: absolute;
    
}
.curved-corner-bottomleft {
    right:-10px;
    top:15px;
}
.curved-corner-bottomright {
    left:-10px;
    top:15px;
}
<div class="flex">
      <div class="tab">
        <div class="curved-corner-bottomright"></div>
        <div class="curved-corner-bottomleft"></div>
      </div>
      <div class="tab">
        <div class="curved-corner-bottomright"></div>
        <div class="curved-corner-bottomleft"></div>
      </div>
     </div>
    <div id="bar"></div>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

I would probably solve it using clip-path CSS property to define the shape of the active element (see also the d attribute reference). The active element also has to be made bigger, so the "feathers" on sides can be displayed, along with negative margin to compensate for bigger size, so the elements don't move. Finally, you need to set z-index higher, so the feathers are displayed above other tabs.

Normally, you would probably define CSS variables to define the arc radius, tab width and height, and calculate the path from those.

#bar {
  width: 300px;
  height: 50px;
  background-color: gray;
}

.tab {
  width: 75px;
  height: 25px;
  background-color: lightgray;
  margin-left: 0;
  text-align: center;
}

.tab:active {
  background-color: gray;
  margin: 0 -10px;
  width: 95px;
  z-index: 10;
  clip-path: path('M 0 25 A 10,10 0,0,0 10,15 L 10 10 A 10,10 0,0,1 20 0 L 75 0 A 10,10 0,0,1 85 10 L 85 15 A 10,10 0,0,0 95 25');
}

.flex {
  display: flex;
  width: 300px;
  justify-content: center;
}
<div class="flex">
  <div class="tab">Click me</div>
  <div class="tab">Click me</div>
  <div class="tab">Click me</div>
 </div>
<div id="bar"></div>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

Another possibility is to use border-radius. The "trick" here is to add an extra element next to the tabs, with the same border-radius values (on the relevant corners) but opposite background colours (so the tab has white at the front and grey behind, while the before and after elements have grey at the front and white behind):

<div class="flex">
  <div class="tab-area">
    <div class="before"></div>
    <div class="tab"></div>
    <div class="after"></div>
  </div>
</div>

The tab itself has border-radius: 5px 5px 0 0;, while the .before class has border-radius-bottom-right: 5px; and the .after class has border-radius-bottom-left: 5px;.

You can further neaten this up by using ::before and ::after but getting the backgrounds right in that case gets confusing so I generally accept the extra HTML elements!

  • Related