Подтвердить что ты не робот

Сделайте правильный внешний изогнутый слой для абзаца с CSS

Я пытаюсь составить список абзацев, и один из них должен быть выбран, как и изображение ниже, но кажется, что я просто не могу добиться успеха.

введите описание изображения здесь

Я пробовал что-то в: http://jsfiddle.net/bmj2j2wd/, но конец просто не кривит так, как мне хотелось бы... т.е. наружу, а не внутрь.

Это css оттуда:

.active{
    border:2px solid dodgerblue;
    border-bottom:0;
    width:80px;
    height:32px;
    margin:10px;
    position:relative;
    border-radius:16px 16px 0 0;
}
.active:after,
.active:before{
    content:'';
    width:80px;
    height:32px;
    border:2px solid dodgerblue;
    position:absolute;
    bottom:-8px;
    border-top:0;
}
.active:after{
    border-left:0;
    border-radius:0 0 16px 0;
    down:-16px;
}
.active:before{
    border-right:0;
    border-radius:0 0 0 16px;
    up:-16px;
}

но это выглядит совершенно не так.

Очень важно было бы, чтобы две прямые линии после кривизны проходили весь путь вверх и вниз до верхней и нижней части страницы.

Итак, я хотел бы попросить о помощи у сообщества, чтобы эта работа работала.

4b9b3361

Ответ 1

В основном вы можете использовать :before и :after, чтобы создать окно сверху и поле внизу активного элемента <p> (p.active). С помощью этих двух полей вы можете изменить направление границы. Ниже приведен пример с динамической длиной, основанной на элементах (Код на JSFiddle):

См. следующее решение (исходный ответ перед редактированием):

.container :not(.active) {
  border-right:1px solid dodgerblue;
  margin:0;
  padding:10px 10px 10px 20px;
  width:72px;
}
.active {
  border:1px solid dodgerblue;
  border-radius:5px 0 0 5px;
  border-right:0;
  height:32px;
  line-height:32px;
  margin:10px;
  padding-left:10px;
  position:relative;
  width:80px;
}
.active:after, .active:before {
  border-right:1px solid dodgerblue;
  content:'';
  height:32px;
  right:-2px;
  position:absolute;
  width:80px;
}
.active:after {
  border-bottom-right-radius: 5px;
  transform:translateY(-100%);
}
.active:before {
  border-top-right-radius:5px;
  transform:translateY(100%);
}
<div class="container">
  <p>item1</p>
  <p>item2</p>
  <p>item3</p>
  <p class="active">item4</p>
  <p>item5</p>
  <p>item6</p>
</div>

Ответ 2

Вы можете использовать псевдонимы :after и :before и добавить border-radius.

.active {
  padding: 15px;
  margin: 60px;
  border: 1px solid blue;
  border-top-left-radius: 10px;
  border-bottom-left-radius: 10px;
  padding-right: 0;
  display: inline-block;
  border-right: none;
  position: relative;
}
.active:before,
.active:after {
  content: '';
  position: absolute;
  width: 30px;
  height: 40px;
}
.active:before {
  border-right: 1px solid blue;
  border-bottom: 1px solid blue;
  border-bottom-right-radius: 50%;
  right: -30px;
  top: 0;
  transform: translateY(-100%);
}
.active:after {
  border-right: 1px solid blue;
  border-top: 1px solid blue;
  border-top-right-radius: 50%;
  right: -30px;
  bottom: 0;
  transform: translateY(100%);
}
<div class="active">Some selection</div>

Ответ 3

Другая опция, которая использует span элементы для кривых линий вместо pseudoelements

fiddle

body {
  margin: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.active {
  border: 1px solid red;
  border-right: 0;
  width: 80px;
  height: 32px;
  position: relative;
  border-radius: 5px 0 0 5px;
  display: flex;
  align-items: center;
  padding-left: 1em;
}

.curvy {
  flex: 1;
  width: 80px;
  margin-left: 30px;
  border: 1px solid red;
  border-left: 0;
  border-top: 0;
  border-radius: 0 0 5px 0;
  margin-bottom: -1px;
}

.active+.curvy {
  margin-bottom: 0;
  margin-top: -1px;
  border-top: 1px solid red;
  border-radius: 0 5px 0 0;
  border-bottom: 0;
}
<span class="curvy"></span>
<div class="active">hi</div>
<span class="curvy"></span>

Ответ 4

В то время как другие два работают, но это было не все вверх и вниз. Чтобы линия была длиннее/короче, измените высоту и верхнее значение.

height: 50vh;

top: calc(-50vh - 1px);

.active{
    border:1px solid red;
    border-right:0;
    width:80px;
    height:32px;
    margin: 150px auto 0;
    position:relative;
    border-radius: 10px 0px 0 10px;
    padding: 10px;
}
.active:after,
.active:before {
  content: '';
  position: absolute;
  width: 20px;
  height: 50vh;
}
.active:before {
  top: calc(-50vh - 1px);
  right: -20px;
  border-bottom-right-radius: 10px;
  border: 1px solid red;
  border-left: none;
  border-top: none;
}
.active:after{
  bottom: calc(-50vh - 1px);
  right: -20px;
  border-top-right-radius: 10px;
  border: 1px solid red;
  border-left: none;
  border-bottom: none;
}
<div class="active">hi</div>