Entonces, necesito hacer un patrón hexagonal repetido, usando CSS. Si se necesitan imágenes, puedo ir allí, pero preferiría usar CSS si es posible.
Aquí tienes una idea de lo que estoy intentando crear:
Básicamente, solo necesito una forma de crear las formas hexagonales y luego superponer texto / imágenes encima de ellas. Todavía no tengo mucho código porque no estoy seguro de por dónde empezar. El problema es que podría usar <div>
s en forma de hexágono como se muestra en ( http://css-tricks.com/examples/ShapesOfCSS/ ), pero entonces no se conectarían. Podría usar un patrón hexagonal repetido, pero entonces no podría especificar la ubicación exacta del texto o las imágenes que necesito en formas específicas. Gracias por cualquier ayuda de antemano.
fuente
<img>
etiqueta en lugar de una imagen de fondo, puede marcar Cuadrícula de hexágonos con la etiqueta <img> .Respuestas:
(Aunque la respuesta de Ana llegó meses después de la mía, probablemente usando la mía como base para "pensar desde",
div
vale la pena promocionar el hecho de que pudo idear un método usando una sola , así que revisa su respuesta también, pero tenga en cuenta que el contenido en el hexadecimal es más limitado).Esta fue una pregunta realmente asombrosa. Gracias por preguntar Lo bueno es el hecho de que:
¡Este violín demuestra que puedes hacerlo!
Original Fiddle Used (modificado en la edición posterior del enlace de violín anterior): utilizó imágenes de imgur.com, que no parecían ser muy confiables en la carga, por lo que el nuevo violín está usando photobucket.com ( avíseme si hay imágenes persistentes problemas de carga de imágenes ). He mantenido el enlace original porque el código siguiente explicación va con eso (hay algunas diferencias en
background-size
oposition
al nuevo violín).La idea se me ocurrió casi instantáneamente después de leer su pregunta, pero me tomó un tiempo implementarla. Originalmente intenté obtener un solo "hex" con un solo
div
y solo pseudo elementos, pero lo mejor que pude ver, no había forma de simplemente rotar elbackground-image
(que necesitaba), así que tuve que agregar algunosdiv
elementos adicionales para obtener el correcto / lados izquierdos del hexágono, para que luego pudiera usar los pseudo elementos como un medio debackground-image
rotación.Probé en IE9, FF y Chrome. En teoría, cualquier navegador que admita CSS3
transform
debería funcionar.Primera actualización principal (explicación agregada)
Ahora tengo algo de tiempo para publicar una explicación del código, así que aquí va:
Primero, los hexágonos se definen por relaciones de 30/60 grados y trigonometría, por lo que esos serán los ángulos clave involucrados. En segundo lugar, comenzamos con una "fila" para que resida la cuadrícula hexadecimal. El HTML se define como (los
div
elementos adicionales ayudan a construir el hexadecimal):<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>
Vamos a usar
inline-block
para el hexágonodisplay
, pero no queremos que pasen accidentalmente a la siguiente línea y arruinen la cuadrícula, asíwhite-space: nowrap
que resuelve ese problema. Elmargin
de esta fila dependerá de cuánto espacio desee entre los hexágonos, y es posible que se necesite algo de experimentación para obtener lo que desea..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; }
Usando los hijos inmediatos de los
.hexrow
que son solodiv
elementos, formamos la base para la forma hexagonal. Lawidth
conducirá el horizontal de la parte superior de la hexagonal, laheight
deriva de ese número desde todos los lados son de igual longitud en un hexágono regular. Nuevamente, el margen dependerá del espaciado, pero aquí es donde se producirá la "superposición" de los hexágonos individuales para que se produzca el aspecto de la cuadrícula. Sebackground-image
define una vez, aquí mismo. El cambio a la izquierda es para acomodar al menos el ancho adicional para el lado izquierdo del hexágono. Suponiendo que desea texto centrado, eltext-align
maneja el horizontal (por supuesto) pero elline-height
que coincide con elheight
permitirá un centrado 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; }
Cada extraña número hexadecimal que se va a desplazar hacia abajo en relación con la "fila" y cada incluso hacer el cambio. El cálculo de desplazamiento (ancho x cos (30) / 2) también es el mismo que (alto / 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)) */ }
Estamos usando 2
div
elementos secundarios para crear las "alas" del hex. Tienen el mismo tamaño que el rectángulo hexagonal principal, y luego se giran y se empujan "debajo" del hexágono principal.Background-image
se hereda para que la imagen sea la misma (por supuesto), porque la imagen en las "alas" se "alineará" con la del rectángulo principal. Los pseudo elementos se utilizan para generar las imágenes, porque necesitan ser "rotados" de nuevo a la horizontal (ya que giramos el padrediv
de ellos para crear las "alas").El
:before
del primero traducirá su fondo al ancho de la cantidad negativa igual a la parte principal del hexágono más el desplazamiento de fondo original del hexágono principal. El:before
del segundo cambiará el punto de origen de la traslación y cambiará el ancho principal en el eje xy la mitad de la altura en el eje 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; }
Esto
span
alberga su texto. Seline-height
restablece para que las líneas de texto sean normales, perovertical-align: middle
funciona ya queline-height
era más grande en el padre. Sewhite-space
reinicia para que permita volver a envolver. El margen izquierdo / derecho se puede establecer en negativo para permitir que el texto entre en las "alas" del hex..hexrow > div > span { display: inline-block; margin: 0 -30px; line-height: 1.1; vertical-align: middle; white-space: normal; }
Puede seleccionar filas y celdas individualmente en esas filas para cambiar las imágenes, la
span
configuración del texto o la opacidad, o acomodar una imagen más grande (para cambiarla al lugar que desee), etc. Eso es lo que hace lo siguiente para la segunda fila..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; }
fuente
div.container
: el diseño se estropea cuando el hexágono está dentro de este contenedor div. Sin embargo, lo extraño es mirar la comparación entre cada escenario: enlace y enlace . ¡Hice algunas pruebas pero no puedo entender qué está arruinando los hexágonos!overflow: hidden
haría lo que muestra), pero no parece ser así. Mire el anidamiento de segundo niveldiv
y su:before
código, porque es probable quediv
no esté rotando en la transformación, obackground-image
que no esté heredando tanto esodiv
como su:before
pseudoelemento.display:block
.z-index
. Lo estoy modificando ahora para asegurarme de que todo funcione correctamente.En realidad, se puede hacer con un solo elemento por hexágono y pseudoelementos para la imagen de fondo y el texto.
manifestación
Estructura HTML básica :
<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>
Puede tener muchas más filas, solo necesita tener
n
hexágonos en filas impares yn+/-1
hexágonos en filas pares.CSS relevante :
* { 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); }
fuente
.content:after
con.hexagon > *
. Ingenioso.Proporcionaré una demostración simple de cómo crear una forma hexagonal.
.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>
fuente
Aquí hay otro enfoque que usa COMPASS / SCSS, que permite establecer fácilmente el tamaño y el diseño de los hexágonos:
http://codepen.io/interdruper/pen/GrBEk
fuente
Puede crear una cuadrícula hexagonal totalmente receptiva utilizando solo CSS. La idea es crear una forma principal como una máscara usando CSS2.1 overflow: hidden que es compatible con casi todos los navegadores, incluso Internet Explorer 6.
Es una técnica sorprendentemente simple que se puede usar para crear una cuadrícula receptiva de todo tipo de formas, solo requiere pensar fuera de la caja para resolver el problema.
Tengo una extensa guía paso a paso sobre cómo hacer esta técnica aquí: https://www.codesmite.com/article/how-to-create-pure-css-hexagonal-grids
Esta es la mejor forma que he encontrado hasta ahora, no requiere javascript y es fluida y receptiva.
También utilicé la técnica en una plantilla HTML gratuita que incluye imágenes dentro de los hexágonos que puedes hacer una demostración y descargar aquí: https://www.codesmite.com/freebie/hexa-free-responsive-portfolio-template
fuente
si puede implementar el truco de las formas div, simplemente dé a cada div a
position:relative
(inicialmente tendría que colocarlos todos uno por uno al principio, estableciendo tambiéntop
yleft
)fuente
AFAIK, no hay forma de hacerlo en CSS puro. Su mejor opción sería usar el recorte de máscara para los fondos como se explica aquí: http://www.cssbakery.com/2009/06/background-image.html (esto solo funcionará si el fondo de su página es de color sólido o si puede ajustar y coloque su máscara para que coincida con el fondo de la página.
Entonces puede usar csstextwrap para encajar en el texto: http://www.csstextwrap.com/examples.php
Hubo un montón de preguntas similares sobre SO. Por ejemplo, ¿ alguna forma de que el texto en div llene una forma de triángulo?
fuente