如何用CSS制作单侧带倾斜角且带圆角的盒子?
问题描述
我需要制作如图所示的单侧带22.5°倾斜角且带圆角的盒子:
最初尝试用clip-path,但没法实现圆角,而且盒子宽度随内容变化时,很难维持22.5°的倾斜角。后来改用每个按钮嵌套两个<div>:一个做常规矩形,另一个应用skewX(22.5deg)变换叠加,同时给两者加圆角,代码如下:
现有代码
CSS
body { line-height: 0; font-size: 16px; background-color: black; } .cta-button-group { display: flex; gap: 2rem; align-items: center; } .button-angular-wrapper-left { display: flex; isolation: isolate; position: relative; height: 40px; width: fit-content; } .button-angular-wrapper-left .button-angular-main { border-radius: 7px 0 0 7px; height: 100%; display: inline-grid; place-items: center; padding-inline: 8px 16px; margin-right: 13px; transition: background-color 50ms; } .button-angular-wrapper-left .button-angular-slant { border-radius: 0 7px 7px 0; height: 100%; width: 24px; position: absolute; right: 0; top: 0; bottom: 0; z-index: -1; transition: background-color 50ms; } .button-angular-wrapper-left .button-angular-slant.back-slash { transform: skewX(22.5deg); } .button-angular-wrapper-left .button-angular-slant.forward-slash { transform: skewX(-22.5deg); } .button-angular-wrapper-left.button-angular-color-solid-white .button-angular-main, .button-angular-wrapper-left.button-angular-color-solid-white .button-angular-slant { background: white; border: 3px solid white; color: blue; } .button-angular-wrapper-left.button-angular-color-solid-white .button-angular-main { border-right: none; } .button-angular-wrapper-left.button-angular-color-solid-white .button-angular-slant { border-left: none; } .button-angular-wrapper-right { display: flex; isolation: isolate; position: relative; height: 40px; width: fit-content; } .button-angular-wrapper-right .button-angular-main { border-radius: 0 7px 7px 0; height: 100%; display: inline-grid; place-items: center; padding-inline: 8px 16px; margin-left: 13px; } .button-angular-wrapper-right .button-angular-slant { border-radius: 7px 0 0 7px; height: 100%; width: 24px; position: absolute; left: 0; top: 0; bottom: 0; z-index: -1; } .button-angular-wrapper-right .button-angular-slant.back-slash { transform: skewX(22.5deg); } .button-angular-wrapper-right .button-angular-slant.forward-slash { transform: skewX(-22.5deg); } .button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main, .button-angular-wrapper-right.button-angular-color-outline-white .button-angular-slant { border: 3px solid white; } .button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main { border-left: none; } .button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main .icon-call { color: white; } .button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main .cta-text { color: white; } .button-angular-wrapper-right.button-angular-color-outline-white .button-angular-slant { border-right: none; }
HTML
<div class="cta-button-group"> <div class="button-angular-wrapper-left button-angular-color-solid-white" href=""> <div class="button-angular-main"> <span class="cta-text"> Learn More Today </span> </div> <div class="button-angular-slant back-slash"> </div> </div> <div class="button-angular-wrapper-right button-angular-color-outline-white" href=""> <div class="button-angular-main"> <span class="cta-text tel-link-no"> 1800-1-5555 </span> </div> <div class="button-angular-slant back-slash"> </div> </div> </div>
这个方案能实现效果,但在部分浏览器和分辨率下会出现明显的显示瑕疵。求一个优质的解决方案,不要使用mask(我在尺寸控制上难以驾驭mask)。
解决方案
推荐用单个容器+伪元素的方案,既能减少DOM节点,又能避免两个div叠加的显示问题,同时保证倾斜角始终是22.5°,且自适应内容宽度。
核心思路:
- 主容器负责承载内容、设置单侧圆角,以及控制整体尺寸
- 伪元素通过
transform-origin定位后做倾斜变换,实现单侧斜角,同时匹配主容器的圆角和样式 - 用
calc()和三角函数(tan(22.5deg))动态计算伪元素的宽度,确保倾斜角固定,不受容器高度变化影响
实现代码
CSS
body { font-size: 16px; background-color: black; padding: 2rem; } .cta-button-group { display: flex; gap: 2rem; align-items: center; } /* 左侧斜角按钮通用样式 */ .button-skew-left { position: relative; display: inline-flex; align-items: center; padding: 0 16px 0 8px; height: 40px; border-radius: 7px 0 0 7px; box-sizing: border-box; color: blue; } /* 左侧斜角伪元素 */ .button-skew-left::after { content: ''; position: absolute; top: 0; right: 0; height: 100%; /* 用tan(22.5°)计算宽度,确保倾斜角固定:宽度 = 高度 * tan(22.5deg) */ width: calc(100% * tan(22.5deg)); border-radius: 0 7px 7px 0; transform-origin: top right; transform: skewX(-22.5deg); z-index: -1; } /* 实心白样式 */ .button-skew-left.solid-white { background: white; border: 3px solid white; border-right: none; } .button-skew-left.solid-white::after { background: white; border: 3px solid white; border-left: none; } /* 右侧斜角按钮通用样式 */ .button-skew-right { position: relative; display: inline-flex; align-items: center; padding: 0 8px 0 16px; height: 40px; border-radius: 0 7px 7px 0; box-sizing: border-box; color: white; } /* 右侧斜角伪元素 */ .button-skew-right::after { content: ''; position: absolute; top: 0; left: 0; height: 100%; width: calc(100% * tan(22.5deg)); border-radius: 7px 0 0 7px; transform-origin: top left; transform: skewX(22.5deg); z-index: -1; } /* 描边白样式 */ .button-skew-right.outline-white { background: transparent; border: 3px solid white; border-left: none; } .button-skew-right.outline-white::after { background: transparent; border: 3px solid white; border-right: none; }
HTML
<div class="cta-button-group"> <a class="button-skew-left solid-white"> <span class="cta-text">Learn More Today</span> </a> <a class="button-skew-right outline-white"> <span class="cta-text">1800-1-5555</span> </a> </div>
方案优势
- DOM结构更简洁:单个容器+伪元素,避免多余嵌套
- 倾斜角绝对固定:通过
tan(22.5deg)动态计算伪元素宽度,不管容器高度怎么变,倾斜角始终是22.5° - 无显示瑕疵:伪元素和主容器的边界通过border控制,不会出现两个div叠加时的缝隙或错位问题
- 自适应内容宽度:主容器宽度随内容自动调整,伪元素宽度会同步适配
- 样式易维护:统一的样式变量(比如圆角、倾斜角),修改时只需改一处
内容的提问来源于stack exchange,提问作者Exito
相关产品推荐
相关产品推荐

