it-swarm.com.ru

Создать повторяющийся шестиугольный узор с помощью CSS3

Итак, мне нужно сделать повторяющийся шестиугольный узор, используя CSS. Если нужны изображения, я могу пойти туда, но я бы предпочел просто использовать CSS, если это возможно.

Вот идея того, что я пытаюсь создать:

enter image description here

По сути, мне просто нужен способ создать шестиугольные фигуры, а затем наложить текст/изображения поверх них. У меня пока нет большого кода, потому что я не совсем уверен, с чего начать. Проблема в том, что я мог бы просто использовать <div>s в форме шестиугольника, как показано в ( http://css-tricks.com/examples/ShapesOfCSS/ ), но тогда они не будут подключаться. Я мог бы использовать повторяющийся шестиугольник, но тогда я не смог бы указать точное местоположение текста или изображений, которые мне нужны, в определенных формах. Спасибо за любую помощь заранее.

78
element119

(Хотя ответ Аны пришел через несколько месяцев после моего, вероятно, с использованием моего в качестве основы для «размышлений», тот факт, что она смогла придумать метод, использующий одну переменную div, стоит продвигать, поэтому посмотрите ее отвечу тоже - но учтите, что содержание в гексе более ограничено.)

Это был действительно удивительный вопрос. Спасибо, что спросили. Самое замечательное в том, что:

Это Fiddle доказывает, что вы можете сделать это!

Использовано оригинальное Fiddle (изменено при последующем редактировании ссылки на скрипку выше) - в нем использовались изображения imgur.com, которые не выглядели очень надежными при загрузке, поэтому новая скрипка использует photobucket.com (дайте мне знать, если есть постоянные проблемы с загрузкой изображений). Я сохранил исходную ссылку, потому что приведенный ниже код объяснения соответствует этому (есть несколько отличий в background-size или position от новой скрипки).

Идея пришла ко мне почти сразу после прочтения вашего вопроса, но потребовалось некоторое время для ее реализации. Первоначально я пытался получить один "hex" с одним div и только псевдоэлементами, но, как я мог сказать, не было никакого способа просто повернуть 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 обрабатывает горизонтальный (конечно), но line-height, который соответствует 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;
}
130
ScottS

На самом деле это может быть сделано только с одним элементом на шестиугольник и псевдоэлементами для фонового изображения и текста.

демо

Базовая структура 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); 
}
52
Ana

Я предоставлю простую демонстрацию того, как создать шестиугольную форму.

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

Вот еще один подход, использующий COMPASS/SCSS, который позволяет легко установить размер и расположение шестиугольников:

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

1
Interdruper

если вы можете реализовать трюк с формами div, просто дайте каждому div position:relative (сначала вам нужно было бы сначала расположить их все по одному, также задав top и left)

0
RozzA

Вы можете создать полностью адаптивную гексагональную сетку, используя только 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

0
Ash