使用CSS和HTML5创建导航按钮,使用梯形形状

24

我正在尝试制作一个导航div,其中包括4个按钮,一个向左、一个向右、一个向下和另一个向上。此外,在中间还需要一个确定按钮。

按钮需要定位,以形成任何矩形(大小未设置)。在按钮内部,位置分别在右侧、左侧、顶部和底部,并且它们各自是梯形,留下一个正方形供确定按钮使用。

就像这样:Navbar Element

我所做的是创建了一个梯形父元素,使用CSS进行相对位置的形状:

.trapezoid_parent {
    position: relative;
}

还需要使用梯形,它是绝对的。

.trapezoid {
    position: absolute;
    border-bottom: 50px solid #f98d12;
    border-left: 80px solid transparent;
    border-right: 80px solid transparent;
    width: 100%; 
    height: 0; 
    z-index: 2;
    border-top: 1px solid #000000;
}

为了让它成为顶部的一个,我翻转了普通的那个并将其定位到顶部:

.trapezoid.top {
    transform: rotate(180deg);
    top: 0;
}

底部的梯形只需要放置在底部位置:

.trapezoid.bottom {
    bottom: 0;
}

接下来我们需要左侧按钮

.left_button {
    height: 100%; 
    position: absolute; 
    width: 40%; 
    left:0; 
    z-index: 1;
    border-right: 1px solid #000000;
}

右边的那一个

.right_button {
    height: 100%; 
    position: absolute; 
    width: 40%; 
    right:0; 
    z-index: 1;
    border-left: 1px solid #000000;
}

最后但同样重要的是中间的那个:

.center_button {
    height: 100%; position: absolute; width: 100%; right:0; z-index: 0;
}

那么,为了将所有内容放在一起,我使用了以下的html:

<div class="trapezoid_parent" style="width:200px; height:125px">
        <button class="left_button function"><i class='fa fa-arrow-left'></i></button>
        <button class="trapezoid top function"><i class='fa fa-arrow-down'></i></button>
        <button class="trapezoid bottom function"><i class='fa fa-arrow-down'></i></button>
        <button class="right_button function"><i class='fa fa-arrow-right'></i></button>
        <button class="center_button">OK</button>
</div>

为了使整个事情具有响应性,我制作了一个 jQuery 插件,可以根据父元素的大小相应地更改边框下部、左侧和右侧属性来调整大小:

var internal_square_size = ((1.0 / 2) - plugin.settings.square_size);

var tpw = $element.width();
var tph = $element.height();
$(".trapezoid", $element)
.css("border-left-width", "" + (tpw * internal_square_size) + "px")
.css("border-right-width", "" + (tpw * internal_square_size) + "px")
.css("border-bottom-width","" + (tph * internal_square_size) + "px");

$(".left_button, .right_button", $element).css("width", "" + internal_square_size*100 + "%");

结果看起来像这样:

Result

您可以在此处查看完整的内容:完整的jsfiddle示例

仍然存在一些问题,而我已经花费了所有的努力,但也许其他人有一些想法如何获取最后几个部分。

使用所提供的方法无法显示对角线边框,这是我无法接受的。有人有想法吗?

其次:如果按钮实际上可以以对角线结束,那将非常好,因为触摸太小的按钮始终很棘手。我错过了什么吗? HTML5不能完成我要求的事情吗?


@Paulie_D 我也考虑过这个问题,但我从未使用过SVG,请问你能否提供一份详细的答案? - Sebastian van Wickern
1
那会非常宽泛和太长,我认为在这里讨论不太现实,但我会看看能想出什么。 - Paulie_D
3个回答

27

如我在评论中提到的,我认为应该在这里使用SVG。

建议结构的简要示例。

