This time take a look at the layout of the navigation bar with special rounded corners, as shown in Google chrome’s TAB bar:

How can such a layout be implemented? Here are a few ways to do it

1. Pseudo-element stitching

Suppose you have an HTML structure like this

<nav class="tab">
  <a class="tab-item">Svelte API</a>
  <a class="tab-item active">Svelte API</a>
  <a class="tab-item">Svelte API</a>
  <a class="tab-item">Svelte API</a>
</nav>
Copy the code

One of the first ways to think about it is by concatenating two pseudo-elements

The middle corner is easier, how to achieve the left and right sides of the reverse corner? You can actually think about what you can do to implement a circular style, and here I think of border-radius, and I can do this

  1. Draw a transparent circle
  2. Add a large enough border or shadow to the circle
  3. Cut a small part
  4. complete

Indicated as follows

In code

.tab-item{
  position: relative;
  background-color: red;
  padding: 10px 15px;
  border-radius: 12px 12px 0 0;
  cursor: pointer;
  transition:.2s;
}
.tab-item::before..tab-item::after{
  position: absolute;
  bottom: 0;
  content: ' ';
  width: 20px;
  height: 20px;
  border-radius: 100%;
  box-shadow: 0 0 0 40px red;/* Box-shadow does not affect size */
  transition:.2s;
}
.tab-item::before{
  left: -20px;
  clip-path: inset(50% -10px 0 50%);
}
.tab-item::after{
  right: -20px;
  clip-path: inset(50% 50% 0 -10px);
}
Copy the code

The final real-time results are as follows

Chrome – TAB (codepen.io)

Of course, the reverse roundness can also be achieved with a radial gradient, and then we’ll see.

Universal gradients

CSS gradients can do almost anything. You can draw any shape you like. Here you can split it up: two rectangles, two circles, and two reverse rounded corners

In code

