This time, let’s look at a navigation bar layout with special rounded corners, such as the tab bar of Google Chrome:
How to realize such a layout? Here are a few methods
1. Pseudo-element splicing
Suppose there is such an HTML structure
<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>
The first way to consider is to use two pseudo-elements to splice
The round corners in the middle are easier. How to realize the reverse round corners on the left and right sides? In fact, you can think about what can achieve circular styles, here is border-radius , which can be achieved like this
- Draw a transparent circle
- Add a large enough border or projection to the circle
- Crop a small part
- carry out
The schematic is as follows
The code implementation is
.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
The cropping here is clip-path . Note that the left and right sides can be cropped toward the inside to avoid gaps in the splicing. The completed code can be accessed at chrome-tab (codepen.io)
Of course, the reverse fillet here can also be achieved by using a radial gradient, and then look down.
Second, the omnipotent gradient
CSS gradients are almost omnipotent. Any graphics can be drawn. You can split them here. Two rectangles, two circles, and two reverse rounded corners, that is, 2 linear gradients and 4 diameters. To the gradient, as shown below
The code implementation is
.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 it is realized, it is very . Careful observation shows that the two circles of 160f635389da2f can be realized by tiling, and the two inverted rounded corners can be regarded as a semicircle , and then can also be tiled, as shown below
In this way, only two radial gradients are needed. 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 (the above is the schematic diagram)
The completed code can be accessed at chrome-tab-gradient (codepen.io)
Three, adaptive svg
Although gradual changes are omnipotent, the amount of code is relatively large, which tests patience. For this example, svg is also a good solution.
The rounded rectangle in the middle is easier, 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 reverse fillet on both sides can directly use a path path (all kinds of 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>
<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>
Then use these 3 svg codes as the background, you can use background-size and background-position to adjust and control
.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'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M100 100C44.772 100 0 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'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 100c55.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 complete code can be accessed chrome-tab-svg (codepen.io)
In addition, some people may be wondering, why do we use three Isn't it okay to include 3 paths in one svg? answer to 160f635389dc2a is no good. There is no flexibility to use positioning in svg. For example, if you want to be located in the lower right corner, svg can only use 100% instead of calc( 100% ) 160f635389dc2e, let alone CSS also has right bottom such positioning properties , So you must use CSS multi-background achieve
Fourth, the picture frame
The above methods are still too complicated, can "cut the picture" ? Of course it is possible, but it also requires certain skills to achieve self-adaptation. This can be achieved by using CSS3 border-image . For border-image, please refer to this article: JELLY | Correct usage of border-image (jd.com) .
Just prepare such a picture, svg or png will do
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>
Then cut according to the border-image specification.
The code is implemented 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'%3E%3Cpath 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='%23F8EAE7'/%3E%3C/svg%3E") 12 27 15 fill;
}
The real-time effect is as follows
The complete code can be accessed at chrome-tab-border-image (codepen.io)
Although the code implementation is relatively brief, the content size is somewhat difficult to control due to the addition of borders
Five, mask mask
In fact, there is a problem with the previous methods of background pictures. The colors are almost fixed in the background pictures and are not convenient to modify. Then, with the help of mask, this problem can be easily solved.
With the previous background (gradient or svg will work), just background to -webkit-mask , just like this
Take svg as an example, after the replacement 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'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M100 100C44.772 100 0 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'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M0 100c55.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 convenient to control the background color. If you need to change the background color, just change it directly.
.tab-item:hover{
background: #F2D0CA;
}
The complete code can be viewed at chrome-tab-mask (codepen.io)
In addition, those who like "cutting pictures" can also use mask-border achieve, which is border-image , but the effect of the mask is obtained.
Still use this picture for cutting
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'%3E%3Cpath 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='%23F8EAE7'/%3E%3C/svg%3E") 12 27 15;
}
The complete code can be accessed at chrome-tab-mask-border (codepen.io)
Currently still in the draft, there is an alternative attribute -webkit-mask-box-image can be used
Six, summary and explanation
A total of 5 different layout methods have been introduced above, and the main points of implementation are summarized below:
- border-radius with clip-path can achieve concave rounded corners
- Gradient is omnipotent, repeat content as much as possible through background-repeat
- svg in rect can realize adaptive rounded rectangle, which is also suitable for background
- You can use multiple segments svg as multiple backgrounds to control the size and position separately
- border-image can achieve adaptive effect, you need to pay attention to setting border-width
- mask mask can directly use gradient or svg as the mask layer, you can modify the background color more conveniently
- mask-border and border-image use similar, but currently only -webkit- kernel supports
Each has its own characteristics. For example, gradients are universal, but the implementation is the most cumbersome. Although svg is simple, it also has limitations (the rounded rectangle in the middle is not supported by other shapes). It is mainly to open up thinking. You can follow your actual needs. Choose by yourself, and you can also consider these aspects next time you encounter other layouts. Finally, if you think it’s pretty good, if it’s helpful to you, please like, bookmark, and forward ❤❤❤
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。