svg {
  display: block;
  width: 200px;
  height: 200px;
  margin: 25px auto;
  border: 1px solid grey;
  stroke: #006600;
}
#buttons polygon:hover {
  fill: orange;
}
#buttons rect:hover {
  fill: blue
}
#center {
  fill: #00cc00;
}
#top {
  fill: #cc3333;
}
#right {
  fill: #663399;
}
#left {
  fill: #bada55;
}
<svg viewbox="0 0 100 100">
  <g id="buttons">
    <rect id="center" x="25" y="25" height="50" width="50" />
    <polygon id="top" points="0,0 100,0 75,25 25,25" />
    <polygon id="right" points="100,0 75,25 75,75 100,100" />
    <polygon id="bottom" points="0,100 25,75 75,75 100,100" />
    <polygon id="left" points="0,0 25,25 25,75 0,100" />
  </g>
</svg>

注意: 由于SVG中的每个元素都有一个ID,因此您应该能够使用JS / Jquery对它们进行定位。


不错的回答。display: block 对于 svg 有什么具体优势,还是只为了让边距起作用?我没有在其他地方看到它被使用过,只是想了解是否有任何好处。 - Harry
1
不,那只是为了边距。 - Paulie_D

12

以下是旧版本,它使用jQuery进行调整大小。但是在查看此问题后:SVG 多边形点支持百分比单位,您可以通过应用百分比而不需要任何 JS 来实现相同的效果:

<div id="svg-container">
    <svg id="mySVG" width='100%' height='100%' viewBox="0 0 100 100" preserveAspectRatio="none" style='background-color: whitesmoke'>
        <polygon id="ok" points="25,25 75,25 75,75 25,75" />
        <polygon id="up" points="0,0 100,0 75,25 25,25" />
        <polygon id="right" points="100,0 100,100 75,75 75,25" />
        <polygon id="down" points="0,100 25,75 75,75 100,100" />
        <polygon id="left" points="0,0 25,25 25,75 0,100" />
    </svg>
</div>

查看演示效果:http://jsfiddle.net/th4uo8wk/4/


旧答案:

糟糕,等我准备好的时候,Paulie_D已经回答了。

嗯,这里有一个响应式的(您可以在此jsfiddle上查看其工作,调整屏幕大小以查看其响应):

HTML:

<svg id="mySVG" height="20%" width="20%">
    <polygon id="ok" points="50,50 150,50 150,150 50,150" />
    <polygon id="up" points="0,0 200,0 150,50 50,50" />
    <polygon id="right" points="200,0 200,200 150,150 150,50" />
    <polygon id="down" points="0,200 50,150 150,150 200,200" />
    <polygon id="left" points="0,0 50,50 50,150 0,200" />
</svg>

JS/JQUERY