.tab-item{
  padding: 10px 35px;
  background-image: 
    radial-gradient(circle at 0 0, transparent 15px,blue 0),
    radial-gradient(circle at 0 0, transparent 15px,blue 0),
    radial-gradient(circle at 0 0, green 12px,transparent 0.radial-gradient(circle at 12px 0, green 12px,transparent 0.linear-gradient(red,red),
    linear-gradient(red,red);
  background-repeat: no-repeat;
  background-position: 15px top, right 15px top 0, left bottom, right bottom, center bottom, center, bootom;
  background-size: 30px 30px.30px 30px.12px 12px.12px 12px.calc(100% - 30px) calc(100% - 12px), calc(100% - 54px) 100%;
}
Copy the code

Although realized, but very wordy, careful observation found that two circles can be realized by tiling, two reverse rounded corners can be regarded as a semicircle, and then can also be tiled, as shown below

In this case, only two radial gradients are required, as shown below

.tab-item{
  position: relative;
  padding: 10px 35px;
  cursor: pointer;
  background-image: radial-gradient(circle at 15px 0, transparent 15px,blue 0),
    radial-gradient(circle at 27px 12px, green 12px,transparent 0),
    linear-gradient(red,red),
    linear-gradient(red,red);
  background-size: 100% 15px.calc(100% - 54px), calc(100% - 30px) calc(100% - 12px), calc(100% - 54px) 100%;
  background-position: -15px bottom, left top, center bottom, center bottom;
  background-repeat: repeat-x, repeat-x, no-repeat, no-repeat;
}
Copy the code

The final real-time look is as follows (schematic above)

Chrome-tab-gradient (codepen.io)

Adaptive SVG

Gradients are versatile, but they require a lot of code and can be very patient. SVG is also a good solution for this example.

The rounded rectangle in the middle is easier. Rect will do

<svg xmlns='http://www.w3.org/2000/svg' width='100%' height='100%'>   
	<rect rx="12" width='100%' height='100%' fill="#3A8EFF"/>
</svg>
Copy the code

The reverse rounded corners on both sides can be directly used with a path path (any graphics software can generate)

<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
	<path fill-rule="evenodd" clip-rule="evenodd" d="M0 100C55.2285 100 100 55.2285 100 0V100H0Z" fill="#3A8EFF"/>
</svg>
Copy the code
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
	<path fill-rule="evenodd" clip-rule="evenodd" d="M100 100C44.7715 100 0 55.2285 0 0V100H100Z" fill="#3A8EFF"/>
</svg>
Copy the code

Then use the 3 SVG code as the background, which can be adjusted and controlled using background-size and background-position

.tab-item{
  position: relative;
  padding: 10px 35px;
	margin: 0 -15px;
  cursor: pointer;
  transition:.2s;
  background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' XMLNS = 'http://www.w3.org/2000/svg' % 3 e % 3 cpath fill - rule = 'evenodd' clip - rule = 'evenodd' d = 'M100 approximately 100 c44. 772, 100, 55.228 0 0v100h100z' fill='%23F8EAE7'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' XMLNS = 'http://www.w3.org/2000/svg' % 3 e % 3 cpath fill - rule = 'evenodd' clip - rule = 'evenodd' d = 'M0 100 c55. 228 0 100-44.772 100-100v100H0z' fill='%23F8EAE7'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect rx='12' width='100%' height='100%' fill='%23F8EAE7'/></svg>");
  background-size: 12px 12px.12px 12px.calc(100% - 24px) calc(100% + 12px);
  background-position: right bottom, left bottom, center top;
  background-repeat: no-repeat;
}
Copy the code

The real-time effects are as follows

Chrome-tab-svg (codepen.io)

Also, one might wonder, why are we using 3 SVG pieces here? Isn’t it possible to have 3 paths in one SVG? ** The answer is no. There is no flexibility to use positioning in SVG. For example, to implement positioning in the lower right corner, SVG can only use 100% instead of CALC (100%-12px), let alone CSS with positioning attributes such as right Bottom, so CSS multi-background implementation is necessary

4. Picture border

The above ways still feel too complicated, can ** “cut map” **? Of course you can, but it takes a little bit of skill to do that. CSS3 border-image can be used to achieve this. About the border – image can refer to this article: JELLY | border – the correct use of the image (jd.com).

Prepare an image like this, either in SVG or PNG

SVG is as follows

<svg width="67" height="33" viewBox="0 0 67 33" fill="none" xmlns="http://www.w3.org/2000/svg">
  <path fill-rule="evenodd" clip-rule="evenodd" d="M27 0c-6.627 0-12 5.373-12 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z" fill="#F8EAE7"/>
</svg>
Copy the code

Then cut according to the border-image specification

The code implementation is as follows, remember to add border

.tab-item{
  position: relative;
  padding: 0 8px;
  margin: 0 -15px;
  cursor: pointer;
  border-width: 12px 27px 15px;
  border-style: solid;
  border-image: url("data:image/svg+xml,%3Csvg width='67' height='33' viewBox='0 0 67 33' fill='none' XMLNS = 'http://www.w3.org/2000/svg' % 3 e % 3 cpath fill - rule = 'evenodd' clip - rule = 'evenodd' d = 'M27 0 0 c - 6.627-5.373-12 December 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z' fill='%23F8EAE7'/%3E%3C/ SVG %3E" 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12) 12 27 15 fill;
}
Copy the code

The real-time effects are as follows

Chrome-tab-border-image (codepen.io)

Although the code implementation is relatively brief, the content size is a little difficult to control due to the need to add border

V. Mask

In fact, there is a problem with the previous background images. The colors are almost fixed in the background images, which is not easy to modify. Therefore, mask can be used to solve this problem easily.

With the previous background (gradient or SVG), just change the background batch to -webkit-mask, like this

Using SVG as an example, the substitution is as follows

.tab-item{
  position: relative;
  padding: 10px 35px;
  cursor: pointer;
  background: #F8EAE7;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' XMLNS = 'http://www.w3.org/2000/svg' % 3 e % 3 cpath fill - rule = 'evenodd' clip - rule = 'evenodd' d = 'M100 approximately 100 c44. 772, 100, 55.228 0 0v100h100z' fill='%23F8EAE7'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' fill='none' XMLNS = 'http://www.w3.org/2000/svg' % 3 e % 3 cpath fill - rule = 'evenodd' clip - rule = 'evenodd' d = 'M0 100 c55. 228 0 100-44.772 100-100v100H0z' fill='%23F8EAE7'/%3E%3C/svg%3E"),
    url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'><rect rx='12' width='100%' height='100%' fill='%23F8EAE7'/></svg>");
  -webkit-mask-size: 12px 12px.12px 12px.calc(100% - 24px) calc(100% + 12px);
  -webkit-mask-position: right bottom, left bottom, center top;
  -webkit-mask-repeat: no-repeat;
}
Copy the code

Now it’s easy to control the background color. If you need to change the background color, just change it

.tab-item:hover{
  background: #F2D0CA;
}
Copy the code

Chrome-tab-mask (codepen.io)

In addition, you can also use mask-border if you like to “slice” the image, which is basically the same as the border-image above, but with the effect of a mask

I’m going to take this picture and cut it

The code implementation is

.tab-item{
  / *... * /
  -webkit-mask-box-image: url("data:image/svg+xml,%3Csvg width='67' height='33' viewBox='0 0 67 33' fill='none' XMLNS = 'http://www.w3.org/2000/svg' % 3 e % 3 cpath fill - rule = 'evenodd' clip - rule = 'evenodd' d = 'M27 0 0 c - 6.627-5.373-12 December 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12-12H27z' fill='%23F8EAE7'/%3E%3C/ SVG %3E" 12v6c0 8.284-6.716 15-15 15h67c-8.284 0-15-6.716-15-15v-6c0-6.627-5.373-12-12) 12 27 15;
}
Copy the code

Full code can be accessed at Chrome-tab-mask-border (codepen.io)

Currently in draft, there is an alternative property -webkit-mask-box-image to use

Summary and explanation

There are 5 different layout methods described above. Here are the main implementation points:

  1. Border-radius with clip-path can achieve concave rounded corners
  2. Gradients are versatile, and repeat content with background-repeat as much as possible
  3. Rect in SVG can implement an adaptive rounded rectangle, which is also useful as a background
  4. Multiple SVG segments can be used as multiple backgrounds, controlling size and position separately
  5. Border-image can be adaptive. Set border-width
  6. Mask masks can be directly used as a gradient or SVG mask layer, making it easier to change the background color
  7. Mask-border and border-image are used similarly, but currently only -webkit-kernel support is available

Each have each characteristic, such as the gradient is everything, but realize the most trival, SVG, although simple, but there are limitations (rounded rectangle, among other shapes don’t support), mainly is the development thinking, you can choose according to actual demand, the next encounter other layout also can from these aspects to consider. Finally, if you think it’s good and helpful, please like, bookmark and retweet ❤❤❤