我想知道是否可以在CSS3中执行这样的复杂按钮?我不知道从哪里开始。我可以很容易地做类似梯形的形状,但是添加边框似乎是不可能的。我错过了什么吗?
(PS:图片是Deus Ex Human Revolution)
答案 0 :(得分:5)
正如您自己指出的那样,生成相关的形状非常简单,下面是如何实现它的示例片段。基本思想是使用伪元素,向其添加background
然后将其倾斜。父项上的overflow: hidden
会切掉不需要的形状部分,从而最终形成形状。
ul {
list-style-type: none;
margin: 0;
padding: 0;
list-style-position: inside;
}
li {
position: relative;
height: 40px;
width: 300px;
margin: 10px;
padding-right: 30px;
line-height: 40px;
text-align: right;
text-transform: uppercase;
border-radius: 8px;
color: crimson;
overflow: hidden;
}
li:after {
position: absolute;
content: '';
left: 0;
top: 0;
height: 100%;
width: 100%;
background: rgba(0, 0, 0, 0.5);
transform: skew(45deg);
z-index: -1;
}
/* just for demo */
body {
background: url(http://lorempixel.com/800/500/abstract/2);
}
*, *:after, *:before {
box-sizing: border-box;
}

<ul>
<li>Menu Text 1</li>
<li>Menu Text 2</li>
<li>Menu Text 3</li>
</ul>
&#13;
但是,为使用此方法创建的形状添加边框非常困难,并且在形状与其边框之间需要透明区域的事实使得它几乎不可能。
我们可以在下面的代码段中使用clip-path
,这样就可以使用伪元素添加边框,但这种方法有以下缺点:
clip-path
的纯CSS版本。clip-path
。clip-path
以在背景和边框之间产生透明区域,但这会使其变得极其复杂并且几乎无法维护。
ul {
list-style-type: none;
margin: 0;
padding: 0;
list-style-position: inside;
}
li {
position: relative;
height: 40px;
width: 300px;
margin: 10px;
padding-right: 30px;
line-height: 40px;
text-align: right;
text-transform: uppercase;
border-radius: 8px;
background: crimson;
color: crimson;
-webkit-clip-path: polygon(0% 0%, 0% 50%, 10% 100%, 100% 100%, 100% 50%, 90% 0%);
clip-path: polygon(0% 0%, 0% 50%, 10% 100%, 100% 100%, 100% 50%, 90% 0%);
}
li:after {
position: absolute;
content: '';
height: calc(100% - 4px);
width: calc(100% - 4px);
left: 2px;
top: 2px;
border-radius: 7px;
background: rgba(0, 0, 0, 0.5);
-webkit-clip-path: polygon(0% 0%, 0% calc(50% - 1px), 10% 100%, 100% 100%, 100% calc(50% + 1px), 90% 0%);
clip-path: polygon(0% 0%, 0% calc(50% - 1px), 10% 100%, 100% 100%, 100% calc(50% + 1px), 90% 0%);
z-index: -1;
}
/* just for demo */
body {
background: url(http://lorempixel.com/800/500/abstract/2);
}
*, *:after, *:before {
box-sizing: border-box;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<ul>
<li>Menu Text 1</li>
<li>Menu Text 2</li>
<li>Menu Text 3</li>
</ul>
&#13;
考虑到上述所有情况,我建议你使用SVG 来制作如此复杂的形状。使用SVG,我们可以使用path
元素创建边框和形状的填充。
ul {
list-style-type: none;
margin: 0;
padding: 0;
list-style-position: inside;
}
li {
position: relative;
height: 40px;
width: 300px;
margin: 10px;
padding-right: 30px;
line-height: 40px;
text-align: right;
text-transform: uppercase;
border-radius: 8px;
color: crimson;
}
li.active {
width: 350px;
height: 50px;
line-height: 50px;
}
svg #fill {
fill: rgba(0, 0, 0, 0.5);
}
svg #border {
stroke: crimson;
stroke-width: 2;
fill: transparent;
}
li svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
z-index: -1;
}
/* just for demo */
body {
background: url(http://lorempixel.com/800/500/abstract/2);
}
*, *:after, *:before {
box-sizing: border-box;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<svg viewBox='0 0 300 40' height='0' width='0'>
<defs>
<g id='shape'>
<path d='M8,0 A8,8 0 0,0 0,8 L0,20 30,40 292,40 A8,8 0 0,0 300,32 L300,20 270,0z' id='fill' />
</g>
<g id='shape-bordered'>
<path d='M9,1 A8,8 0 0,0 1,9 L1,20 30,39 292,39 A8,8 0 0,0 299,32 L299,20 270,1z' id='border' />
<path d='M10,4 A7,7 0 0,0 4,6 L4,19 31,36 290,36 A5,5 0 0,0 296,34 L296,21 269,4z' id='fill' />
</g>
</defs>
</svg>
<ul>
<li class='active'>
<svg viewBox='0 0 300 40' preserveAspectRatio='none'>
<use xlink:href='#shape-bordered' />
</svg>Menu Text 1</li>
<li>
<svg viewBox='0 0 300 40' preserveAspectRatio='none' vector-effect='non-scaling-stroke'>
<use xlink:href='#shape' />
</svg>Menu Text 2</li>
<li>
<svg viewBox='0 0 300 40' preserveAspectRatio='none'>
<use xlink:href='#shape' />
</svg>Menu Text 3</li>
</ul>
&#13;
(SVG可能会进一步调整。上面的代码片段只是一个示例,用于说明可以实现的目标。)