(Bien que la réponse d'Ana soit arrivée plusieurs mois après la mienne, utilisant probablement la mienne comme base de réflexion, le fait qu'elle ait été capable de trouver une méthode en utilisant une seule div
vaut la peine d'être promu, donc Regardez aussi sa réponse -mais notez que le contenu de l'hexagone est plus limité).
C'était une question vraiment étonnante. Merci de l'avoir posée. Ce qui est génial, c'est le fait que :
Violon original utilisé (modifié dans l'édition ultérieure du lien du violon ci-dessus) - il utilisait des images imgur.com, qui ne semblaient pas être très fiables dans le chargement, donc le nouveau violon utilise photobucket.com ( faites-moi savoir s'il y a des problèmes persistants de chargement d'images ). J'ai gardé le lien original parce que le code d'explication ci-dessous va avec (il y a quelques différences en background-size
o position
au nouveau violon).
L'idée m'est venue presque instantanément après avoir lu votre question, mais il a fallu du temps pour la mettre en œuvre. J'ai d'abord essayé d'obtenir un seul "hex" avec un seul div
et des pseudo-éléments, mais il n'y a pas de moyen de faire pivoter l'image de l'utilisateur. background-image
(dont j'avais besoin), j'ai donc dû ajouter un peu de div
pour obtenir les côtés droit/gauche de l'hexagone, de sorte que je puisse ensuite utiliser les pseudo-éléments comme un moyen de background-image
rotation.
J'ai testé dans IE9, FF, et Chrome. Théoriquement, tout navigateur supportant CSS3 transform
dans lequel il devrait fonctionner.
Première mise à jour principale (explication ajoutée)
J'ai un peu de temps maintenant pour poster une explication de code, alors c'est parti :
Tout d'abord, les hexagones sont définis par des relations de 30/60 degrés et la trigonométrie, ce sont donc les principaux angles impliqués. Deuxièmement, nous commençons par une "rangée" dans laquelle la grille d'hexagones doit résider. Le HTML est défini comme (l'extra div
les éléments aident à construire l'hexagone) :
<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>
Nous allons utiliser inline-block
pour l'hexagone display
mais nous ne voulons pas qu'ils passent accidentellement à la ligne suivante et ruinent la grille, donc white-space: nowrap
résout ce problème. Le site margin
sur cette rangée va dépendre de l'espace que vous voulez entre les hexagones, et une certaine expérimentation peut être nécessaire pour obtenir ce que vous voulez.
.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;
}
En utilisant les enfants immédiats de la .hexrow
qui sont juste div
éléments, nous formons la base de la forme hexagonale. Le site width
conduira l'horizontale du sommet de l'hexagone, le height
est dérivé de ce nombre puisque tous les côtés sont de même longueur sur un hexagone régulier. Encore une fois, la marge va dépendre de l'espacement, mais c'est ici que le "chevauchement" des hexagones individuels va se produire pour que la grille ait l'air de se produire. Le site background-image
est défini une fois, ici même. Le décalage vers la gauche permet de prendre en compte au moins la largeur supplémentaire du côté gauche de l'hexagone. En supposant que vous souhaitiez centrer le texte, l'élément text-align
gère l'horizontal (bien sûr) mais le line-height
qui correspond à la height
va permettre un centrage vertical.
.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;
}
Chaque étrange hexagone que nous allons déplacer vers le bas par rapport à la "rangée" et à chaque même shift up. Le calcul du décalage (largeur x cos(30) / 2) est également identique à celui de la hauteur (hauteur / 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)) */
}
Nous utilisons 2 enfants div
pour créer les "ailes" de l'hexagone. Ils ont la même taille que le rectangle de l'hexagone principal, puis ils sont tournés et poussés "sous" l'hexagone principal. Background-image
est hérité pour que l'image soit la même (bien sûr), car l'image dans les "ailes" va être "alignée" sur celle du rectangle principal. Les pseudo-éléments sont utilisés pour générer les images, parce qu'ils doivent être ramenés à l'horizontale (puisque nous avons fait pivoter le rectangle parent). div
d'entre eux pour créer les "ailes").
Le site :before
du premier translatera son arrière-plan de la largeur de la quantité négative égale à la partie principale de l'hexagone plus le décalage d'arrière-plan original de l'hexagone principal. Le site :before
de la seconde changera le point d'origine de la translation et décalera la largeur principale sur l'axe des x, et la moitié de la hauteur sur l'axe des 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;
}
Ce site span
abrite votre texte. Le site line-height
est réinitialisée pour rendre les lignes de texte normales, mais l'option vertical-align: middle
fonctionne depuis le line-height
était plus grande sur le parent. Le site white-space
est réinitialisé pour qu'il autorise à nouveau l'emballage. La marge gauche/droite peut être définie comme négative pour permettre au texte d'entrer dans les "ailes" de l'hexagone.
.hexrow > div > span {
display: inline-block;
margin: 0 -30px;
line-height: 1.1;
vertical-align: middle;
white-space: normal;
}
Vous pouvez cibler individuellement des lignes et des cellules de ces lignes pour modifier les images, ou bien span
les paramètres du texte, ou l'opacité, ou l'adaptation d'une image plus grande (pour la déplacer à l'endroit souhaité), etc. C'est ce que font les éléments suivants pour la deuxième ligne.
.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;
}
2 votes
Il existe des masques CSS, mais le support est terrible : webkit.org/blog/181/css-masks
0 votes
Pour un même motif hexagonal utilisant le
<img>
au lieu d'une image d'arrière-plan, vous pouvez cocher la case Grille d'hexagones avec la balise <img>. .0 votes
J'ai fait une version sass de la solution de ScottS pour avoir des tailles différentes rapidement. Regardez-la ici codepen.io/mort3za/pen/wBabaB