Квадрат с закругленными углами и изогнутой изогнутой рамкой

Мне было интересно, можно ли сделать квадрат с круглыми углами и отступом в чистом CSS.

В настоящее время у меня есть это:

#custom-square {
     position: relative;
     display: block;
     width: 75px;
     height: 75px;
     border: 2px solid #8A6EF1;
     border-radius: 10px;
     background-color: white;
}

Квадрат с закругленными углами и отступом

Ответы

Ответ 1

С учетом сложности и количества кода, необходимого для выравнивания двойных кривых с CSS, SVG выглядит более подходящим. Несколько других причин для перехода на svg:

  • контроль пути (цвет, ширина, кривая...)
  • управлять заливом простым цветом, градиентом или изображением
  • меньше кода
  • вы можете отображать его на неровном фоне (градиент или изображение)
  • сохранить границы формы для пользовательских взаимодействий (наведите указатель мыши, щелкните...)

Вот базовый пример использования inline svg с элемент пути.
Кривые рисуются с помощью кривых кубического Безье:

svg{width:30%;}
<svg viewbox="0 0 10 10">
  <path d="M1.5 0.5 Q5 1 8.5 0.5 Q9.5 0.5 9.5 1.5 Q9 5 9.5 8.5 Q9.5 9.5 8.5 9.5 Q5 9 1.5 9.5 Q0.5 9.5 0.5 8.5 Q1 5 0.5 1.5 Q0.5 0.5 1.5 0.5z" 
        fill="none" stroke-width="0.2" stroke="#8A6FF2" />
</svg>

Ответ 2

Еще один чистый CSS-подход для создания этой границы - использовать свойство border-image. Все, что требуется, - это создать изображение с необходимой формой границы и установить его в элемент с использованием свойства border-image-source.

.shape.large {
  height: 300px;
  width: 300px;
  border-image-source: url(http://i.stack.imgur.com/Qkh6A.png);
  border-image-width: 34px; /* the width of the border portions in the image - refer to image at the end of the answer for the exact portion details*/
  border-image-slice: 34; /* equal to border-image-width */
  border-width: 34px; /* equal to border-image-width */
}
.shape.small {
  height: 100px;
  width: 100px;
  border-image-source: url(http://i.stack.imgur.com/Mra4B.png);
  border-image-width: 14px;
  border-image-slice: 14;
  border-width: 14px;
}
.shape.small.fill {
  background: aliceblue content-box;
  border-image-source: url(http://i.stack.imgur.com/Ovj03.png);
  border-width: 14px;
}

/* Just for demo */

body {
  background: url(http://lorempixel.com/800/800/abstract/2);
}
.shape.small {
  float: left;
}
.shape.large {
  clear: both;
}
<div class='shape small'>Some content</div>
<div class='shape small fill'>Some content</div>
<div class='shape large'>Some content</div>

Ответ 3

Этот проект макета настолько близок, что я могу получить его до чистого CSS, но все равно требует вложенного div. Вам нужно будет настроить размер/радиус для кругов до/после.

Pen

div {

  position: absolute;
  top: 100px;
  left: 100px;
  width: 100px;
  height: 100px; 
  border: 4px solid purple;
  border-radius: 30px;
  //overflow: hidden;
  box-sizing: border-box;

  &:before {
    position: absolute;
    top: -4px;
    left: -94px;
    content: ' ';
    width: 100px;
    height: 100px;
    border: 4px solid purple;
    border-radius: 50px;
    box-sizing: border-box;
    background-color: white;
    clip: rect(0px, 100px, 100px, 90px);
  }

  &:after {
    position: absolute;
    top: -4px;
    right: -94px;
    content: ' ';
    width: 100px;
    height: 100px;
    border: 4px solid purple;
    border-radius: 50px;
    box-sizing: border-box;
    background-color: white;
    clip: rect(0px, 10px, 100px, 0px);
  }
}

div > div {
  position: absolute;
  top: -4px;
  left: -4px;
  transform: rotate(90deg);
  border-color: transparent;
}

Ответ 4

SVG, вероятно, путь сюда, но здесь довольно близкое приближение в чистом CSS. Это можно сделать еще лучше, увеличив размер внешних кругов.

#middle {
  width: 96px;
  height: 96px;
  border-radius: 10px;
  background-color: green;
  border: 2px solid #8A6EF1;
}
.outside {
  width: 100px;
  height: 100px;
  position: relative;
  overflow: hidden;
  margin: 0;
  padding: 0;
}
.cutout {
  width: 96px;
  height: 96px;
  border-radius: 50%;
  background-color: white;
  border: 2px solid #8A6EF1;
}
#top {
  top: -100px;
  height: 10px;
}
#right {
  top: -110px;
  left: 90px;
  width: 10px;
}
#bottom {
  top: -120px;
  height: 10px;
}
#left {
  top: -220px;
  width: 10px;
}
#top > .cutout {
  margin-top: -90px;
}
#left > .cutout {
  margin-left: -90px;
}
<div id="wrapper">
  <div id="middle">
  </div>
  <div id="top" class="outside">
    <div class="cutout">
    </div>
  </div>
  <div id="right" class="outside">
    <div class="cutout">
    </div>
  </div>
  <div id="bottom" class="outside">
    <div class="cutout">
    </div>
  </div>
  <div id="left" class="outside">
    <div class="cutout">
    </div>
  </div>
</div>