function resizeButtons() {
    // get the width
    var w = $("#mySVG").width();

    // make it squared
    $("#mySVG").height(w);

    // recalculate the position of each polygon
    $("#ok").attr("points", w * 0.25 + "," + w * 0.25 + " " + w * 0.75 + "," + w * 0.25 + " " + w * 0.75 + "," + w * 0.75 + " " + w * 0.25 + "," + w * 0.75);
    $("#up").attr("points", "0,0 " + w + ",0 " + w * 0.75 + "," + w * 0.25 + " " + w * 0.25 + "," + w * 0.25);
    $("#left").attr("points", w + ",0 " + w + "," + w + " " + w * 0.75 + "," + w * 0.75 + " " + w * 0.75 + "," + w * 0.25);
    $("#down").attr("points", "0," + w + " " + w * 0.25 + "," + w * 0.75 + " " + w * 0.75 + "," + w * 0.75 + " " + w + "," + w);
    $("#right").attr("points", "0,0 " + w * 0.25 + "," + w * 0.25 + " " + w * 0.25 + "," + w * 0.75 + " 0," + w);
}
CSS
svg { background:#ccc; }
#ok { fill: red; }
#up { fill: blue; }
#down { fill: green; }
#right { fill: yellow; }
#left { fill: orange; }

谢谢,我也有同样的想法,让它变得响应式。在这种情况下,SVG确实是更好的选择。 - Sebastian van Wickern
如果你只是在SVG上使用%宽度,它会自动响应。- http://codepen.io/Paulie-D/pen/5a603f8cdb764f01c87e2086714a2d25?editors=110 不确定你是否需要任何JS/JQ。 - Paulie_D
@Paulie_D,没错。我看到了这个问题https://dev59.com/3WMm5IYBdhLWcg3wlvwK并更新了代码。不需要JS来调整大小。 - Alvaro Montoro

9

正如其他人已经指出的那样,您应该使用SVG。以下是您可以使用的CSS替代方案。

它使用了转换的伪元素和transform-origin属性。为使其响应式,您需要更改单位。由于此方法中的单位为em,因此只需更改父级或body元素中的字体大小即可。

Fiddle

body {
    font-size: 12px;
}
.left, .right, .top, .bottom, .ok {
    height: 10em;
    width: 10em;
    position: relative;
}
.left {
    background-color: #FFBF00;
    margin-top: 10em;
}
.right {
    background-color: #FF7E00;
    margin-top: -10em;
    margin-left: 20em;
}
.top {
    background-color: #D3212D;
    margin-top: -20em;
    margin-left: 10em;
}
.bottom {
    background-color: #318CE7;
    margin-top: 10em;
    margin-left: 10em;
}
.ok {
    background-color: #3B444B;
    margin-top: -21.666em;
    margin-left: 8.333em;
    height: 13.33em;
    width: 13.33em;
}
.ok span {
    line-height: 6.666em;
    text-align: center;
    width: inherit;
    display: block;
    font-size: 2em;
    font-family: sans-serif;
    color: white;
    font-weight: bold;
}
.left:before, .left:after, .right:before, .right:after, .top:before, .top:after, .bottom:before, .bottom:after {
    position: absolute;
    content: "";
    height: inherit;
    width: inherit;
    background-color: inherit;
}
.left:before, .right:before {
    -webkit-transform: skewY(45deg);
    -moz-transform: skewY(45deg);
    -ms-transform: skewY(45deg);
    -o-transform: skewY(45deg);
    transform: skewY(45deg);
}
.top:before, .bottom:before {
    -webkit-transform: skewX(45deg);
    -moz-transform: skewX(45deg);
    -ms-transform: skewX(45deg);
    -o-transform: skewX(45deg);
    transform: skewX(45deg);
}
.left:after, .right:after {
    -webkit-transform: skewY(-45deg);
    -moz-transform: skewY(-45deg);
    -ms-transform: skewY(-45deg);
    -o-transform: skewY(-45deg);
    transform: skewY(-45deg);
}
.top:after, .bottom:after {
    -webkit-transform: skewX(-45deg);
    -moz-transform: skewX(-45deg);
    -ms-transform: skewX(-45deg);
    -o-transform: skewX(-45deg);
    transform: skewX(-45deg);
}
.left:before, .left:after, .bottom:before, .bottom:after {
    -webkit-transform-origin: 100% 0%;
    -moz-transform-origin: 100% 0%;
    -ms-transform-origin: 100% 0%;
    -o-transform-origin: 100% 0%;
    transform-origin: 100% 0%;
}
.right:before, .right:after, .top:before, .top:after {
    -webkit-transform-origin: 0% 100%;
    -moz-transform-origin: 0% 100%;
    -ms-transform-origin: 0% 100%;
    -o-transform-origin: 0% 100%;
    transform-origin: 0% 100%;
}
/*HOVER STYLES*/
.top:hover, .right:hover, .bottom:hover, .left:hover, .ok:hover {background: #F7E7CE; transition: 0.3s ease;}
.ok:hover span {color: #222;}
<div class="left"></div>
<div class="right"></div>
<div class="top"></div>
<div class="bottom"></div>
<div class="ok"><span>OK</span></div>

屏幕截图(gif)

enter image description here


浏览器支持:IE 9+,GC 4+,FF 3.5+,Safari 3.1+,Opera 11.5+

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