Pertanyaan Hasilkan pola heksagonal berulang dengan CSS3


Jadi, saya perlu membuat pola heksagonal berulang, menggunakan CSS. Jika gambar diperlukan, saya bisa pergi ke sana, tetapi saya lebih suka menggunakan CSS jika memungkinkan.

Berikut adalah gagasan tentang apa yang saya coba buat:

enter image description here

Pada dasarnya, saya hanya perlu cara untuk membuat bentuk heksagonal, dan kemudian overlay teks / gambar di atasnya. Saya belum punya banyak kode, karena saya tidak yakin harus mulai dari mana. Masalahnya adalah, saya hanya bisa menggunakannya <div>s dalam bentuk segi enam seperti ditunjukkan dalam (http://css-tricks.com/examples/ShapesOfCSS/), tetapi kemudian mereka tidak akan terhubung. Saya bisa menggunakan pola segi enam berulang, tetapi kemudian saya tidak dapat menentukan lokasi persis dari teks atau gambar yang saya butuhkan dalam bentuk tertentu. Terima kasih atas bantuan apa pun sebelumnya.


75
2018-04-08 12:45


asal


Jawaban:


(Meskipun jawaban Ana datang berbulan-bulan setelah saya, mungkin menggunakan saya sebagai dasar untuk "berpikir dari", fakta bahwa dia bisa datang dengan metode menggunakan satu div layak mempromosikan, jadi periksa jawabannya juga--tapi perhatikan bahwa konten dalam hex lebih terbatas.)

Ini adalah pertanyaan yang sangat luar biasa. Terima kasih sudah menanyakannya. Hal yang hebat adalah kenyataan bahwa:

Fiddle Ini Membuktikan Anda Bisa Melakukannya!

Fiddle Asli Digunakan (dimodifikasi di kemudian diedit untuk link di atas) - itu digunakan imgur.com gambar, yang tampaknya tidak sangat handal dalam memuat, sehingga biola baru menggunakan photobucket.com (beri tahu saya jika ada masalah pemuatan gambar yang persisten). Saya telah menyimpan tautan asli karena kode penjelasan di bawah ini sesuai dengan itu (ada beberapa perbedaan dalam background-size atau position ke biola baru).

Idenya datang kepada saya hampir seketika setelah membaca pertanyaan Anda, tetapi butuh beberapa waktu untuk mengimplementasikannya. Saya awalnya mencoba mendapatkan "hex" tunggal dengan satu div dan hanya elemen semu, tetapi sebaik yang saya tahu, tidak ada cara untuk memutar background-image (yang saya butuhkan), jadi saya harus menambahkan beberapa tambahan div elemen untuk mendapatkan sisi kanan / kiri hex, sehingga saya kemudian dapat menggunakan elemen pseudo sebagai sarana background-image rotasi.

Saya menguji di IE9, FF, dan Chrome. Secara teoritis browser apa pun yang mendukung CSS3 transform itu harus bekerja.

First Main Update (penjelasan tambahan)

Saya punya waktu sekarang untuk memposting beberapa penjelasan kode, jadi begini:

Pertama, hexagon didefinisikan oleh hubungan 30/60 derajat dan trigonometri, sehingga mereka akan menjadi sudut kunci yang terlibat. Kedua, kita mulai dengan "baris" untuk grid hex untuk berada di dalamnya. HTML didefinisikan sebagai (ekstra div elemen membantu membangun hex):

<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>

Kami akan gunakan inline-block untuk segi enam display, tapi kami tidak ingin mereka secara tidak sengaja membungkus ke baris berikutnya dan merusak grid, jadi white-space: nowrap memecahkan masalah itu. Itu margin pada baris ini akan tergantung pada seberapa banyak ruang yang Anda inginkan antara hex, dan beberapa eksperimen mungkin diperlukan untuk mendapatkan apa yang Anda inginkan.

.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;
}

Menggunakan anak-anak langsung dari .hexrowyang adil div elemen, kami membentuk dasar untuk bentuk hex. Itu width akan mendorong horisontal bagian atas hex, the height berasal dari bilangan itu karena semua sisinya memiliki panjang yang sama pada segi enam reguler. Sekali lagi, margin akan tergantung pada jarak, tetapi ini adalah di mana "tumpang tindih" dari hexagon individu akan terjadi untuk membuat tampilan grid terjadi. Itu background-image didefinisikan sekali, di sini. Pergeseran kiri di atasnya adalah untuk mengakomodasi setidaknya lebar tambahan untuk sisi kiri hex. Dengan asumsi Anda ingin teks terpusat, text-align menangani horisontal (tentu saja) tetapi line-height yang cocok dengan height akan memungkinkan untuk centering vertikal.

.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;
}

