如何创建切出的六边形?

时间:2015-12-22 13:59:11

标签: html css css3 svg css-shapes

如何使用CSS创建切出的六边形?

通过切出六边形形状我的意思是这样的:

cut out hexagon

我能够创建一个带有背景图像的六边形,但我需要它像图像中那样。

.hexagon {
  position: relative;
  width: 300px;
  height: 173.21px;
  margin: 86.60px 0;
  background-image: url('https://placeimg.com/300/400/any');
  background-size: auto 346.4102px;
  background-position: center;
}

.hexTop,
.hexBottom {
  position: absolute;
  z-index: 1;
  width: 212.13px;
  height: 212.13px;
  overflow: hidden;
  -webkit-transform: scaleY(0.5774) rotate(-45deg);
  -ms-transform: scaleY(0.5774) rotate(-45deg);
  transform: scaleY(0.5774) rotate(-45deg);
  background: inherit;
  left: 43.93px;
}

/* Counter transform the background image on the caps */
.hexTop:after,
.hexBottom:after {
  content: "";
  position: absolute;
  width: 300.0000px;
  height: 173.20508075688775px;
  -webkit-transform:  rotate(45deg) scaleY(1.7321) translateY(-86.6025px);
  -ms-transform:      rotate(45deg) scaleY(1.7321) translateY(-86.6025px);
  transform:          rotate(45deg) scaleY(1.7321) translateY(-86.6025px);
  -webkit-transform-origin: 0 0;
  -ms-transform-origin: 0 0;
  transform-origin: 0 0;
  background: inherit;
}

.hexTop {
  top: -106.0660px;
}

.hexTop:after {
  background-position: center top;
}

.hexBottom {
  bottom: -106.0660px;
}

.hexBottom:after {
  background-position: center bottom;
}

.hexagon:after {
  content: "";
  position: absolute;
  top: 0.0000px;
  left: 0;
  width: 300.0000px;
  height: 173.2051px;
  z-index: 2;
  background: inherit;
}
<div class="hexagon">
  <div class="hexTop"></div>
  <div class="hexBottom"></div>
</div>

5 个答案:

答案 0 :(得分:33)

对于透明切出的六边形,我建议您使用inline SVG path element

&#13;
&#13;
svg{
  display: block;
  width: 70%;
  height: auto;
  margin: 0 auto;
}

path{
  transition: fill .5s;
  fill: #E3DFD2;
}
path:hover{
  fill: pink;
}
body{background:url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-position:center;background-size:cover;}
&#13;
<svg viewbox="-10 -2 30 14">
  <path d=" M-10 -2 H30 V14 H-10z M2.5 0.66 L0 5 2.5 9.33 7.5 9.33 10 5 7.5 0.66z" />
</svg>
&#13;
&#13;
&#13;

Transparent hexagon mask

六边形掩模点计算:

六边形坐标非常容易计算。对于上述方向的正六边形:

width = height / sin(60deg)
sin(60deg) ~=0.866

如果width为10(如上例所示),坐标为:

Transparent hexagon coordinates

您可以在第二个d之后的M属性中找到这些坐标。

为什么要使用SVG?

在这种情况下使用SVG的主要优点是:

  • 可维护性(例如:想象一下你需要改变面具的颜色。在SVG中你很清楚你需要改变什么,只有一个属性可以改变。)
  • 更短的代码
  • 您可以轻松使用图像或渐变填充蒙版
  • 保持形状的边界并触发鼠标仅在面对面具的填充上进行(在示例中悬停透明六边形)。

mask element的原始示例:

&#13;
&#13;
body{background:url('https://farm9.staticflickr.com/8760/17195790401_ceeeafcddb_o.jpg');background-position:center;background-size:cover;}

svg{
  display: block;
  width: 70%;
  height: auto;
  margin: 0 auto;
}
&#13;
<svg viewbox="-10 -2 30 14" >
  <defs>
    <mask id="mask" x="0" y="0" width="10" height="10">
      <rect x="-10" y="-2" width="40" height="16" fill="#fff"/>
      <polygon points="2.5 0.66 7.5 0.66 10 5 7.5 9.33 2.5 9.33 0 5" />
    </mask>
  </defs>
  <rect x="-10" y="-5" width="30" height="20" mask="url(#mask)" fill="#E3DFD2"/>
</svg>
&#13;
&#13;
&#13;

答案 1 :(得分:16)

这种形状可以通过使用元件填充六边形的外部来实现。应该对每个元素应用不同的transform:rotate(xdeg)以实现此效果。

以下是创建此效果的代码段。

注意:下面的代码段应该是响应式的,所以如果它看起来坏了,请看下面的代码。

