带边框/轮廓的六边形形状

19

我知道可以使用以下代码创建一个六边形:

.hex:before {
    content: " ";
    width: 0; height: 0;
    border-bottom: 30px solid #6C6;
    border-left: 52px solid transparent;
    border-right: 52px solid transparent;
    position: absolute;
    top: -30px;
}

.hex {
    margin-top: 30px;
    width: 104px;
    height: 60px;
    background-color: #6C6;
    position: relative;
}

.hex:after {
    content: "";
    width: 0;
    position: absolute;
    bottom: -30px;
    border-top: 30px solid #6C6;
    border-left: 52px solid transparent;
    border-right: 52px solid transparent;
}

我该如何创建一个由一种颜色填充、另一种颜色描边的六边形?我试着调整它,但似乎无法实现。

欢迎提供任何其他选择,我想避免使用图片。


看一下这个CSS六边形教程:http://jtauber.github.io/articles/css-hexagon.html - Vinay Pratap Singh Bhadauria
那正是我获取代码的地方。我的问题是,我想要一个白色六边形,并带有绿色轮廓线,而不是绿色六边形。 - Arkuen
请为您的问题创建一个 Fiddle,这样更容易进行工作。 - Vinay Pratap Singh Bhadauria
这样行吗?我在原帖中包含了代码。http://jsfiddle.net/uTfCY/ - Arkuen
7个回答

22

由于六边形是通过伪元素的边框创建的,因此无法直接实现此目标。另一种方法是在六边形内部覆盖其他六边形,从而实现相同的预期结果。

下面是一个示例,展示了可以实现的效果:

hexagon image enter image description here

实时示例在这里

HTML - 相当基础,继续使用相同的模式添加更多边框。

<div class="hex">
    <div class="hex inner">
        <div class="hex inner2"></div>
    </div>
</div>

CSS(三层 - 两个内部元素)

从六边形类开始,定义形状/大小/颜色:

.hex {
    margin-top: 70px;
    width: 208px;
    height: 120px;
    background: #6C6;
    position: relative;
}
.hex:before, .hex:after {
    content:"";
    border-left: 104px solid transparent;
    border-right: 104px solid transparent;
    position: absolute;
}
.hex:before {
    top: -59px;
    border-bottom: 60px solid #6C6;
}
.hex:after {
    bottom: -59px;
    border-top: 60px solid #6C6;
}

为内部类设置样式,并使用transform: scale()按比例减小内部元素的尺寸。在此示例中,使用了scale(.8, .8)的缩放比例。如果想要更粗的边框,请减小数字;相反,如果想要更细的边框,请增加数字。

指定并覆盖颜色,同时增加z-index值以将元素置于前方。

.hex.inner {
    background-color:blue;
    -webkit-transform: scale(.8, .8);
    -moz-transform: scale(.8, .8);
    transform: scale(.8, .8);
    z-index:1;
}
.hex.inner:before {
    border-bottom: 60px solid blue;
}
.hex.inner:after {
    border-top: 60px solid blue;
}

按照与上一次相同的步骤,样式化第二个嵌套元素。需要注意的是,使用了相同的scale值,因为它在已经缩放的元素内部。当然,您可以使用任何您想要的值;这只是一个基本示例。

.hex.inner2 {
    background-color:red;
    -webkit-transform: scale(.8, .8);
    -moz-transform: scale(.8, .8);
    transform: scale(.8, .8);
    z-index:2;
}
.hex.inner2:before {
    border-bottom: 60px solid red;
}
.hex.inner2:after {
    border-top: 60px solid red;
}

再次, 这里有一个实时演示例子


2
没错!能否让轮廓线的宽度四面都相等呢? - Arkuen
1
@Anon 好的,给我一秒钟,你只需要使它们成比例即可。 - Josh Crozier
2
太棒了。非常感谢! - Arkuen

17

使用clip-path特性可以创建带有边框(或轮廓线)的六边形的另一种方法。在这种方法中,我们使用一个容器元素和一个伪元素,其尺寸(heightwidth)都比容器小。当相同的clip-path应用于两个元素时,容器元素的background-color只在伪元素的边缘处可见,并使其看起来像形状的边框/轮廓线。

