CSS/网页设计:如何创建倾斜/侧面按钮

3
如何在网站上创建一个每一边都是斜的(对角线)的按钮?
我没有找到一个示例来展示给你,但这是我在10分钟内找到的最接近的: http://cfl.ca/(查看带有选项卡的菜单:新闻、视频、时间表、排名)
然而,在我的情况下,我需要这种设计作为一个独立的按钮,而不是菜单选项卡。
4个回答

14

这是一种(不完美的)实现方式,但它需要使用大量标记:

<div class="button">
    <span></span>
    Some button text
    <span></span>
</div>

使用CSS:

.button {
    width: auto;
    display: inline-block;
    background-color: #f00;
    height: 2em;
    overflow: hidden;
}

.button span:first-child {
    display: inline-block;
    border-top: 1em solid #fff;
    border-left: 1em solid #fff;
    border-bottom: 1em solid #f00;
    border-right: 1em solid #f00;
    float: left;
    margin-right: 1em;
}

.button span:last-child {
    display: inline-block;
    border-bottom: 1em solid #fff;
    border-right: 1em solid #fff;
    border-top: 1em solid #f00;
    border-left: 1em solid #f00;
    margin-left: 1em;
}

.button:hover {
    background-color: #0f0;
}

.button:hover span:first-child {
    border-right-color: #0f0;
    border-bottom-color: #0f0;
}

.button:hover span:last-child {
    border-left-color: #0f0;
    border-top-color: #0f0;
}

JS Fiddle演示

我还不确定为什么文本对齐到.button元素的底部,但至少这是一个起点。(如果有任何修改或评论来解释/改进答案,我回到我的桌子上会欢迎的...)


编辑以修改演示CSS:

.button {
    width: auto;
    display: inline-block;
    background-color: #f00;
    height: 2em;
    line-height: 2em; /* centering the text vertically */
}

/* other stuff */

.button span:last-child {
    display: inline-block;
    border-bottom: 1em solid #fff;
    border-right: 1em solid #fff;
    border-top: 1em solid #f00;
    border-left: 1em solid #f00;
    margin-left: 1em;
    float: right; /* removes from the 'normal flow' */
    margin-top: -2em; /* aligns vertically with the top of the parent .button div */
}

修订后的 JS Fiddle 示例.


根据 Adam(原文章作者)在评论中的问题进行编辑:

...我正在试图理解你是如何做到的。

这个想法基于一个简单的前提,即边框之间的连接是45°,如下面的 HTML/CSS 所示:

<span id="box"></span>

#box {
    display: inline-block;
    border-width: 30px;
    border-style: solid;
    border-top-color: red;
    border-right-color: green;
    border-bottom-color: yellow;
    border-left-color: blue;
}

得到如下结果:

JS Fiddle演示

如果相邻的两个边框颜色相同,则会创建两个直角三角形(使用与上述相同的HTML):

#box {
    display: inline-block;
    border-width: 30px;
    border-style: solid;
    border-top-color: red;
    border-right-color: red;
    border-bottom-color: yellow;
    border-left-color: yellow;
}

给出:

JS Fiddle 演示

在上面的示例中,我将包含元素(.box)的高度定义为 2em,并且包含的 span 元素的边框为 1em(如果我给 span 分配了它们自己的 height(或 width),这个形状将变得更加复杂:

#box {
    display: inline-block;
    border-width: 30px;
    border-style: solid;
    border-top-color: red;
    border-right-color: red;
    border-bottom-color: yellow;
    border-left-color: yellow;
    height: 30px;
}

使用height属性:

或者,使用width属性:

#box {
    display: inline-block;
    border-width: 30px;
    border-style: solid;
    border-top-color: red;
    border-right-color: red;
    border-bottom-color: yellow;
    border-left-color: yellow;
    width: 30px;
}

给出:

同时使用widthheight可以创建一个部分被切断的盒子:

#box {
    display: inline-block;
    border-width: 30px;
    border-style: solid;
    border-top-color: red;
    border-right-color: red;
    border-bottom-color: yellow;
    border-left-color: yellow;
    width: 30px;
    height: 30px;
}

给出:

这可能对于伪3D框架效果非常有用,特别是使用:hover效果/变化。

我不确定这是否有所帮助,但如果您有任何具体的好奇心,请在评论中让我知道,我会尽力回答。=)

编辑添加一个伪元素,::before/::after,解决方案。

HTML略微简化为:

<div class="button">
    Some button text
</div>
<div class="button">
    Some more button text
</div>
<div class="button">
    And yet more button text
</div>

但 CSS 更冗长,不算复杂,但显然包含的内容更多:

.button {
    width: auto;
    display: inline-block;
    background-color: #f00;
    height: 2em;
    line-height: 2em;
    position: relative;
    margin-left: 3em;
}

.button::before,
.button::after {
    content: '';
    border-color: #f00;
    border-width: 1em;
    border-style: solid;
    position: absolute;
    top: 0;
    bottom: 0;
}

.button::before {
    border-top-color: transparent;
    border-left-color: transparent;
    right: 100%;
}

.button::after {
    border-right-color: transparent;
    border-bottom-color: transparent;
    left: 100%;
}

.button:hover {
    background-color: #0f0;
}

.button:hover::before {
    border-color: #0f0;
    border-top-color: transparent;
    border-left-color: transparent;
}

.button:hover::after {
    border-color: #0f0;
    border-right-color: transparent;
    border-bottom-color: transparent;
}

JS Fiddle演示


不幸的是,它仍然具有矩形命中区域,尽管我目前没有更好的建议。 - shanethehat
真棒,我正试着理解你是如何做到的。 - Adam Strudwick
@Adam,我已经尝试解释一下我的Fiddle背后的一些工作原理(请参见最新编辑)。希望这能让你对我的方法和思路有所了解。如果我的回答还不够充分,请告诉我。我会尽力帮助你的。 :) - David Thomas
1
@David 哇,真的是非常好的解释!现在我完全明白了,多亏了你。我在这里欠你一个人情 ;) - Adam Strudwick
@Adam:很高兴能够提供帮助;你绝对是受欢迎的! :) - David Thomas

2

注意,这在Internet Explorer上根本不起作用,我甚至在检查时都看不到菜单。使用倾斜按钮的图像是安全的选择。(尽管在该示例站点上硬编码与z-index重叠的每个菜单栏项是任何自尊心的网页设计师都不应该做的事情) - NorthGuard
1
是的,他在网站上确实说这只是一个概念验证,需要更多的工作来提高兼容性,首先是添加图像回退。不过我认为这值得发布。 - shanethehat

0
您可以为每个元素使用斜线背景图像,然后重叠这些元素以使图像在视觉上紧密连接。要避免没有矩形点击区域的问题,唯一的方法是使用图像映射(您可能不想使用)。

0

我知道这不是最“技术”的答案,但这个网站可以为您生成那种类型的CSS(如果可能的话还兼容浏览器)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接