用边框、圆角和透明背景制作六边形形状

5

我希望用CSS3制作一个类似于以下图片的具有边框、圆角和透明背景的六边形:

rounded hexagon with border

我无法做到同时满足圆角和边框的效果。

这是我的代码:

#hexagon-circle {
  position: relative;
  margin: 1em auto;
  width: 10em;
  height: 17.32em;
  border-radius: 1em/.5em;
  background: red;
  transition: opacity .5s;
  cursor: pointer;
}
#hexagon-circle:before {
  position: absolute;
  width: inherit;
  height: inherit;
  border-radius: inherit;
  background: inherit;
  content: '';
  -webkit-transform: rotate(60deg);  /* Chrome, Opera 15+, Safari 3.1+ */
  -ms-transform: rotate(60deg);  /* IE 9 */
  transform: rotate(60deg); /* Firefox 16+, IE 10+, Opera */
}

#hexagon-circle:after {
  position: absolute;
  width: inherit;
  height: inherit;
  border-radius: inherit;
  background: inherit;
  content: '';
  -webkit-transform: rotate(-60deg);  /* Chrome, Opera 15+, Safari 3.1+ */
  -ms-transform: rotate(-60deg);  /* IE 9 */
  transform: rotate(-60deg); /* Firefox 16+, IE 10+, Opera */
}
<div id="hexagon-circle"></div>


2
你尝试过在Google中搜索“如何使用CSS制作带边框和圆角的六边形形状”吗? - Pekka
谢谢关注...我尝试了,但没有帮助...我该如何为这个设置边框:http://jsfiddle.net/yR7zt/4/ ......我的主要问题是如何设置边框....实线边框设置不是一个好主意! - miladhp
我找到了我想要的那个东西的样例 --- 我想要的东西和这个一样:http://respooonsive.com/dash/demo/index-image.html - miladhp
@miladhp:你的形状内部是透明的,还是会有填充的颜色/图像? - Harry
1
@Harry 这是透明的.. 我想在里面添加一段文字.. - miladhp
显示剩余2条评论
2个回答

9
六边形圆角图形是相对复杂的,我通常建议使用SVG来创建它们。需要透明背景使SVG更加适合。使用SVG可以更好地控制形状、曲线等,而且不必向标记中添加大量额外(不必要)的元素。
只需使用单个“path”元素和少量的“L”(线)和“A”(弧)命令即可使用SVG创建此形状。“L”(线)命令基本上从点1到点2绘制一条线,而“A”(弧)命令则绘制指定半径的弧(紧随“A”命令后面的前两个值)
你可以在此MDN教程中了解有关SVG“path”元素及其命令的更多信息。

svg {
  height: 200px;
  width: 240px;
}
path {
  stroke: #777;
  fill: none;
}

body {
  background: black;
}
<svg viewBox='0 0 120 100'>
  <path d='M38,2 
           L82,2 
           A12,12 0 0,1 94,10 
           L112,44 
           A12,12 0 0,1 112,56
           L94,90       
           A12,12 0 0,1 82,98
           L38,98
           A12,12 0 0,1 26,90
           L8,56
           A12,12 0 0,1 8,44
           L26,10
           A12,12 0 0,1 38,2' />
</svg>

如果您仍然想使用 CSS,您可以遵循 jbutler483 在他的这个网页中所使用的方法。(我也将那个网页的代码附在了这个答案中,以避免链接失效的问题

.roundHex {
  position: relative;
  margin: 0 auto;
  background: transparent;
  border-radius: 10px;
  height: 300px;
  width: 180px;
  box-sizing: border-box;
  transition: all 1s;
  border: 10px solid transparent;
  border-top-color: black;
  border-bottom-color: black;
}
.roundHex:before,
.roundHex:after {
  content: "";
  border: inherit;
  position: absolute;
  top: -10px;
  left: -10px;
  background: inherit;
  border-radius: inherit;
  height: 100%;
  width: 100%;
}
.roundHex:before {
  transform: rotate(60deg);
}
.roundHex:after {
  transform: rotate(-60deg);
}
<div class="roundHex"></div>


2
非常感谢哈利。。。使用SVG是这样做的最佳想法。。它是最简单和最好的方法来完成它。 - miladhp

2
我创建了一个Codepen,您可以自定义边长和边框半径:https://codepen.io/shreyansqt/pen/qBjprWE HTML代码:
<svg width="500" height="500">
  <path id="hexagon" fill="red" />
</svg>

JS:

const getHexagonPathData = () => {
  // #################### x1,y0 ####################
  // ############## xc1,yc0 # xc2,yc0 ##############
  // ###############################################
  // ###############################################
  // #### xc0,yc1 ##################### xc3,yc1 ####
  // ## x0,y1 ############################# x2,y1 ##
  // ## x0,yc2 ########################### x2,yc2 ##
  // ###############################################
  // ###############################################
  // ## x0,yc3 ########################### x2,yc3 ##
  // ## x0,y2 ############################# x2,y2 ##
  // #### xc0,yc4 ##################### xc3,yc4 ####
  // ###############################################
  // ###############################################
  // ############## xc1,yc5 # xc2,yc5 ##############
  // #################### x1,y3 ####################

  const sin = (deg) => Math.sin((deg * Math.PI) / 180);
  const cos = (deg) => Math.cos((deg * Math.PI) / 180);

  const borderRadius = 6;
  const sideLength = 80;
  const x0 = 0;
  const y0 = 0;

  const x1 = sideLength * cos(30);
  const y1 = sideLength * sin(30);

  const xc1 = x1 - borderRadius * cos(30);
  const yc0 = borderRadius * sin(30);
  const xc2 = x1 + borderRadius * cos(30);

  const x2 = 2 * x1;
  const y2 = y1 + sideLength;

  const xc3 = x2 - borderRadius * cos(30);
  const yc1 = y1 - borderRadius * sin(30);
  const yc2 = y1 + borderRadius;

  const y3 = y2 + y1;

  const yc3 = y2 - borderRadius;
  const yc4 = y2 + borderRadius * sin(30);

  const yc5 = y3 - borderRadius * sin(30);
  const xc0 = borderRadius * cos(30);

  return `
        M ${xc1},${yc0}
        Q ${x1},${y0} ${xc2},${yc0}

        L ${xc3},${yc1}
        Q ${x2},${y1} ${x2},${yc2}

        L ${x2},${yc3}
        Q ${x2},${y2} ${xc3},${yc4}

        L ${xc2},${yc5}
        Q ${x1},${y3} ${xc1},${yc5}
        
        L ${xc0},${yc4}
        Q ${x0},${y2} ${x0},${yc3}
        
        L ${x0},${yc2}
        Q ${x0},${y1} ${xc0},${yc1}
        Z
      `;
};

const hexagon = document.getElementById("hexagon");

hexagon.setAttribute("d", getHexagonPathData());



4
这是一个很棒的代码,尽管问题是在特别提到如何在CSS中完成这个功能(也许不需要鼠标交互)。 - P. Moloney
@P.Moloney 您的观点是正确的,技术上也是正确的,但值得注意的是,OP在接受的答案中添加了一条评论,指出提供的非CSS解决方案(即使用<svg>)是“最简单和最好的方法”。 - skomisa
惊人的@shreyansqt - Ben Racicot

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