Косая или скрученная форма границы

394
27 марта 2017, 06:54

Мне интересно, можно ли создать завернутую или, лучше сказать, скрученную границу с помощью CSS.

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

Перевод вопроса: Oblique or twisted border shape

Answer 1

Больше мне в голову ни чего не пришло но:

   p{ 
margin:30px; 
transform:translate(100px,50px); 
   } 
 
p.arrow { 
  display: inline-block; 
  width: 250px; 
  height: 60px; 
  text-align: center; 
  line-height: 60px; 
  position: relative; 
  font-size: 20px; 
  z-index: 1; 
} 
 
p.arrow:before { 
  content: ""; 
  display: block; 
  width: 100%; 
  height: 50%; 
  background: red; 
  position: absolute; 
  top: 0; 
  left: 0; 
} 
 
p.arrow:after { 
  content: ""; 
  display: block; 
  width: 100%; 
  height: 50%; 
  background: red; 
  position: absolute; 
  bottom: 0; 
  left: 0; 
} 
 
p.arrow:after, 
p:before { 
  z-index: -100; 
} 
 
p.arrow:after { 
  transform: skew(-20deg); 
} 
 
p.arrow:before { 
  transform: skew(20deg); 
} 
 
p.trap { 
  width: 300px; 
  height: 60px; 
  text-align: center; 
  line-height: 60px; 
  position: relative; 
  perspective: 200px; 
  font-size: 20px; 
  color: #eee; 
} 
 
p.trap:after, 
p.trap:before { 
  z-index: -100; 
} 
 
p.trap:after { 
  content: ""; 
  display: block; 
  width: 100%; 
  height: 30px; 
  position: absolute; 
  top: 8px; 
  left: 0; 
  background: blue; 
} 
 
p.trap:before { 
  content: ""; 
  display: block; 
  width: 100%; 
  height: 30px; 
  position: absolute; 
  bottom: 8px; 
  left: 0; 
  background: blue; 
} 
 
p.trap:after { 
  transform: rotateX(-50deg); 
} 
 
p.trap:before { 
  transform: rotateX(50deg); 
} 
 
   p.center-arrow{ 
display:block; 
width:300px; 
height:60px; 
line-height:60px; 
text-align:center; 
position:relative; 
perspective:100px; 
color:#222; 
font-size:20px; 
font-weight:900; 
} 
p.center-arrow span.center-arrow-line{ 
display:block; 
width:350px; 
height:20px; 
background:red; 
border:none; 
outline:none; 
border-radius:45%; 
border-style:solid; 
border-width:4px; 
border-color:blue; 
position:absolute; 
top:50%; left:50%; 
transform:translate(-50%,-50%); 
z-index:-1200; 
} 
p.center-arrow:after, 
p.center-arrow:before{ 
content:""; 
display:block; 
width:100%; 
height:30px; 
position:absolute; 
left:0; 
z-index:-100; 
} 
p.center-arrow:after{ 
top:-10px; 
background:red; 
transform:rotateX(-40deg); 
border-style:solid; 
border-width:4px; 
border-color:blue blue red blue; 
} 
p.center-arrow:before{ 
bottom:-10px; 
background:red; 
transform:rotateX(40deg); 
border-style:solid; 
border-width:4px; 
border-color:red blue blue blue; 
}
<p class="arrow">Такой элемент</p> 
 
<p class="trap">Трапеция</p> 
 
<p class="center-arrow"> 
  с полосой в центре 
  <span class="center-arrow-line"></span> 
</p>
Пример смотреть желательно в полноэкранном режиме

Демо с background на codepen: http://codepen.io/Geyan/pen/EWpwVr?editors=1100

Answer 2

CSS решение:

В качестве альтернативного решения вы всегда можете использовать - :after и :before псевдоэлементы.
Ширина и высота псевдоэлементов :after и :before - вычислялись с использованием некоторой базовой тригонометрии.

Прим. переводчика:
У автора на рисунке ошибка - во второй и третьей формуле сверху.
Должно быть: opposite side = Sin(45) x Hypotenuse;
Но результат у автора, тем не менее получился верный - 21.21px.

Противоположная сторона - ширина и высота псевдоэлементов :after и :before.
На левой стороне даны верхняя и правая границы, а справа - верхняя и левая границы.
Затем, левый край ленточки был повернут на 45deg, а тот, что справа, был повернут на -45deg.

