使用CSS3生成重复六边形图案

mrfwxfqh  于 2023-01-14  发布在  CSS3
关注(0)|答案(7)|浏览(196)

所以,我需要做一个重复的六边形图案,使用CSS。如果需要图片,我可以去那里,但我宁愿只使用CSS,如果可能的话。
下面是我想创造的东西的一个想法:

基本上,我只需要一种方法来创建六边形形状,然后在其上覆盖文本/图像。我还没有太多代码,因为我不确定从哪里开始。问题是,我可以只使用<div>的六边形形状,如(http://css-tricks.com/examples/ShapesOfCSS/),但它们不会连接。我可以使用一个重复的六边形模式,但这样我就无法在特定形状中指定所需文本或图像的确切位置。感谢您的帮助。

ni65a41a

ni65a41a1#

(虽然Ana的答案比我晚了几个月,可能是以我的答案为基础来"思考",但她能够使用单个div提出一种方法的事实值得推广,因此check out her answer too--但注意十六进制中的内容更为有限。)
这真是一个令人惊奇的问题。谢谢你问这个问题。最棒的是:
∮ ∮ ∮ ∮
Original Fiddle Used(在后面的编辑中修改了上面的fiddle链接)--它使用了www.example.com图像,这些图像在加载时似乎不是很可靠,所以新的fiddle使用了www.example.comimgur.com(background-sizeposition与新的小提琴有一些不同)。photobucket.com(let me know if there are persistent image loading issues). I've kept the original link because the explanation code below goes with that (there are a few differences in background-size or position to the new fiddle).
在阅读了您的问题后,我几乎立刻想到了这个想法,但花了一些时间来实现。我最初尝试用单个div和伪元素获得单个"hex",但据我所知,没有办法只旋转background-image(这是我需要的),所以我不得不添加一些额外的div元素来获得十六进制的右/左侧,这样我就可以使用伪元素作为background-image旋转的一种手段。
我在ie9,ff和chrome中测试过。理论上任何支持css3 transform的浏览器都应该可以工作。

    • 首次主要更新(添加说明)**

我现在有一些时间来发布一些代码解释,所以这里去:
首先,六边形是由30/60度关系和三角学定义的,所以这些角是关键的;其次,我们从十六进制网格所在的"行"开始,HTML定义为(额外的div元素有助于构建十六进制):

<div class="hexrow">
    <div>
        <span>First Hex Text</span>
        <div></div>
        <div></div>
    </div>
    <div>
        <span>Second Hex Text</span>
        <div></div>
        <div></div>
    </div>
    <div>
        <span>Third Hex Text</span>
        <div></div>
        <div></div>
    </div>
</div>

我们将使用inline-block来表示六边形display,但是我们不希望它们意外地绕到下一行而破坏网格,所以white-space: nowrap解决了这个问题。这一行中的margin将取决于您希望十六进制之间有多大的空间,可能需要进行一些实验才能得到您想要的结果。

.hexrow {
    white-space: nowrap;
    /*right/left margin set at (( width of child div x sin(30) ) / 2) 
    makes a fairly tight fit; 
    a 3px bottom seems to match*/
    margin: 0 25px 3px;
}

使用.hexrow的直接子元素,即div元素,我们形成了十六进制形状的基础。width将驱动十六进制顶部的水平方向,height是从该数字推导出来的,因为正六边形的所有边都是等长的。同样,边距将取决于间距。但这是各个六边形的"重叠"将要发生的地方,以使网格看起来发生。background-image只定义一次,就在这里。它的左移是为了至少容纳十六进制左侧增加的宽度。假设您希望文本居中,text-align处理水平(当然),但与height匹配的line-height将允许垂直居中。

.hexrow > div {
    width: 100px;
    height: 173.2px; /* ( width x cos(30) ) x 2 */
    /* For margin:
    right/left = ( width x sin(30) ) makes no overlap
    right/left = (( width x sin(30) ) / 2) leaves a narrow separation
    */
    margin: 0 25px;
    position: relative;
    background-image: url(http://i.imgur.com/w5tV4.jpg);
    background-position: -50px 0; /* -left position -1 x width x sin(30) */
    background-repeat: no-repeat;
    color: #ffffff;
    text-align: center;
    line-height: 173.2px; /*equals height*/
    display: inline-block;
}

每一个十六进制的奇数都要相对于"行"下移,每一个偶数都要上移。移位计算(宽度x cos(30)/2)也与(高度/4)相同。

.hexrow > div:nth-child(odd) {
    top: 43.3px; /* ( width x cos(30) / 2 ) */
}

.hexrow > div:nth-child(even) {
    top: -44.8px; /* -1 x( ( width x cos(30) / 2) + (hexrow bottom margin / 2)) */
}

我们使用2个子元素div来创建十六进制的"翼"。它们的大小与主十六进制矩形相同,然后旋转,并推到主十六进制的"下方"。Background-image是继承的,因此图像是相同的(当然),因为"翼"中的图像将与主矩形中的图像"对齐"。伪元素用于生成图像,因为它们需要"重新旋转"回水平(因为我们旋转了它们的父对象div来创建"翅膀")。
第一个的:before将其背景平移负量的宽度,该宽度等于十六进制的主要部分加上主要十六进制的原始背景偏移。第二个的:before将更改平移的原点,并将在x轴上偏移主要宽度,在y轴上偏移一半高度。

.hexrow > div > div:first-of-type {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    z-index: -1;
    overflow: hidden;
    background-image: inherit;

    -ms-transform:rotate(60deg); /* IE 9 */
    -moz-transform:rotate(60deg); /* Firefox */
    -webkit-transform:rotate(60deg); /* Safari and Chrome */
    -o-transform:rotate(60deg); /* Opera */
    transform:rotate(60deg);
}

.hexrow > div > div:first-of-type:before {
    content: '';
    position: absolute;
    width: 200px; /* width of main + margin sizing */
    height: 100%;
    background-image: inherit;
    background-position: top left;
    background-repeat: no-repeat;
    bottom: 0;
    left: 0;
    z-index: 1;

    -ms-transform:rotate(-60deg) translate(-150px, 0); /* IE 9 */
    -moz-transform:rotate(-60deg) translate(-150px, 0); /* Firefox */
    -webkit-transform:rotate(-60deg) translate(-150px, 0); /* Safari and Chrome */
    -o-transform:rotate(-60deg) translate(-150px, 0); /* Opera */
    transform:rotate(-60deg) translate(-150px, 0);

    -ms-transform-origin: 0 0; /* IE 9 */
    -webkit-transform-origin: 0 0; /* Safari and Chrome */
    -moz-transform-origin: 0 0; /* Firefox */
    -o-transform-origin: 0 0; /* Opera */
    transform-origin: 0 0;
}

.hexrow > div > div:last-of-type {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    z-index: -2;
    overflow: hidden;
    background-image: inherit;

    -ms-transform:rotate(-60deg); /* IE 9 */
    -moz-transform:rotate(-60deg); /* Firefox */
    -webkit-transform:rotate(-60deg); /* Safari and Chrome */
    -o-transform:rotate(-60deg); /* Opera */
    transform:rotate(-60deg);
}

.hexrow > div > div:last-of-type:before {
    content: '';
    position: absolute;
    width: 200px; /* starting width + margin sizing */
    height: 100%;
    background-image: inherit;
    background-position: top left;
    background-repeat: no-repeat;
    bottom: 0;
    left: 0;
    z-index: 1;

    /*translate properties are initial width (100px) and half height (173.2 / 2 = 86.6) */
    -ms-transform:rotate(60deg) translate(100px, 86.6px); /* IE 9 */
    -moz-transform:rotate(60deg) translate(100px, 86.6px); /* Firefox */
    -webkit-transform:rotate(60deg) translate(100px, 86.6px); /* Safari and Chrome */
    -o-transform:rotate(60deg) translate(100px, 86.6px); /* Opera */
    transform:rotate(60deg) translate(100px, 86.6px);

    -ms-transform-origin: 100% 0; /* IE 9 */
    -webkit-transform-origin: 100% 0; /* Safari and Chrome */
    -moz-transform-origin: 100% 0; /* Firefox */
    -o-transform-origin: 100% 0; /* Opera */
    transform-origin: 100% 0;
}

这个span用来存放你的文本。line-height被重置以使文本行正常,但是vertical-align: middle可以工作,因为line-height在父节点上更大。white-space被重置以允许再次换行。左/右边距可以被设置为负以允许文本进入十六进制的"翅膀"。

.hexrow > div > span {
    display: inline-block;
    margin: 0 -30px;
    line-height: 1.1;
    vertical-align: middle;
    white-space: normal;
}

您可以单独的目标行和这些行中的单元格来更改图像、span文本设置、不透明度或容纳更大的图像(将其移动到您想要的位置)等。这就是下面对第二行所做的操作。

.hexrow:nth-child(2) > div:nth-child(1) {
    background-image: url(http://i.imgur.com/7Un8Y.jpg);
}

.hexrow:nth-child(2) > div:nth-child(1) > span {
    /*change some other settings*/
    margin: 0 -20px;
    color: black;
    font-size: .8em;
    font-weight: bold;
}

.hexrow:nth-child(2) > div:nth-child(2) {
    background-image: url(http://i.imgur.com/jeSPg.jpg);
}

.hexrow:nth-child(2) > div:nth-child(3) {
    background-image: url(http://i.imgur.com/Jwmxm.jpg);
    /*you can shift a large background image, but it can get complicated
    best to keep the image as the total width (200px) and height (174px)
    that the hex would be.
    */
    background-position: -150px -120px;
    opacity: .3;
    color: black;
}

.hexrow:nth-child(2) > div:nth-child(3) > div:before {
    /*you can shift a large background image, but it can get complicated
    best to keep the image as the total width (200px) and height (174px)
    that the hex would be.
    */
    background-position: -100px -120px; /* the left shift is always less in the pseudo elements by the amount of the base shift */
}

.hexrow:nth-child(2) > div:nth-child(4) {
    background-image: url(http://i.imgur.com/90EkV.jpg);
    background-position: -350px -120px;
}

.hexrow:nth-child(2) > div:nth-child(4) > div:before {
    background-position: -300px -120px;
}
tct7dpnv

tct7dpnv2#

它实际上可以通过每个六边形一个元素和背景图像和文本的伪元素来完成。
∮ ∮ ∮
基本HTML结构:

<div class='row'>
    <div class='hexagon'></div>
</div>
<div class='row'>
    <div class='hexagon content ribbon' data-content='This is a test!!! 
    9/10'></div><!--
    --><div class='hexagon content longtext' data-content='Some longer text here.
       Bla bla bla bla bla bla bla bla bla bla blaaaah...'></div>
</div>

你可以有更多的行,你只需要在奇数行有n六边形,在偶数行有n+/-1六边形。
相关CSS

* { box-sizing: border-box; margin: 0; padding: 0; }
.row { margin: -18.5% 0; text-align: center; }
.row:first-child { margin-top: 7%; }
.hexagon {
    position: relative;
    display: inline-block;
    overflow: hidden;
    margin: 0 8.5%;
    padding: 16%;
    transform: rotate(30deg) skewY(30deg) scaleX(.866); /* .866 = sqrt(3)/2 */
}
.hexagon:before, .content:after {
    display: block;
    position: absolute;
    /* 86.6% = (sqrt(3)/2)*100% = .866*100% */
    top: 6.7%; right: 0; bottom: 6.7%; left: 0; /* 6.7% = (100% -86.6%)/2 */
    transform: scaleX(1.155) /* 1.155 = 2/sqrt(3) */ 
               skewY(-30deg) rotate(-30deg);
    background-color: rgba(30,144,255,.56);
    background-size: cover;
    content: '';
}
.content:after { content: attr(data-content); }
/* add background images to :before pseudo-elements */
.row:nth-child(n) .hexagon:nth-child(m):before {
    background-image: 
        url(background-image-mxn.jpg); 
}
n53p2ov0

n53p2ov03#

你可以只使用CSS来创建一个完全响应的六边形网格。这个想法是使用CSS2.1溢出:隐藏来创建一个父形状作为一个遮罩,它几乎兼容所有的浏览器,甚至是internet explorer 6。
这是一个非常简单的技术,可以用于创建各种形状的响应网格,它只需要跳出框框来解决问题。
我有一个广泛的一步一步的指南如何做这个技术在这里:https://www.codesmite.com/article/how-to-create-pure-css-hexagonal-grids
这是目前为止我发现的最好的方法,不需要javascript,而且流畅且响应迅速。
我还在一个免费的HTML模板中使用了这种技术,该模板包括六边形内部的图像,您可以在这里演示和下载:https://www.codesmite.com/freebie/hexa-free-responsive-portfolio-template

xesrikrc

xesrikrc4#

我将提供一个简单的演示如何创建一个六边形的形状。

.hex {
  width: 40px;
  height: 70px;
  margin: 20px;
  overflow: hidden;
}

.hex:before {
  content: "";
  transform: rotate(45deg);
  background: #f00;
  width: 50px;
  height: 50px;
  display: inline-block;
  margin: 10px -5px 10px -5px;
}
<div class="hex">
</div>
3lxsmp7m

3lxsmp7m5#

这里是使用COMPASS/SCSS的另一种方法,可以轻松设置六边形的大小和布局:
http://codepen.io/interdruper/pen/GrBEk

9ceoxa92

9ceoxa926#

我写了一篇详细的文章,介绍如何用一小段代码生成一个响应式六边形网格:https://css-tricks.com/hexagons-and-beyond-flexible-responsive-grid-patterns-sans-media-queries/
您所要做的就是更新一些CSS变量来控制网格:

.main {
  display:flex;
  --s: 100px;  /* size  */
  --m: 4px;    /* margin */
  --f: calc(1.732 * var(--s) + 4 * var(--m)  - 1px);
}

.container {
  font-size: 0; /*disable white space between inline block element */
}

.container div {
  width: var(--s);
  margin: var(--m);
  height: calc(var(--s)*1.1547); 
  display: inline-block;
  font-size:initial;
  clip-path: polygon(0% 25%, 0% 75%, 50% 100%, 100% 75%, 100% 25%, 50% 0%);
  background: red;
  margin-bottom: calc(var(--m) - var(--s)*0.2885); 
}
.container div:nth-child(odd) {
  background:green;
}
.container::before {
  content: "";
  width: calc(var(--s)/2 + var(--m));
  float: left;
  height: 120%;
  shape-outside: repeating-linear-gradient(     
                   #0000 0 calc(var(--f) - 3px),      
                   #000  0 var(--f));
}
<div class="main">
  <div class="container">
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
  </div>
</div>

也可以在Github上找到这个项目:https://github.com/Afif13/responsive-grid-shapes

g6ll5ycj

g6ll5ycj7#

如果您能够实现div形状技巧,那么只需给予每个div一个position:relative(您必须首先通过设置topleft来逐个定位它们)

相关问题