본문 바로가기
WEB/HTML & CSS

[CSS] 육각형 만들기 (⭐️반응형)

by 12th_moon 2020. 11. 14.

 

한 페이지에 <div>든, <li>든 무언가 여러 개를 나열해야 할 때 보통은 왼쪽처럼 가지런하게 나열하는 걸 선호하지만,

가끔은 꾸안꾸 하게 나열하는 일도 필요한 법.

 

마찬가지로 가지런하면서 색다른 게 없을까 하다가 오른쪽처럼 육각형으로 나열하는 방법을 찾았다.

 

<div class="wrap">
  <div class="hex">
    <div class="hex-inner">
      <div class="content">
      	<p>HEX 1</p>
      </div><!--content-->
    </div><!--hex-inner-->
  </div><!--hex-->
</div><!--wrap-->

 

우선 wrapper로 사용할 큰 틀을 하나 만든 후 그 안에 필요한 개수만큼 육각형을 만들어준다.

 

<div class="hex"></div>로 만들어주고 그 안에 inner하나,

그리고 콘텐츠가 실제로 자리할 div를 또 만들어준다.

 

전체 육각형 개수는 상관없지만 난 홀수 줄에는 4개, 짝수 줄에는 3개씩 육각형이 들어가게끔 만들거라

일단 이런 육각형을 일곱 개 만들어주고 CSS.

 

* {
  margin: 0;
  padding: 0;
}
.wrap {
  width: 80%;
  margin: 100px auto;
  display: flex;
  flex-wrap: wrap;
}
.hex {
  width: 25%;
  margin-bottom: 1.8%;
  position: relative;
  visibility: hidden;
}
.hex:nth-of-type(7n+5) {
  margin-left: 12.5%;
}
.hex::after {
  content: '';
  display: block;
  padding-bottom: 80%;
}
.hex-inner {
  position: absolute;
  width: 99%;
  padding-bottom: 114.6%;
  overflow: hidden;
  visibility: hidden;
  transform: rotate3d(0,0,1,-60deg) skewY(30deg);
}
.hex-inner * {
  position: absolute;
  visibility: visible;
}
.content {
  display: flex;
  width: 100%;
  height: 100%;
  overflow: hidden;
  transform: skewY(-30deg) rotate3d(0,0,1,60deg);
  background: #02b4cd80;
  justify-content: center;
  align-items: center;
}
.content p {
  font-size: 3vw;
  text-align: center;
  color: #fff;
}

육각형 각각의 제일 바깥 div에서 영역을 만들어주고,

inner에서 돌리고 비틀어서(rotate, skew) 마름모 모양을 만들어준 다음에

가장 안의 content에서 다시 원래 모습처럼 돌려놓고(rotate, skew 둘 다),

이 영역 밖으로 넘치는 부분은 가려서 육각형으로 보이게 만들어준다.

 

예전에 소스만 복붙 해서 사용했을 땐 되게 간단해 보였는데 막상 이해하면서 값을 미세 조정하려니 새삼 복잡하다.

 

 

창 크기를 조절하면서 확인해보면 잘 반응 중!

 

 

+ 활용 예시

단색도 좋지만 이런 식으로 배경이 가지각색일 때 쓰면 예쁜듯하다 :)

 

 

 

 


 

 

 

 

그리고 덤으로 육각형 달랑 하나 만들 때 더 간단하게 쓸 수 있는 방법도 찾았다.

css는 첫 번째 방식과 비슷한 분량이지만 html이 훨씬 짧고, 육각형을 만드는 원리도 더 간단하다.

 

<div class="wrap">
  <div class="hex">
    <p>HEX 1</p>
  </div>
</div>

 

html에서 wrapper용도의 <div> 안쪽이든 어디든 필요한 곳에 <div class="hex"></div>를 만들어주고 또 css.

 

* {
  margin: 0;
  padding: 0;
}
.wrap {
  width: 80%;
  margin: 100px auto;
}
.hex {
  width: 10vw;
  height: calc(10 * 1.7320vw);
  background: #02b4cd;
  position: relative;
}
.hex::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: inherit;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(60deg);
}
.hex::after {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: inherit;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-60deg);
}
.hex p {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 2rem;
  color: #fff;
  z-index: 1;
}

 