div { 
  position: relative; 
  text-transform: uppercase; 
  width: 200px; 
  height: 30px; 
  text-align: center; 
  line-height: 27px; 
  border-top: 3px solid black; 
  border-bottom: 3px solid black; 
  box-sizing: border-box; 
} 
div:after, 
div:before { 
  position: absolute; 
  content: ''; 
  width: 21.21px; 
  height: 21.21px; 
  border-top: 3px solid black; 
  border-right: 3px solid black; 
  transform: rotate(45deg); 
  box-sizing: border-box; 
  top: 1px; 
  left: -9px; 
} 
div:after { 
  border-right: 0; 
  border-left: 3px solid black; 
  left: 100%; 
  margin-left: -10px; 
  transform: rotate(-45deg); 
}
<div>lorem ipsum</div>

Перевод ответа: Oblique or twisted border shape

Answer 3

SVG решение:

Самым простым и аккуратным решением было бы использование svg для создания границы.

#container { 
  position: relative; 
  width: 200px; 
  height: 30px; 
} 
#content { 
  text-transform: uppercase; 
  position: absolute; 
  width: 200px; 
  height: 30px; 
  top: 0; 
  text-align: center; 
  line-height: 30px; 
}  
<div id="container"> 
  <svg width="200" height="30" viewBox="-1 -2 201 33"> 
    <path d="M0,0 h200 l-15,15 l15,15 h-200 l15,-15z" stroke="black" stroke-width="2" fill="none" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div>

Вы могли бы даже использовать path с квадратичными кривыми Безье для усложнения формы границы фигуры.

#container { 
  position: relative; 
  width: 200px; 
  height: 30px; 
  margin-bottom: 30px; 
} 
#content { 
  text-transform: uppercase; 
  position: absolute; 
  width: 200px; 
  height: 30px; 
  top: 0; 
  text-align: center; 
  line-height: 30px; 
}
<div id="container"> 
  <svg width="200" height="30" viewBox="-1 -1 201 33"> 
    <path d="M0,0 h200 q-20,15 0,30 h-200 q20,-15 0,-30" stroke="black" stroke-linejoin="round" stroke-width="2" fill="none" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div> 
 
<div id="container"> 
  <svg width="200" height="30" viewBox="-1 -1 201 33"> 
    <path d="M0,0 h200 q0,10 -15,15 q10,0 15,15 h-200 q0,-10 15,-15 q-10,0 -15,-15" stroke="black" stroke-linejoin="round" stroke-width="2" fill="none" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div> 
 
<div id="container"> 
  <svg width="200" height="30" viewBox="-1 -1 201 33"> 
    <path d="M0,0 h200 q-10,0 -15,12.5 l15,2.5 l-15,2.5 q0,10 15,13 h-200 q10,0 15,-12.5 l-15,-2.5 l15,-2.5 q0,-10 -15,-12.5" stroke="black" stroke-linejoin="round" stroke-width="2" fill="none" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div>

Вы можете легко добавить эффект тени.

#container { 
  position: relative; 
  width: 200px; 
  height: 30px; 
  margin-bottom: 30px; 
} 
#content { 
  text-transform: uppercase; 
  position: absolute; 
  width: 200px; 
  height: 30px; 
  top: 0; 
  text-align: center; 
  line-height: 30px; 
}
<div id="container"> 
  <svg width="205" height="35" viewBox="-1 -1 205 38"> 
    <filter id="f"> 
      <feGaussianBlur stdDeviation="1.5" /> 
    </filter> 
    <path filter="url(#f)" d="M0,0 h200 l-15,15 l15,15 h-200 l15,-15z" stroke="black" stroke-linejoin="round" stroke-width="2" transform="translate(0,3)" fill="black" /> 
    <path id="shape" d="M0,0 h200 l-15,15 l15,15 h-200 l15,-15z" stroke="black" stroke-linejoin="round" stroke-width="2" fill="white" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div> 
 
<div id="container"> 
  <svg width="205" height="35" viewBox="-1 -1 205 38"> 
    <path filter="url(#f)" d="M0,0 h200 q0,10 -15,15 q10,0 15,15 h-200 q0,-10 15,-15 q-10,0 -15,-15" stroke="black" stroke-linejoin="round" stroke-width="2" transform="translate(0,3)" fill="black" /> 
    <path d="M0,0 h200 q0,10 -15,15 q10,0 15,15 h-200 q0,-10 15,-15 q-10,0 -15,-15" stroke="black" stroke-linejoin="round" stroke-width="2" fill="white" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div> 
 
<div id="container"> 
  <svg width="205" height="35" viewBox="-1 -1 205 38"> 
    <path filter="url(#f)" d="M0,0 h200 q-10,0 -15,12.5 l15,2.5 l-15,2.5 q0,10 15,13 h-200 q10,0 15,-12.5 l-15,-2.5 l15,-2.5 q0,-10 -15,-12.5" stroke="black" stroke-linejoin="round" stroke-width="2" transform="translate(0,3)" fill="black" /> 
    <path d="M0,0 h200 q-10,0 -15,12.5 l15,2.5 l-15,2.5 q0,10 15,13 h-200 q10,0 15,-12.5 l-15,-2.5 l15,-2.5 q0,-10 -15,-12.5" stroke="black" stroke-linejoin="round" stroke-width="2" fill="white" /> 
  </svg> 
  <div id="content">lorem ipsum</div> 