Setiap aneh nomor hex kita akan bergeser ke bawah dalam kaitannya dengan "baris" dan masing-masing bahkan bergeser ke atas. Perhitungan pergeseran (lebar x cos (30) / 2) juga sama dengan (tinggi / 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)) */
}

Kami menggunakan 2 anak div elemen untuk menciptakan "sayap" dari hex. Mereka berukuran sama dengan persegi panjang hex utama, dan kemudian diputar, dan mendorong "bawah" hex utama. Background-image diwariskan sehingga gambarnya sama (tentu saja), karena gambar di "sayap" akan "dijajarkan" ke dalam persegi panjang utama. Elemen pseudo digunakan untuk menghasilkan gambar, karena mereka harus "dirotasi ulang" kembali ke horizontal (karena kita memutar induknya div dari mereka untuk menciptakan "sayap").

Itu :before yang pertama akan menerjemahkan latar belakangnya lebar dari jumlah negatif sama dengan bagian utama dari hex ditambah pergeseran latar belakang asli dari hex utama. Itu :before yang kedua akan mengubah titik asal terjemahan dan akan menggeser lebar utama pada sumbu x, dan setengah tinggi pada sumbu 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;
}

Ini span merumahkan teks Anda. Itu line-height direset untuk membuat garis teks normal, tetapi vertical-align: middle bekerja sejak line-height lebih besar pada orang tua. Itu white-space disetel ulang sehingga memungkinkan pembungkus lagi. Margin kiri / kanan dapat diatur ke negatif untuk memungkinkan teks masuk ke "sayap" dari hex.

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

Anda dapat menargetkan baris dan sel individual di baris tersebut untuk mengubah gambar, atau span pengaturan teks, atau opasitas, atau mengakomodasi gambar yang lebih besar (untuk menggesernya ke tempat yang Anda inginkan), dll. Itulah yang dilakukan berikut untuk baris kedua.

.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;
}

128
2018-04-09 02:41



Ini sebenarnya dapat dilakukan hanya dengan satu elemen per segi enam dan elemen semu untuk gambar latar belakang dan teks.

demo

Dasar HTML struktur:

<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>

Anda dapat memiliki lebih banyak baris, Anda hanya perlu memiliki n hexagon pada baris ganjil dan n+/-1 segienam pada baris genap.

Relevan 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); 
}

51
2017-10-25 13:05



Saya akan memberikan demo sederhana tentang cara membuat bentuk heksagonal.

.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>


2
2018-04-09 03:24



Berikut ini pendekatan lain menggunakan COMPASS / SCSS, yang memungkinkan dengan mudah mengatur ukuran dan tata letak heksagonal:

http://codepen.io/interdruper/pen/GrBEk


1
2018-05-03 10:59



jika Anda dapat mengimplementasikan trik bentuk div, maka cukup beri setiap div a position:relative(Anda harus awalnya memposisikan mereka semua satu per satu pada awalnya, dengan pengaturan juga top dan left)


0
2018-04-08 13:00



Anda dapat membuat kisi heksagonal yang sepenuhnya responsif hanya menggunakan CSS. Idenya adalah untuk membuat bentuk induk sebagai topeng menggunakan CSS2.1 overflow: tersembunyi yang kompatibel dengan hampir semua browser, bahkan internet explorer 6.

Ini adalah teknik yang sangat sederhana yang dapat digunakan untuk membuat grid responsif dari semua jenis bentuk, itu hanya membutuhkan pemikiran di luar kotak untuk memecahkan masalah.

Saya memiliki panduan langkah demi langkah tentang cara melakukan teknik ini di sini: https://www.codesmite.com/article/how-to-create-pure-css-hexagonal-grids

Ini adalah cara terbaik yang saya temukan sejauh ini, tidak memerlukan javascript dan bersifat cair dan responsif.

Saya juga menggunakan teknik dalam template HTML gratis yang menyertakan gambar di dalam hexagon yang dapat Anda demo dan unduh di sini: https://www.codesmite.com/freebie/hexa-free-responsive-portfolio-template


0
2018-01-21 06:54



AFAIK, tidak ada cara untuk melakukan CSS murni. Taruhan terbaik Anda adalah menggunakan kliping topeng untuk latar belakang seperti yang dijelaskan di sini: http://www.cssbakery.com/2009/06/background-image.html (ini hanya akan berfungsi jika latar belakang halaman Anda berwarna solid atau Anda dapat memasang dan menempatkan topeng Anda untuk menyesuaikan dengan latar belakang halaman.

Kemudian Anda bisa menggunakan csstextwrap agar sesuai dengan teks: http://www.csstextwrap.com/examples.php

Ada banyak pertanyaan serupa di SO. Misalnya. Cara apa pun agar teks dalam div mengisi bentuk segitiga?


-2
2018-04-08 19:46