우선 육각형의 바탕이 될 .hex의 가로 세로 길이를 계산한 뒤

::before과 ::after로 같은 크기의 박스를 두 개 만든 다음에

하나는 -60도, 하나는 60도를 돌려서 세 개를 포개 주면 육각형이 되는 건데...

.hex의 세로 값이 난관이었다.

 

이게 고정이면 몇 px이든 가로세로 동일하게 입력해주면 그만인데

반응형으로 만들려면 height에서 % 단위의 값은 적용되지 않기 때문에

vw로 단위를 갈아타고 가로의 길이 값에 맞춰 계산을 해주어야 했다.

 

그래서 학교 다닐 때도 몰랐던 육각형 공식 검색!

 

https://rechneronline.de/pi/hexagon.php

역시나 오늘도 구글링 만세.

여기서 내가 필요한 값은 d₂ = √3 * a

 

css에서 루트 계산은 좀 복잡해 보여서(새로운 세계를 엿본 것 같은 이 기분)

그냥 √3을 소수점 이하 네 자리까지 바꿔 계산하는 걸로.

 

그래서 나온 세로 값이 calc(10 * 1.7320vw);

가로길이에 1.7320을 곱하면 된다.

 

확대해서 보면 귀퉁이 몇 개가 맞아떨어지지 않는 경우도 있지만

확대하지 않고 그냥 봤을 땐 크게 티 나지 않을뿐더러 첫 번째 방법에 비해 원리와 코드가 아주 간단하다는 장점이 있다.

 

다만 육각형 안에 이처럼 텍스트를 포함할 경우에는 ::before과 ::after로 만든 박스가 내용을 가려버리기 때문에

텍스트에도 position: absolute;를 주고 z-index를 통해 최상위로 띄워야 한다.

 

이 방법으로 첫 번째와 같은 모양으로 나열하려면

* {
  margin: 0;
  padding: 0;
}
.wrap {
  width: 80%;
  margin: 100px auto;
  display: flex;
  flex-wrap: wrap;
}
.hex {
  width: 10vw;
  height: calc(10 * 1.7320vw);
  background: #02b4cd;
  position: relative;
  margin: -0.8vw 4vw;
  transform: rotate(30deg);
}
.hex:nth-of-type(7n+5) {
  margin-left: 13vw;
}
.hex::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: inherit;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(60deg);
}
.hex::after {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: inherit;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-60deg);
}
.hex p {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) rotate(-30deg);
  font-size: 2rem;
  color: #fff;
  z-index: 1;
}

wrapper를 display: flex;해주고 

.hex를 30도 회전시킨 다음에 안의 내용(.hex p)을 다시 -30도 돌려주어야 한다.

그리고 .hex의 margin을 적당히 조절해주면 끝.

 

이 방법으로 나열해서 만들어보니 간단하긴 한데

생각해보니 세 개의 직사각형을 하나로 합쳐서 육각형으로 보이게끔 만든 거라

첫 번째의 응용 예시처럼 배경 이미지를 넣는 건 불가능하다.

(아니면 혹시 이것도 방법이 있으려나?)

 

 

 


 

 

 

검색하다가 육각형 레이아웃이 잘 된 사이트를 찾았다.

 

 

Home Page - Lamb's Navy Rum

Address: Pernod Ricard UK Building 12 Chiswick Park 566 Chiswick High Road London W4 5AN Contact: e: ukconsumerfeedback@pernod-ricard.com t: 0800 3765550 close

www.lambsnavyrum.com

육각형 자체의 크기가 변하지는 않지만 미디어쿼리로 레이아웃을 조정한다.

육각형을 만드는 방식은 1번과 2번을 합친 느낌인데 도형 사이사이 간격을 조절하는 부분은 훨씬 간단해 보인다.

 

 

 

See the Pen WNxqpMe by shynaunum (@shynaunum) on CodePen.

 

 

 

 

이 세 번째 방법으로 위처럼 육각형 여러 개를 나열해본다면 이런 느낌~

두 번째와 달리 단색 외에도 이미지를 배경으로 사용할 수 있다는 장점이 있다.

 

 

 

 

 

오늘 뭔가 육각형 공부 많이 한 듯.

어쨌든 고정형에 비해 반응형은 까다롭긴 하지만, 재미는 쏠쏠하다.👍

 

 

 

 

댓글