* {
    margin: 0;
    padding: 0;
}

body, html {
    width: 100%;
    height: 100%;
}

body {
    display: flex;
    align-items: center;
    background: url('https://placeimg.com/800/600/any');
    background-size: cover;
    background-attachment: fixed;
}

.container {
    width: 50%;
    height: 50%;
    position: relative;
    margin: 0 auto;
    overflow: hidden;
    border: 10px solid #009688;
}

.cut:after {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 0% 100%;
    transform: rotate(-60deg);
    top: 0;
}

.cut:before {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 0% 0%;
    transform: rotate(60deg);
    top: 0;
}

.container:after {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 100% 0%;
    transform: rotate(-60deg);
    top: 0;
}

.container:before {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 100% 100%;
    transform: rotate(60deg);
    top: 0;
}
<div class="container">
    <div class="cut"></div>
</div>

固定高度和宽度(以全屏方式查看):

* {
    margin: 0;
    padding: 0;
}

body, html {
    width: 100%;
    height: 100%;
}

body {
    display: flex;
    align-items: center;
    background: url('https://placeimg.com/800/600/any');
    background-size: cover;
    background-attachment: fixed;
}

.container {
    width: 500px;
    height: 300px;
    position: relative;
    margin: 0 auto;
    overflow: hidden;
    border: 10px solid #009688;
}

.cut:after {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 0% 100%;
    transform: rotate(-60deg);
    top: 0;
}

.cut:before {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 0% 0%;
    transform: rotate(60deg);
    top: 0;
}

.container:after {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 100% 0%;
    transform: rotate(-60deg);
    top: 0;
}

.container:before {
    position: absolute;
    content: "";
    width: 100%;
    height: 100%;
    background: #009688;
    transform-origin: 100% 100%;
    transform: rotate(60deg);
    top: 0;
}
<div class="container">
    <div class="cut"></div>
</div>

切割六边形的工作原理如下:

答案 2 :(得分:11)

SVG是这类事物的最佳工具,最大的促成因素是创建和维护SVG这样的形状更容易。

但是这些可以用CSS transform以另一种方式完成,也可以使用更简单的变换。我们需要做的就是使用skew变换并根据所需的形状设置倾斜角度。

对于六边形,每边之间的角度为120度,因此元素必须倾斜+/- 30度。对于五边形,每边之间的角度为108度,因此下半部分的倾斜角度为+/- 18度,但上半部分的倾斜角度为+/- 36度。对于钻石,每侧之间的角度为90度,因此倾斜角度为+/- 45度。

