Сделать шестиугольник с рамкой, закругленными углами и прозрачным фоном

Я хочу сделать шестиугольную форму с рамкой, закругленными углами и прозрачным фоном в CSS3, как на этом изображении:

закругленный шестиугольник с рамкой

Я не могу сделать это с закругленными углами и границей.

Мой код здесь:

#hexagon-circle {
  position: relative;
  margin: 1em auto;
  width: 10em;
  height: 17.32em;
  border-radius: 1em/.5em;
  background: red;
  transition: opacity .5s;
  cursor: pointer;
}
#hexagon-circle:before {
  position: absolute;
  width: inherit;
  height: inherit;
  border-radius: inherit;
  background: inherit;
  content: '';
  -webkit-transform: rotate(60deg);  /* Chrome, Opera 15+, Safari 3.1+ */
  -ms-transform: rotate(60deg);  /* IE 9 */
  transform: rotate(60deg); /* Firefox 16+, IE 10+, Opera */
}

#hexagon-circle:after {
  position: absolute;
  width: inherit;
  height: inherit;
  border-radius: inherit;
  background: inherit;
  content: '';
  -webkit-transform: rotate(-60deg);  /* Chrome, Opera 15+, Safari 3.1+ */
  -ms-transform: rotate(-60deg);  /* IE 9 */
  transform: rotate(-60deg); /* Firefox 16+, IE 10+, Opera */
}
<div id="hexagon-circle"></div>

2 ответа

Решение

Шестиугольник с закругленными углами - это сложные формы для создания, и я обычно рекомендую использовать SVG для их создания. Необходимость в прозрачном фоне делает его еще более подходящим для SVG. С SVG вы можете лучше контролировать форму, ее кривые и т.д., и вам не нужно добавлять много дополнительных (ненужных) элементов в вашу разметку.

Все, что нужно для создания этой фигуры с помощью SVG - это использовать один path элемент вместе с несколькими L (линия) и A (дуги) команды. L (линия) команда в основном рисует линию от точки 1 до точки 2, тогда как A (дуга) команда рисует дугу указанного радиуса (первые два значения сразу после A команда).

Вы можете прочитать больше о SVG path элемент и его команды в этом учебнике MDN.

svg {
  height: 200px;
  width: 240px;
}
path {
  stroke: #777;
  fill: none;
}

body {
  background: black;
}
<svg viewBox='0 0 120 100'>
  <path d='M38,2 
           L82,2 
           A12,12 0 0,1 94,10 
           L112,44 
           A12,12 0 0,1 112,56
           L94,90       
           A12,12 0 0,1 82,98
           L38,98
           A12,12 0 0,1 26,90
           L8,56
           A12,12 0 0,1 8,44
           L26,10
           A12,12 0 0,1 38,2' />
</svg>

Если вы все еще хотите использовать CSS, вы можете использовать подход, использованный jbutler483 в этой своей скрипке. (Я добавил код из этой скрипки также в этот ответ, чтобы избежать проблем гниения ссылок)

.roundHex {
  position: relative;
  margin: 0 auto;
  background: transparent;
  border-radius: 10px;
  height: 300px;
  width: 180px;
  box-sizing: border-box;
  transition: all 1s;
  border: 10px solid transparent;
  border-top-color: black;
  border-bottom-color: black;
}
.roundHex:before,
.roundHex:after {
  content: "";
  border: inherit;
  position: absolute;
  top: -10px;
  left: -10px;
  background: inherit;
  border-radius: inherit;
  height: 100%;
  width: 100%;
}
.roundHex:before {
  transform: rotate(60deg);
}
.roundHex:after {
  transform: rotate(-60deg);
}
<div class="roundHex"></div>

Я сделал codepen, где вы можете настроить длину стороны и радиус границы: https://codepen.io/shreyansqt/pen/qBjprWE

HTML:

      <svg width="500" height="500">
  <path id="hexagon" fill="red" />
</svg>

JS:

      const getHexagonPathData = () => {
  // #################### x1,y0 ####################
  // ############## xc1,yc0 # xc2,yc0 ##############
  // ###############################################
  // ###############################################
  // #### xc0,yc1 ##################### xc3,yc1 ####
  // ## x0,y1 ############################# x2,y1 ##
  // ## x0,yc2 ########################### x2,yc2 ##
  // ###############################################
  // ###############################################
  // ## x0,yc3 ########################### x2,yc3 ##
  // ## x0,y2 ############################# x2,y2 ##
  // #### xc0,yc4 ##################### xc3,yc4 ####
  // ###############################################
  // ###############################################
  // ############## xc1,yc5 # xc2,yc5 ##############
  // #################### x1,y3 ####################

  const sin = (deg) => Math.sin((deg * Math.PI) / 180);
  const cos = (deg) => Math.cos((deg * Math.PI) / 180);

  const borderRadius = 6;
  const sideLength = 80;
  const x0 = 0;
  const y0 = 0;

  const x1 = sideLength * cos(30);
  const y1 = sideLength * sin(30);

  const xc1 = x1 - borderRadius * cos(30);
  const yc0 = borderRadius * sin(30);
  const xc2 = x1 + borderRadius * cos(30);

  const x2 = 2 * x1;
  const y2 = y1 + sideLength;

  const xc3 = x2 - borderRadius * cos(30);
  const yc1 = y1 - borderRadius * sin(30);
  const yc2 = y1 + borderRadius;

  const y3 = y2 + y1;

  const yc3 = y2 - borderRadius;
  const yc4 = y2 + borderRadius * sin(30);

  const yc5 = y3 - borderRadius * sin(30);
  const xc0 = borderRadius * cos(30);

  return `
        M ${xc1},${yc0}
        Q ${x1},${y0} ${xc2},${yc0}

        L ${xc3},${yc1}
        Q ${x2},${y1} ${x2},${yc2}

        L ${x2},${yc3}
        Q ${x2},${y2} ${xc3},${yc4}

        L ${xc2},${yc5}
        Q ${x1},${y3} ${xc1},${yc5}
        
        L ${xc0},${yc4}
        Q ${x0},${y2} ${x0},${yc3}
        
        L ${x0},${yc2}
        Q ${x0},${y1} ${xc0},${yc1}
        Z
      `;
};

const hexagon = document.getElementById("hexagon");

hexagon.setAttribute("d", getHexagonPathData());


Другие вопросы по тегам