Muszę więc stworzyć powtarzający się sześciokątny wzór, używając CSS. Jeśli potrzebne są obrazy, mogę tam wejść, ale wolałbym po prostu użyć CSS, jeśli to możliwe.
Oto pomysł na to, co próbuję stworzyć:
Po prostu potrzebuję sposobu na utworzenie sześciokątnych kształtów, a następnie nałożenie na nie tekstu / obrazów. Nie mam jeszcze dużo kodu, ponieważ nie bardzo wiem, od czego zacząć. Problem w tym, że mógłbym po prostu użyć <div>
s w kształcie sześciokąta, jak pokazano na ( http://css-tricks.com/examples/ShapesOfCSS/ ), ale wtedy nie będą się łączyć. Mógłbym użyć powtarzającego się wzoru sześciokąta, ale wtedy nie byłbym w stanie określić dokładnej lokalizacji potrzebnego tekstu lub obrazów w określonych kształtach. Z góry dziękuję za pomoc.
źródło
<img>
tagu zamiast obrazu tła, możesz sprawdzić Siatkę sześciokątów za pomocą tagu <img> .Odpowiedzi:
(Chociaż odpowiedź Any nadeszła kilka miesięcy po mojej, prawdopodobnie wykorzystując moją jako podstawę do „myślenia”, fakt, że była w stanie wymyślić metodę wykorzystującą singiel,
div
jest wart promowania, więc sprawdź też jej odpowiedź - ale Zwróć uwagę, że zawartość na heksie jest bardziej ograniczona.)To było naprawdę niesamowite pytanie. Dziękuję, że o to zapytałeś. Wspaniałe jest to, że:
To skrzypce udowadnia, że możesz to zrobić!
Oryginalne skrzypce używane (zmodyfikowane w późniejszej edycji do linku skrzypcowego powyżej) - wykorzystywały obrazy imgur.com, które nie wydawały się bardzo niezawodne w ładowaniu, więc nowe skrzypce używają photobucket.com ( daj mi znać, jeśli są trwałe problemy z ładowaniem obrazu ). Mam zachował pierwotną więź, ponieważ poniżej kod który idzie z wyjaśnieniem (istnieje kilka różnic
background-size
lubposition
do nowego skrzypce).Pomysł przyszedł mi do głowy niemal natychmiast po przeczytaniu twojego pytania, ale jego wdrożenie zajęło trochę czasu. Początkowo próbowałem uzyskać pojedynczy „hex” z jednym
div
i tylko pseudoelementami, ale najlepiej, jak mogłem powiedzieć, nie było sposobu, aby po prostu obrócićbackground-image
(czego potrzebowałem), więc musiałem dodać kilka dodatkowychdiv
elementów, aby uzyskać właściwą / lewe boki hexa, abym mógł wtedy użyć pseudoelementów jako środkabackground-image
obrotu.Testowałem w IE9, FF i Chrome. Teoretycznie każda przeglądarka obsługująca CSS3, w
transform
której powinna działać.Pierwsza główna aktualizacja (dodano wyjaśnienie)
Mam teraz trochę czasu, aby opublikować wyjaśnienie kodu, więc oto:
Po pierwsze, sześciokąty są definiowane przez relacje 30/60 stopni i trygonometrię, więc będą to kluczowe kąty. Po drugie, zaczynamy od „wiersza”, w którym ma się znajdować siatka szesnastkowa. Kod HTML jest zdefiniowany jako (dodatkowe
div
elementy pomagają zbudować 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>
Będziemy używać
inline-block
sześciokątadisplay
, ale nie chcemy, aby przypadkowo zawinął do następnej linii i zrujnował siatkę, więcwhite-space: nowrap
rozwiązujemy ten problem. Wartośćmargin
w tym wierszu będzie zależeć od tego, ile chcesz odstępu między heksami, i może być potrzebne trochę eksperymentów, aby uzyskać to, czego chcesz..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; }
Używając bezpośrednich elementów potomnych,
.hexrow
które są tylkodiv
elementami, tworzymy podstawę dla kształtu heksadecymalnego.width
Pojedzie poziomy z góry hex Theheight
pochodzi od tej liczby, ponieważ wszystkie boki są równej długości na sześciokąta foremnego. Ponownie, margines będzie zależał od odstępów, ale w tym miejscu wystąpi „nakładanie się” poszczególnych sześciokątów, aby uzyskać wygląd siatki. Tobackground-image
jest zdefiniowane raz, właśnie tutaj. Przesunięcie z lewej strony ma na celu uwzględnienie co najmniej dodanej szerokości lewej strony heksa. Zakładając, że chcesz wyśrodkować tekst,text-align
uchwyt obsługuje położenie poziome (oczywiście), ale to,line-height
co pasujeheight
do, pozwoli na wyśrodkowanie w pionie..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; }
Każde szesnastkowe liczby nieparzyste przesuniemy w dół w stosunku do „rzędu”, a każda parzysta zmiana w górę. Obliczenie przesunięcia (szerokość x cos (30) / 2) jest również takie samo jak (wysokość / 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)) */ }
Używamy 2
div
elementów potomnych do stworzenia „skrzydeł” heksa. Mają taki sam rozmiar jak główny sześciokątny prostokąt, a następnie są obracane i wypychane „poniżej” głównego heksa.Background-image
jest dziedziczona, więc obraz jest taki sam (oczywiście), ponieważ obraz w "skrzydłach" będzie "wyrównany" do tego w głównym prostokącie. Pseudoelementy są używane do generowania obrazów, ponieważ należy je „ponownie obrócić” z powrotem do poziomu (ponieważ obróciliśmydiv
ich rodziców, aby utworzyć „skrzydła”).Pierwsza
:before
z nich przetłumaczy swoje tło na szerokość ujemnej wartości równej głównej części szesnastki plus oryginalne przesunięcie tła głównego szesnastki.:before
Z drugiego zmienia punkt początkowy translacji i przesuwa główną szerokość na osi x, a w połowie wysokości na osi 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; }
To
span
mieści twój tekst.line-height
Jest resetowany, aby linie tekstu normalne, alevertical-align: middle
prace Ponieważline-height
był większy od rodzica.white-space
Jest resetowany co pozwala zawijanie ponownie. Marginesy lewy / prawy można ustawić na wartość ujemną, aby umożliwić umieszczenie tekstu w „skrzydłach” heksa..hexrow > div > span { display: inline-block; margin: 0 -30px; line-height: 1.1; vertical-align: middle; white-space: normal; }
Możesz wybrać poszczególne wiersze i komórki w tych wierszach, aby zmienić obrazy,
span
ustawienia tekstu lub krycie, lub pomieścić większy obraz (aby przesunąć go w wybrane miejsce) itd. Oto, co zrobisz w drugim wierszu..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; }
źródło
div.container
: układ staje się pomieszany, gdy sześciokąt znajduje się w tym elemencie div kontenera. Dziwną rzeczą jest jednak przyjrzenie się porównaniu między każdym scenariuszem: link i link . Przeprowadziłem kilka testów, ale nie wiem, co psuje sześciokąty!overflow: hidden
zrobiłby to, co pokazujesz), ale tak nie jest. Spójrz na zagnieżdżenie drugiego poziomudiv
i jego:before
kod, ponieważ prawdopodobnie albodiv
nie obraca się w transformacji, albobackground-image
nie dziedziczy zarówno tego, jakdiv
i jego:before
pseudoelementu.display:block
.z-index
. Poprawiam to teraz, aby upewnić się, że wszystko działa poprawnie.W rzeczywistości można to zrobić za pomocą tylko jednego elementu na sześciokąt i pseudoelementów obrazu tła i tekstu.
próbny
Podstawowa struktura 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>
Możesz mieć więcej rzędów, wystarczy mieć
n
sześciokąty na nieparzystych rzędach in+/-1
sześciokąty na parzystych rzędach.Odpowiedni 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); }
źródło
.content:after
z.hexagon > *
. Pomysłowy.Przedstawię proste demo, jak stworzyć sześciokątny kształt.
.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>
źródło
Oto inne podejście wykorzystujące COMPASS / SCSS, które pozwala łatwo ustawić rozmiar i układ sześciokątów:
http://codepen.io/interdruper/pen/GrBEk
źródło
Możesz stworzyć w pełni responsywną sześciokątną siatkę, używając tylko CSS. Pomysł polega na utworzeniu kształtu rodzica jako maski za pomocą przepełnienia CSS2.1: ukrytego, który jest kompatybilny z prawie wszystkimi przeglądarkami, nawet z Internet Explorer 6.
Jest to zaskakująco prosta technika, której można użyć do stworzenia responsywnej siatki o różnych kształtach, a rozwiązanie problemu wymaga jedynie nieszablonowego myślenia.
Mam tutaj obszerny przewodnik krok po kroku, jak wykonać tę technikę: https://www.codesmite.com/article/how-to-create-pure-css-hexagonal-grids
To najlepszy sposób, jaki do tej pory znalazłem, nie wymaga javascript i jest zarówno płynny, jak i responsywny.
Technikę wykorzystałem również w darmowym szablonie HTML, który zawiera obrazy wewnątrz sześciokątów, które możesz zaprezentować i pobrać tutaj: https://www.codesmite.com/freebie/hexa-free-responsive-portfolio-template
źródło
jeśli jesteś w stanie zaimplementować sztuczkę z kształtami div, po prostu daj każdemu elementowi div a
position:relative
(musisz najpierw ustawić je wszystkie jeden po drugim, ustawiająctop
ileft
)źródło
AFAIK, nie da się tego zrobić w czystym CSS. Najlepszym rozwiązaniem byłoby użycie przycinania maski dla tła, jak wyjaśniono tutaj: http://www.cssbakery.com/2009/06/background-image.html (zadziała to tylko wtedy, gdy tło strony jest jednolite lub można je dopasować i dopasuj maskę do tła strony.
Następnie możesz użyć csstextwrap, aby dopasować się do tekstu: http://www.csstextwrap.com/examples.php
Na SO było kilka podobnych pytań. Np. Jest jakiś sposób, aby tekst w div wypełniał kształt trójkąta?
źródło