这种方法的积极点是:( 不是SVG没有这些

  • 使用此方法创建的形状是响应式的(尝试将鼠标悬停在演示中的形状上)
  • 鉴于IE8即将退出(微软自己从16年1月起停止支持IE8),变换得到了很好的支持。与SVG 相比,这并不差,因为SVG具有相同的浏览器支持。

使用CSS 有很多弊端:

  • 为了产生形状,需要额外的元素。
  • 这些只适用于IE9 +(即支持转换的浏览器)。缺点不是与SVG相比,而是一般。
  • 填充切口以外的区域不能是渐变或图像。它只能是纯色。
  • 可以添加悬停效果(如演示中所示),但是当鼠标位于剪切区域上方时也会触发,因为它仍然是容器的一部分,即使它是透明的。

.shape {
  position: relative;
  height: 100px;
  border: 20px solid palevioletred;
  overflow: hidden;
}
.shape.hexagon {
  width: calc(100px + (100px * 0.577)); /* width = height + (height * tan 30) for hexagon */
}
.shape.pentagon {
  width: calc(100px * 1.051); /* width = height * 1.618/1.539 for pentagon (Source: Wiki - https://en.wikipedia.org/wiki/Pentagon */
}
.shape.diamond {
  width: 100px; /* height = width for diamond */
}
.hexagon .inner, .pentagon .inner, .diamond .inner {
  position: absolute;
  height: 100%;
  width: 50%;
  top: 0px;
  left: 85%;
}
.diamond .inner {
  left: 100%;
}
.shape:after, .shape:before {
  position: absolute;
  content: '';
  height: 50%;
  width: 50%;
  left: -35%;
  background: palevioletred;
}
.shape.diamond:before, .shape.diamond:after {
  left: -50%;
}
.hexagon .inner:after, .hexagon .inner:before, .pentagon .inner:after,
.pentagon .inner:before, .diamond .inner:after, .diamond .inner:before {
  position: absolute;
  content: '';
  height: 50%;
  width: 100%;
  left: 0px;
  background: palevioletred;
}
.shape.hexagon:before, .hexagon .inner:after {
  transform: skew(-30deg);
}
.shape.hexagon:after, .hexagon .inner:before {
  transform: skew(30deg);
}
.shape.pentagon:before {
  transform: skew(-36deg);
}
.shape.pentagon:after{
  transform: skew(18deg);
}
.shape.diamond:before, .diamond .inner:after {
  transform: skew(-45deg);
}
.shape.diamond:after, .diamond .inner:before {
  transform: skew(45deg);
}
.pentagon .inner:before {
  transform: skew(36deg);
}
.pentagon .inner:after {
  transform: skew(-18deg);
}
.shape:before, .inner:before {
  top: 0px;
  transform-origin: right bottom;
}
.shape:after, .inner:after {
  bottom: 0px;
  transform-origin: right top;
}

/* just for demonstrating responsiveness */

.shape {
  float: left;
  margin: 10px;
  transition: all 1s linear;
}
.shape:hover{ height: 150px; }
.shape.hexagon:hover { width: calc(150px + (150px * 0.577)); }
.shape.pentagon:hover { width: calc(150px * 1.051); }
.shape.diamond:hover { width: 150px; }
body {
  background: url(http://lorempixel.com/500/500/nature/6) fixed;
  background-size: cover;
}
<div class='shape hexagon'>
  <div class='inner'></div>
</div>
<div class='shape pentagon'>
  <div class='inner'></div>
</div>
<div class='shape diamond'>
  <div class='inner'></div>
</div>

enter image description here

答案 3 :(得分:7)

SVG方法显然很好!但我尝试通过CSS完成它!不知怎的,我设法把它拿到这里......

&#13;
&#13;
* {
  box-sizing: border-box;
  margin: 0;
  padding: 0
}
.relative {
  position: relative;
}
.absolute {
  position: absolute;
}
body {
  background: url('http://lorempicsum.com/up/627/300/4') no-repeat top left;
  background-size: cover;
  padding-top: 10%;
}
.parent {
  margin: 0 auto;
  display: table;
  width: 400px;
  height: 230px;
  text-align: center;
  table-layout: fixed;
}
.orange {
  display: table-cell;
  vertical-align: middle;
  background: transparent;
  width: 100%;
  height: 230px;
  margin: 0 auto;
  overflow: hidden;
  position: relative;
  border-left: 137px solid orange;
  border-right: 137px solid orange;
}
.one,
.two {
  position: relative;
  width: 126px;
  height: auto;
  display: block;
  border-left: 28px solid orange;
  border-right: 28px solid orange;
  margin: 0 auto;
}
.one {
  border-top: 60px solid transparent;
  border-bottom: 60px solid orange;
}
.two {
  border-top: 60px solid orange;
  border-bottom: 60px solid transparent;
}
&#13;
<div class="parent">
  <div class="orange">
    <div class="two"></div>
    <div class="one"></div>
  </div>
</div>
&#13;
&#13;
&#13;

答案 4 :(得分:2)

此答案说明了仅使用一个元素的成本

SVG就是这个的工具。任何CSS替代品都可能非常hacky和古怪,所以我说最好的是使用SVG。

使用CSS

使用的属性是:

  • 框阴影(用于透明区域周围的颜色)
  • 透视变换,旋转
  • 溢出隐藏
  • pseudoelement

body {
  background:url('http://i.imgur.com/TYP4Xka.jpg');
}
#box {
  height: 400px;
  width: 400px;
  position: relative;
  box-shadow: inset 70px 0 0 #444, inset -70px 0 0 #444, inset 0 0 0 50px #444;
  overflow: hidden;
}

#box:before {
  content: "";
  position: absolute;
  height: 150px; 
  width: 259.8px; /* w = h * sqrt(3) bcoz w = 2*h*cos(30deg) */
  top: 125px; /* (parentHeight - pseudoHeight)/2 */
  left: 70.1px; /* (parentWidth - pseudoWidth)/2 */
  -webkit-transform: rotate(60deg);
  -moz-transform: rotate(60deg);
  transform: rotate(60deg);
  box-shadow: 70px 0 0 #444, -70px 0 0 #444;
}

#box:after {
  content: "";
  position: absolute;
  height: 150px; 
  width: 259.8px;
  top: 125px;
  left: 70.1px;
  -webkit-transform: rotate(120deg);
  -moz-transform: rotate(120deg);
  transform: rotate(120deg);
  box-shadow: 70px 0 0 #444, -70px 0 0 #444;
}
<div id="box"></div>

注意

你也可以在动画中改变周围的形状,但要注意。不要使用大量的盒子阴影,尤其是动画。 Box-shadow的CPU使用率非常高