This time we’ll look at a layout with a special rounded navigation bar, like the Google browser’s TAB bar:

How can such a layout be implemented? Here are some methods

1. Pseudo-element splicing

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>

One of the first ways to consider is to use two pseudo-elements to join together

The middle corner is easier. How about the opposite corner on the left and right sides? You can actually think about what you can do to make a circle, so border-radius, you can do it like this

  1. Draw a transparent circle
  2. Add a big enough border or drop shadow to the circle
  3. Cut off a small portion
  4. complete

The schematic is as follows:

It’s implemented 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不影响尺寸*/
  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);
}

The final real-time effect is as follows

Here clipping is achieved with clip-path, note that left and right can be clipped a little more to the inside, so as to avoid splicing gaps, complete the code can visit chrome-tab (codepen. IO)

Of course, the reverse rounded corners here can also be achieved with a radial gradient, and then look down.

Two, all-purpose gradient

CSS gradients can do almost anything, you can draw anything, you can split it up here, two rectangles, two circles, and two reverse rounded corners, so 2 linear gradients, 4 radial gradients, and so on

It’s implemented 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%;
}

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

This is done with only two radial gradients. The code is as follows

.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;
}

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

Complete the code to access chrome-tab-gradient (codepen.io)

3. Adaptive SVG

Gradient is omnipotent, but the amount of code is relatively large, very patient test. For this example, SVG is also a good solution.

The rounded rectangle in the middle is easier, so just use rect

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

The two sides of the reverse rounded corner can be directly used 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 Fili-rule ="evenodd" clip-rule="evenodd" d="M0 100c55.2285 100 100 55.2285 100 0V100H0Z" fili-rule ="#3A8EFF"/> </ SVG > "fili-rule ="evenodd" clip-rule="evenodd" d="M0 100c55.2285 100 0V100H0Z
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg"> <path Fili-rule ="evenodd" clip-rule="evenodd" d="M100 100c44.7715 100 0 55.2285 0 0V100H100Z" fili-rule ="#3A8EFF"/> </ SVG > "fili-rule ="evenodd" clip-rule="evenodd" d="M100 100c44.7715 100 0 55.2285 0 0V100H100Z

The three pieces of SVG code can then be used as a 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; }

The real-time effect is as follows

The full code is available at chrome-tab-svg (codepen.io)

Also, one might wonder, why use three-segment SVG here? Wouldn’t it be a good idea to have one block of SVG with three paths in it? The answer is no. There is no way to use positioning in SVG. For example, SVG can only use 100% instead of calc(100%-12px) for the lower right corner, not to mention the CSS right bottom positioning property, so it must be implemented with CSS multi-background

Four, picture frame

The above several ways still feel too complicated, can “cut the picture”? You can, of course, but you have to have a certain skill, so that you can be adaptive. This can be done using CSS3 border-image. About the border – image can refer to this article: JELLY | border – the correct use of the image (jd.com).

Just prepare a picture like this, 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 "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 15 15-6.716 - v - c0 6-6.627-5.373 - the 12-12-12 H27z "fill =" # F8EAE7 "/ > < / SVG >

Then cut according to the border-image specification

The code implementation is as follows, remember to add the 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") 12 27 15 fill; }

The real-time effect is as follows

The full code can be accessed at chrome-tab-border-image (codepen.io)

Although the code implementation is relatively brief, the size of the content is somewhat difficult to control due to the border

Five, mask cover

In fact, there is a problem in the way of the front several background pictures. The colors are almost fixed in the background picture, which is not convenient to modify. Then, with the help of the mask, this problem can be easily solved.

Now that you have the background in front (either gradient or SVG), just batch the background to -webkit-mask, just like that

In the case of SVG, 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; }

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;
}

For the full code, check out chrome-tab-mask (codepen.io).

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

Again, 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") 12 and 15; }

The full code can be found at chrome-tab-mask-border (codepen.io)

Currently still in the draft, there is an alternative property
-webkit-mask-box-imageYou can use

VI. Summary and explanation

The above five different layout methods are introduced. Here are the key points to achieve them:

  1. Border-radius with clip-path can achieve concave rounded corners
  2. Gradient is versatile. Try to use background-repeat for repeated content
  3. Rect in SVG can be used as an adaptive rounded rectangle as well as a background
  4. You can use multi-segment SVG as multiple backgrounds, with separate control of size and position
  5. Border-image can achieve adaptive effect, and it is necessary to pay attention to setting border-width
  6. The mask can be used directly with Gradient or SVG as the mask layer to make it easier to change the background color
  7. Mask-border is similar to border-image, but currently only supported by -webkit-kernel

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 is good and helpful to you, please feel free to thumb up, bookmark, retweet