enter image description here

优点:

  • 六边形也可以具有渐变或图像(基本上是非纯色)作为background
  • 形状是响应式的,可以自动适应容器尺寸的任何更改。

.hexagon {
  position: relative;
  height: 150px;
  width: 150px;
  background: black;
}
.hexagon:before, .double:after {
  position: absolute;
  content: '';
}
.hexagon:before {
  top: 4px;  /* border width */
  left: 4px;  /* border width */
  height: calc(100% - 8px);  /* 100% - (2 * border width) */
  width: calc(100% - 8px);  /* 100% - (2 * border width) */
  background: #6c6;
}
.hexagon, .hexagon:before, .double:after {
  -webkit-clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
  clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}
.image:before {
  background: url(http://lorempixel.com/150/150/nature/1);
}
.double:after {
  top: 8px;
  left: 8px;
  height: calc(100% - 16px);
  width: calc(100% - 16px);
  background: black;
}

/* Just for demo */

.hexagon {
  display: inline-block;
  margin: 20px;
}
<div class="hexagon"></div>
<div class="hexagon image"></div>
<div class="hexagon double"></div>

主要缺点是目前在浏览器上支持度较低。CSS clip-path 目前在IE和FF中不起作用。可以通过使用SVG(内联或外部)来解决FF的问题。点击这里查看支持情况。

.hexagon {
  position: relative;
  height: 150px;
  width: 150px;
  background: black;
}
.hexagon:before, .double:after {
  position: absolute;
  content: '';
}
.hexagon, .hexagon:before, .double:after {
  -webkit-clip-path: url(#hexagon-clip);
  clip-path: url(#hexagon-clip);
}
.hexagon:before {
  top: 4px;  /* border width */
  left: 4px;  /* border width */
  height: calc(100% - 8px);  /* 100% - (2 * border width) */
  width: calc(100% - 8px);  /* 100% - (2 * border width) */
  background: #6c6;
}
.image:before {
  background: url(http://lorempixel.com/200/200);
}
.double:after {
  top: 8px;
  left: 8px;
  height: calc(100% - 16px);
  width: calc(100% - 16px);
  background: black;
}

/* Just for demo */

.hexagon {
  display: inline-block;
  margin: 20px;
}
<svg width="0" height="0">
  <defs>
    <clipPath id="hexagon-clip" clipPathUnits="objectBoundingBox">
      <path d="M0.5 0, 1 0.25, 1 0.75, 0.5 1, 0 0.75, 0, 0.25z" />
    </clipPath>
  </defs>
</svg>
<div class="hexagon"></div>
<div class="hexagon image"></div>
<div class="hexagon double"></div>


由于这篇文章已经过去了很长时间。看起来浏览器支持已经提高了:https://developer.mozilla.org/en-US/docs/Web/CSS/clip-path 现在片段可以在Firefox上运行,如果我理解正确的话,自版本54以来就可以了。 - Marco de Wild

3
完成了将六边形形状放在另一个上面的任务,其中黑色六边形在底部,白色在顶部。
以下是结果: enter image description here 此处有jsFiddle 将只像一个边框。

3
你可以只用一个元素来创建它,使用scaleXrotate变换。这个方法与这里使用的相同,但在顶部添加了一个额外的伪元素。 演示

body{font-size: 25px;}
div {
    margin: 3em 0;
    width: 10em;
    height: 5.7736em; /*width / 2*0.866*/
    background: orange;
    box-shadow: inset -1.22em 0 0 0 navy, inset 1.22em 0 0 0 navy, inset -2.44em 0 0 0 crimson, inset 2.44em 0 0 0 crimson;
    position: relative;
}
div:before, div:after {
    content: '';
    position: absolute;
    background: inherit;
    width:4.08em; 
    height:4.08em;
    -webkit-transform-origin: 0 100%;
    -moz-transform-origin: 0 100%;
    -ms-transform-origin: 0 100%;
    transform-origin: 0 100%;
    -webkit-transform: scaleX(1.73) rotate(45deg);
    -moz-transform: scaleX(1.73) rotate(45deg);
    -ms-transform: scaleX(1.73) rotate(45deg);
    transform: scaleX(1.73) rotate(45deg);
}
div:before {
    top: -4.08em;
    box-shadow: inset 0 1em 0 0 navy, inset 1em 0 0 0 navy, inset 0 2em 0 0 crimson, inset 2em 0 0 0 crimson;
}
div:after {
    bottom: 0;
    box-shadow: inset 0 -1em 0 0 navy, inset -1em 0 0 0 navy, inset 0 -2em 0 0 crimson, inset -2em 0 0 0 crimson;
}
<div></div>

你甚至可以在鼠标悬停时为这个六边形添加过渡效果:Fiddle(悬停过渡)

输入图像描述

在这里使用盒子阴影的缺点是它们会在Firefox上创建可见的锯齿状边缘。


2
刚刚发现了一个链接,可以使用六边形设计师,复制HTML和CSS代码以获得所需的效果。我想把它留在这里,供其他看到这篇文章的人使用。

因此,使用该工具,可以得到一个白色六边形并带有绿色轮廓线:

.hexagon {
  position: relative;
  width: 100px; 
  height: 57.74px;
  background-color: #ffffff;
  margin: 28.87px 0;
  border-left: solid 5px #28bf20;
  border-right: solid 5px #28bf20;
}

.hexagon:before,
.hexagon:after {
  content: "";
  position: absolute;
  z-index: 1;
  width: 70.71px;
  height: 70.71px;
  -webkit-transform: scaleY(0.5774) rotate(-45deg);
  -ms-transform: scaleY(0.5774) rotate(-45deg);
  transform: scaleY(0.5774) rotate(-45deg);
  background-color: inherit;
  left: 9.6447px;
}

.hexagon:before {
  top: -35.3553px;
  border-top: solid 7.0711px #28bf20;
  border-right: solid 7.0711px #28bf20;
}

.hexagon:after {
  bottom: -35.3553px;
  border-bottom: solid 7.0711px #28bf20;
  border-left: solid 7.0711px #28bf20;
}
<div class="hexagon"></div>


1
如果像我一样,你不喜欢为了样式而纯粹使用HTML元素的想法,那么这里有一个解决方案,只使用一个元素,允许在其中放置任何你想要的内容:

.hexagon {
    position: relative;
    height: 150px;
    width: 150px;
    /* We cut the element in an hexagonal shape */
    clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
}

.hexagon::after { 
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    content: '';  
    background: black;
    clip-path: polygon(
        /* We first go around the pseudo element to recreate the hexagon */
        50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%, 
        /* We make sure to close the hexagon and go back to the start */
        50% 0%, 
        /* We then go down inside the hexagon (feel free to change the border size, here it is of 10px)*/
        50% 10px,
        /* We finally go around the pseudo element in reverse to carve a smaller hexagon inside */
        /* 0.49999999999999994 is sin(30deg) as it's only supported in Safari for now */
        10px calc(25% + 10px * 0.49999999999999994), 10px calc(75% + 10px * -0.49999999999999994), 50% calc(100% - 10px), calc(100% - 10px) calc(75% + 10px * -0.49999999999999994), calc(100% - 10px) calc(25% + 10px * 0.49999999999999994), 50% 10px
    );

}
<div class="hexagon">
    <image src="https://picsum.photos/150"/> 
</div>


0

I made it by using three different elements and is fully working It is the easiest way and you can use the default html borders

<!Doctype HTML>
<html >
<head >
 <title >hexagon with border</title>
 <style >

  .hexinner,.hexinner2,.hexinner3{
    width: 208px;
    height: 120px;
    background: #6C6;
    position: fixed;
    left:30%;
    top: 30%;
    border-left:solid red 3px;
    border-right:solid violet 4px;
  }
  .hexinner2{
    transform: rotate(60deg);
  }
   .hexinner3{
    transform: rotate(-60deg);
  }
</style>
</head>
<body >

<h3 class="hexinner"> </h3>
    <h3 class="hexinner2"> </h3>
    <h3 class="hexinner3"> </h3>
</body>
</html>


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