</div>

Перевод ответа: Oblique or twisted border shape

Answer 4

Пример с использованием clip-path + FF

*{ 
  box-sizing: border-box; 
} 
.b-ribbon {     
  position: relative; 
  max-width: 400px; 
  padding: 25px 10%; 
  background-color: tomato;   
  text-align: center; 
  color: tomato; 
  font-size: 15px; 
  font-family: segoe ui, sans-serif; 
  -webkit-clip-path: polygon(0 0%, 100% 0, 90% 50%, 100% 100%, 70% 100%, 30% 100%, 0 100%, 10% 50%); 
          clip-path: polygon(0 0%, 100% 0, 90% 50%, 100% 100%, 70% 100%, 30% 100%, 0 100%, 10% 50%);    
     -webkit-clip-path: url("#clip-ribbon"); 
  clip-path: url("#clip-ribbon");    
  transition: .3s; 
} 
.b-ribbon:before{ 
  content: ''; 
  position: absolute; top: 3px; left: 8px; bottom: 3px; right: 8px; 
  background-color: #fff;   
  -webkit-clip-path: polygon(0 0%, 100% 0, 90.3% 50%, 100% 100%, 70% 100%, 30% 100%, 0 100%, 9.7% 50%); 
          clip-path: polygon(0 0%, 100% 0, 90.3% 50%, 100% 100%, 70% 100%, 30% 100%, 0 100%, 9.7% 50%);  
     -webkit-clip-path: url("#clip-ribbon-inner"); 
  clip-path: url("#clip-ribbon-inner");       
} 
.b-ribbon > span{ 
  position: relative; 
} 
 
.b-ribbon:hover{ 
  color: royalblue; 
  background-color: royalblue; 
}
<div class="b-ribbon"> 
  <span>Text ribbon</span> 
</div> 
<svg width='0' height='0'> 
  <defs> 
    <clipPath id="clip-ribbon" clipPathUnits="objectBoundingBox">     
      <polygon points="0 0, 1 0, 0.9 0.5, 1 1, 0.7 1, 0.3 1, 0 1, 0.1 0.5" /> 
    </clipPath> 
  </defs>   
</svg> 
<svg width='0' height='0'> 
  <defs> 
    <clipPath id="clip-ribbon-inner" clipPathUnits="objectBoundingBox">     
      <polygon points="0 0, 1 0, 0.903 0.5, 1 1, 0.7 1, 0.3 1, 0 1, 0.097 0.5" /> 
    </clipPath> 
  </defs>   
</svg>

Answer 5

О-о-о-о-о-о... Я смотрю тут никто не знает о clip-path.
Всё легче, чем кажется. Но прошу ознакомиться с caniuse.
Ну или если лень, то вот фотка:

Также можешь наметить любые фигуры с помощью этой тулсы.

div { 
  display: -webkit-box; 
  display: -ms-flexbox; 
  display: flex; 
  -webkit-box-pack: center; 
      -ms-flex-pack: center; 
          justify-content: center; 
  -webkit-box-align: center; 
      -ms-flex-align: center; 
          align-items: center; 
  width: 500px; 
  height: 200px; 
  background-color: orangered; 
  -webkit-clip-path: polygon(0 0%, 100% 0, 85% 50%, 100% 100%, 70% 100%, 30% 100%, 0 100%, 15% 50%); 
          clip-path: polygon(0 0%, 100% 0, 85% 50%, 100% 100%, 70% 100%, 30% 100%, 0 100%, 15% 50%); 
  color: white; 
  font-size: 20pt; 
  font-family: Arial, sans-serif; 
}
<div> 
  <p>Какая чудесная погода...</p> 
</div>

READ ALSO
Bootstrap как разместить объкты друг за другом

Bootstrap как разместить объкты друг за другом

Нужно сделать вот так ПРИ ПОМОЩИ BOOTSTRAP

328
Не удалось загрузить тип &ldquo;System.Collections.Generic.IReadOnlyDictionary`2&rdquo;

Не удалось загрузить тип “System.Collections.Generic.IReadOnlyDictionary`2”

При открытии программы на любом другом компьютере появляется ошибка:

360
Where отобрать по списку значений

Where отобрать по списку значений

Есть две модели Категории:

307
Использование собственного Id в Nhibernate

Использование собственного Id в Nhibernate

Имеется маппинг, в котором генерация Id производится автоматически:

267