Как да направя тази стрелка само в CSS?

Създавам подобен на съветник процес на поръчка, където имам това меню: меню

Активната страница е оцветена в зелено (в този случай модел).

Как се прави тази стрелка, като се използва само CSS?:

стрелка

В момента постигам целта си, като използвам няколко div и изображения:

<div class="menuItem">
    <div></div> <!-- The left image -->
    <div>Varianten</div>
    <div></div> <!-- The right image -->
</div>

Лявото изображение: въведете описание на изображението тук

Дясното изображение:въведете описание на изображението тук

Намерих SO отговор, който прави част от това: Кутия със стрелки с CSS, но аз съм има проблем с отстъпа вляво.

Ако имате по-добра идея как да направите това, моля, уведомете ме!


person RobinvdA    schedule 24.12.2014    source източник
comment
проверете това: Форми в css   -  person soroush gholamzadeh    schedule 24.12.2014
comment
Имате ли нужда пространството между всеки бутон да е прозрачно? Или може да е бяло?   -  person Purag    schedule 24.12.2014
comment
същата форма тук: stackoverflow.com/questions/20502191/   -  person web-tiki    schedule 24.12.2014
comment
възможен дубликат на Постигане на подобни на стрелки форми в банер в CSS   -  person jbutler483    schedule 28.01.2015


Отговори (4)


Ако не е необходимо пространството между стрелките да е прозрачно (е плътен цвят), можете да използвате :before и :after, за да създадете ръбовете (без нови елементи в DOM)

По принцип той създава завъртяни квадрати с границите, които желаем, и ги поставя по съответния начин

#flowBoxes {
    margin:auto;
    padding:20px;
    min-width:700px;

}
#flowBoxes div {
    display:inline-block;
    position:relative;
    height:25px;
    line-height:25px;
    padding:0 20px;
    border:1px solid #ccc;
    margin-right:2px;
    background-color:white;
}

#flowBoxes div.right:after{
    content:'';
    border-top:1px solid #ccc;
    border-right:1px solid #ccc;
    width:18px;
    height:18px;
    position:absolute;
    right:0;
    top:-1px;
    background-color:white;
    z-index:150;
    
    -webkit-transform: translate(10px,4px) rotate(45deg);
       -moz-transform: translate(10px,4px) rotate(45deg);
        -ms-transform: translate(10px,4px) rotate(45deg);
         -o-transform: translate(10px,4px) rotate(20deg); 
            transform: translate(10px,4px) rotate(45deg);
}

#flowBoxes div.left:before{
    content:'';
    border-top:1px solid #ccc;
    border-right:1px solid #ccc;
    width:18px;
    height:18px;
    position:absolute;
    left:0;
    top:-1px;
    background-color:white;
    z-index:50;
    
    -webkit-transform: translate(-10px,4px) rotate(45deg);
       -moz-transform: translate(-10px,4px) rotate(45deg);
        -ms-transform: translate(-10px,4px) rotate(45deg);
         -o-transform: translate(-10px,4px) rotate(20deg);
            transform: translate(-10px,4px) rotate(45deg);
}
#flowBoxes .active{
    background-color:green;
    color:white;
}
#flowBoxes div.active:after{
    background-color:green;
}
<div id="flowBoxes">
        <div class="right">Diersoort / I&amp;R</div>
        <div class="left right active">Model</div>
        <div class="left right">Varianten</div>
        <div class="left right">Bedrukkingen</div>
        <div class="left">Bevestiging</div>
</div>

person Gabriele Petrioli    schedule 24.12.2014
comment
Перфектен отговор. В моя случай пространството между стрелките не трябва да е прозрачно, но предполагам, че може да бъде полезно за други. Възможно ли е да направите пространствата прозрачни? - person RobinvdA; 24.12.2014
comment
Придирчиви сте, но защо не използвате :nth-child псевдо класове вместо CSS класове за насочване към първия и последния елемент? + -o- и -moz- префиксите за свойството transform не са наистина вече необходими. - person web-tiki; 24.12.2014
comment
@web-tiki, ако задържите курсора на мишката върху версиите на браузърите, ще видите, че много от тях изискват префикса. Що се отнася до nth-child, вие сте прав, но исках повече гъвкавост относно това, което задавате (и ако всички те са под един и същ контейнер..) - person Gabriele Petrioli; 24.12.2014
comment
Предишните версии изискват префикси! FF 3.5 до 15 изисква -moz-, а Opera 11.5 изисква -o- - person The Pragmatick; 26.02.2015
comment
Идеален, това наистина работи за плоската стриктура отляво, добавих ` #flowBoxes div.left{ margin-left:-5px; border-left:transparent 0px няма; } ` и премахна блока ` #flowBoxes div.right:after ` - person Shyam Achuthan; 19.12.2020
comment
страхотен отговор, работи добре - person kal kokah; 22.01.2021

Ето един алтернативен подход към цялото нещо, използвайки функциите на CSS3. Едно предимство на използването на този метод (и една от основните причини за добавяне на отделен отговор) е, че пространството между стрелките може да бъде прозрачно.

По принцип изпълнението е както следва:

  1. Има едно div за всяка стъпка/елемент и то съдържа текста, който трябва да бъде показан. Да кажем, че height на това div е x (50px в този пример).
  2. Създават се два псевдо-елемента (:before и :after), като техните width са същите като родителя div и height като половината (x/2) от родителя. Елементът :before няма border-bottom, докато елементът :after няма border-top, за да се избегне появата на линия в средата на формата (успоредна на оста x).
  3. Тези два псевдо-елемента след това се skew трансформират в противоположни посоки и се позиционират по такъв начин, че да са точно един под друг и по този начин в крайна сметка образуват необходимата форма.
  4. На псевдоелементите се присвоява отрицателно z-index, за да бъдат зад родителския div (и следователно неговия текст).
  5. Елементите first-child и last-child са леко модифицирани (left позиция, border на псевдо-елементи, background и border на родител div), за да се постигнат прави страни.
  6. Можем да добавим active клас за активни елементи и hover ефекти също към формите като в примера по-долу.

.steps {
  height: 50px;
  width: 150px;
  text-align: center;
  line-height: 50px;
  position: relative;
  margin: 10px 0px 10px 20px;
  display: inline-block;
}
.steps:before,
.steps:after {
  content: '';
  position: absolute;
  left: 0px;
  width: 150px;
  height: 25px;
  z-index: -1;
}
.steps:before {
  top: -2px;
  border-top: 2px solid blue;
  border-right: 2px solid blue;
  border-left: 2px solid blue;
  background: lightblue;
  -moz-transform: skew(30deg);
  -webkit-transform: skew(30deg);
  transform: skew(30deg);
}
.steps:after {
  bottom: -2px;
  border-left: 2px solid blue;
  border-right: 2px solid blue;
  border-bottom: 2px solid blue;
  background: lightblue;
  -moz-transform: skew(-30deg);
  -webkit-transform: skew(-30deg);
  transform: skew(-30deg);
}
.steps:last-child {
  background: lightblue;
  border-right: 2px solid blue;
  border-top: 2px solid blue;
  border-bottom: 2px solid blue;
  margin-left: 38px;
}
.steps:first-child {
  background: lightblue;
  border-left: 2px solid blue;
  border-top: 2px solid blue;
  border-bottom: 2px solid blue;
  margin-right: 18px;
}
.steps:first-child:before,
.steps:first-child:after {
  left: 18px;
}
.steps:last-child:before,
.steps:last-child:after {
  left: -18px;
}
/* Hover Styles */

.steps:first-child:hover,
.steps:last-child:hover,
.steps:hover:before,
.steps:hover:after {
  background: lightgreen;
}
.steps:first-child:hover {
  border-left: 2px solid green;
}
.steps:last-child:hover {
  border-right: 2px solid green;
}
.steps:hover:before {
  border-top: 2px solid green;
  border-right: 2px solid green;
  border-left: 2px solid green;
}
.steps:hover:after {
  border-left: 2px solid green;
  border-right: 2px solid green;
  border-bottom: 2px solid green;
}
.steps:first-child:hover,
.steps:last-child:hover {
  border-top: 2px solid green;
  border-bottom: 2px solid green;
}

/* Active Styles */

.active:first-child,
.active:last-child,
.active:before, 
.active:after{
  background: bisque;
}
.active:first-child{
  border-left: 2px solid red;
}
.active:last-child{
  border-right: 2px solid red;
}
.active:before{
  border-top: 2px solid red;
  border-right: 2px solid red;
  border-left: 2px solid red;
}
.active:after{
  border-left: 2px solid red;
  border-right: 2px solid red;
  border-bottom: 2px solid red;
}
.active:first-child, .active:last-child{
  border-top: 2px solid red;
  border-bottom: 2px solid red;
}

/* Just for creating a non solid color background */
body{
  height: 200px;
  background: -webkit-radial-gradient(center, ellipse, #400, #100);
  background: -moz-radial-gradient(center, ellipse, #400, #100);
  background: radial-gradient(center, ellipse, #400, #100);
}
<div class='steps-container'>
  <div class='steps'>1. Step 1</div>
  <div class='steps active'>2. Step 2</div>
  <div class='steps'>3. Step 3</div>
</div>


Забележка: hover в горния фрагмент не работи, когато задържите курсора на мишката върху десния край на първото дете или левия край на последното дете поради проблеми с z-индекса. Ако имате нужда от безпроблемна hover функционалност, тогава използването на span вътре в елемента .steps, както в фрагмента по-долу, ще реши проблема. (Благодаря на The Pragmatick, че посочи това).

.steps {
  height: 50px;
  width: 150px;
  text-align: center;
  line-height: 50px;
  position: relative;
  margin: 10px 0px 10px 20px;
  display: inline-block;
}
.steps span {
  position: relative;
  z-index: 2;
}
.steps:before,
.steps:after {
  content: '';
  position: absolute;
  left: 0px;
  width: 150px;
  height: 25px;
}
.steps:before {
  top: -2px;
  border-top: 2px solid blue;
  border-right: 2px solid blue;
  border-left: 2px solid blue;
  background: lightblue;
  -moz-transform: skew(30deg);
  -webkit-transform: skew(30deg);
  transform: skew(30deg);
}
.steps:after {
  bottom: -2px;
  border-left: 2px solid blue;
  border-right: 2px solid blue;
  border-bottom: 2px solid blue;
  background: lightblue;
  -moz-transform: skew(-30deg);
  -webkit-transform: skew(-30deg);
  transform: skew(-30deg);
}
.steps:first-child:before,
.steps:first-child:after {
  border-left: none;
}
.steps:last-child:before,
.steps:last-child:after {
  border-right: none;
}
.steps:last-child {
  background: lightblue;
  border-right: 2px solid blue;
  border-top: 2px solid blue;
  border-bottom: 2px solid blue;
  margin-left: 38px;
}
.steps:first-child {
  background: lightblue;
  border-left: 2px solid blue;
  border-top: 2px solid blue;
  border-bottom: 2px solid blue;
  margin-right: 18px;
}
.steps:first-child:before,
.steps:first-child:after {
  left: 18px;
}
.steps:last-child:before,
.steps:last-child:after {
  left: -18px;
}
/* Hover Styles */

.steps:first-child:hover,
.steps:last-child:hover,
.steps:hover:before,
.steps:hover:after {
  background: lightgreen;
}
.steps:first-child:hover {
  border-left: 2px solid green;
}
.steps:last-child:hover {
  border-right: 2px solid green;
}
.steps:hover:before {
  border-top: 2px solid green;
  border-right: 2px solid green;
  border-left: 2px solid green;
}
.steps:hover:after {
  border-left: 2px solid green;
  border-right: 2px solid green;
  border-bottom: 2px solid green;
}
.steps:first-child:hover,
.steps:last-child:hover {
  border-top: 2px solid green;
  border-bottom: 2px solid green;
}
.steps:first-child:hover:before,
.steps:first-child:hover:after {
  border-left: none;
}
.steps:last-child:hover:before,
.steps:last-child:hover:after {
  border-right: none;
}
/* Active Styles */

.active:first-child,
.active:last-child,
.active:before,
.active:after {
  background: bisque;
}
.active:first-child {
  border-left: 2px solid red;
}
.active:last-child {
  border-right: 2px solid red;
}
.active:before {
  border-top: 2px solid red;
  border-right: 2px solid red;
  border-left: 2px solid red;
}
.active:after {
  border-left: 2px solid red;
  border-right: 2px solid red;
  border-bottom: 2px solid red;
}
.active:first-child,
.active:last-child {
  border-top: 2px solid red;
  border-bottom: 2px solid red;
}
/* Just for creating a non solid color background */

body {
  height: 200px;
  background: -webkit-radial-gradient(center, ellipse, #400, #100);
  background: -moz-radial-gradient(center, ellipse, #400, #100);
  background: radial-gradient(center, ellipse, #400, #100);
}
<div class='steps-container'>
  <div class='steps'>
    <span>1. Step 1</span>
  </div>
  <div class='steps active'>
    <span>2. Step 2</span>
  </div>
  <div class='steps'>
    <span>3. Step 3</span>
  </div>
</div>

Екранна снимка: (с задържане на курсора на мишката върху втория елемент)

въведете описание на изображението тук


Отзивчиво внедряване с прозрачен фон:

За адаптивна версия на лентата за проследяване на напредъка с полупрозрачни полета посетете тази писалка. Ширината на всяка стъпка/елемент се задава по такъв начин, че тяхната сума винаги е 100% от наличната ширина и всеки елемент винаги е със същия размер като останалите.

JavaScript се използва за следните функции: (Всички тези функции са с добавена стойност и могат да бъдат премахнати в зависимост от нуждите. Имайте предвид, че когато JS бъде премахнат, съответните CSS свойства трябва да бъдат поставени в CSS файла.)

  • Автоматично регулирайте ширината на всеки елемент в зависимост от бр. на елементите, които присъстват в бара
  • Автоматично регулиране на ширината на всеки елемент при преоразмеряване на прозореца
  • Автоматично регулирайте външния вид на елементите, когато височината на лентата се увеличава или намалява с помощта на плъзгача.

въведете описание на изображението тук

person Harry    schedule 28.01.2015

Ето няколко страхотни стрелки за вас

html{
  background-color:red;
  }
div#page {
    padding-bottom: 40px;
    padding-top: 40px;
    text-align: center;
    z-index: 1;
    position: relative;
}
div.diamond, div.ribbon, div.right-arrow, div.left-arrow {
    display: inline-block;
    color: #FFFFFF;
    font-size: 22px;
    line-height: 38px;
    margin: 15px 0;
    position: relative;
    width: 200px;
}
div.diamond:before, div.diamond:after, div.ribbon:before, div.ribbon:after, div.right-arrow:before, div.right-arrow:after, div.left-arrow:before, div.left-arrow:after {
    content:"";
    border-style: solid;
    border-width: 0;
    height: 0;
    position: absolute;
    width: 0;
}
div.diamond {
    background-color: #CCCCCC;
}
div.diamond:after, div.diamond:before {
    border-color: transparent #CCCCCC;
}
div.diamond:before {
    left: -19px;
    border-width: 19px 19px 19px 0;
}
div.diamond:after {
    right: -19px;
    border-width: 19px 0 19px 19px;
}
div.ribbon {
    background-color: #CCCCCC;
}
div.ribbon:before, div.ribbon:after {
    top: 6px;
    z-index: -15;
}
div.ribbon:before {
    border-color: #B2B2B2 #B2B2B2 #B2B2B2 transparent;
    border-width: 19px;
    left: -25px;
}
div.ribbon:after {
    border-color: #B2B2B2 transparent #B2B2B2 #B2B2B2;
    border-width: 19px;
    right: -25px;
}
div.right-arrow {
    background-color: #CCCCCC;
}
div.right-arrow:after, div.right-arrow:before {
    border-width: 19px 0 19px 19px;
}
div.right-arrow:before {
    border-color: #CCCCCC transparent;
    left: -19px;
}
div.right-arrow:after {
    border-color: transparent #CCCCCC;
    right: -19px;
}
div.left-arrow {
    background-color: #CCCCCC;
}
div.left-arrow:after, div.left-arrow:before {
    border-width: 19px 19px 19px 0;
}
div.left-arrow:before {
    border-color: transparent #CCCCCC;
    left: -19px;
}
div.left-arrow:after {
    border-color: #CCCCCC transparent;
    right: -19px;
}
<div id="page">
    <div class="diamond">Diamond</div>
    <br>
    <div class="ribbon">Ribbon</div>
    <br>
    <div class="right-arrow">Right arrow</div>
    <br>
    <div class="left-arrow">Left arrow</div>
</div>

ИЗТОЧНИК

Забележка

това също позволява градиентни фонове/и т.н.


За други форми видях този codepen също онзи ден

person jbutler483    schedule 24.12.2014
comment
Благодаря за вашият отговор! Но аз ще следвам отговора на Габи, защото той се отнася по-добре за моя проблем. - person RobinvdA; 24.12.2014
comment
това е np. Просто реших да споделя тази информация за всички бъдещи читатели, това е всичко. - person jbutler483; 24.12.2014

Ако искате прозрачни интервали между разделите, настоящият отговор на Хари е, че те са добри.

Но ако искате да премахнете проблемите с задържането, можете да опитате следното. Той използва box-shadow за псевдоелементи вместо фон с плътен цвят.
Същият ефект е постижим с border: _px inset #___ ;

.li {
    height: 50px;
    width: 120px;
    background: #F5FBF1;
    display: inline-block;
    position: relative;
    margin-left: 30px;
    line-height: 50px;
    color: black;
    font-family: sans-serif;
    text-align: center;
}
.li:before, .li:after {
    content: '';
    left: -15px;
    position: absolute;
    height: 23px;
    width: 132px;
    border-left: 2px solid black;
    border-right: 2px solid black;
}
.li:before {
    border-top: 2px solid black;
    -webkit-transform-origin: 0% 0%;
    -moz-transform-origin: 0% 0%;
    -ms-transform-origin: 0% 0%;
    transform-origin: 0% 0%;
    -webkit-transform: skewX(30deg);
    -moz-transform: skewX(30deg);
    -ms-transform: skewX(30deg);
    transform: skewX(30deg);
    top: 0;
    box-shadow: inset 0 8px 0 8px #F5FBF1, inset -6px 8px 0 8px #F5FBF1;
}
.li:after {
    border-bottom: 2px solid black;
    -webkit-transform-origin: 0% 100%;
    -moz-transform-origin: 0% 100%;
    -ms-transform-origin: 0% 100%;
    transform-origin: 0% 100%;
    -webkit-transform: skewX(-30deg);
    -moz-transform: skewX(-30deg);
    -ms-transform: skewX(-30deg);
    transform: skewX(-30deg);
    bottom: 0;
    box-shadow: inset 0 -8px 0 8px #F5FBF1, inset -6px -8px 0 8px #F5FBF1;
}
.li:hover {
    background: #C0EBA4;
}
.li:hover:before {
    box-shadow: inset 0 8px 0 8px #C0EBA4, inset -6px 8px 0 8px #C0EBA4;
}
.li:hover:after {
    box-shadow: inset 0 -8px 0 8px #C0EBA4, inset -6px -8px 0 8px #C0EBA4;
}
<div class="li">ONE</div>
<div class="li">TWO</div>
<div class="li">THREE</div>
<div class="li">FOUR</div>
<div class="li">FIVE</div>

FIDDLE


Финална версия

Можете да го задържите безпроблемно. Включва плоски ръбове на първия и последния раздел.

.li {
    height: 50px;
    width: 100px;
    padding-left: 20px;
    background: #F5FBF1;
    display: inline-block;
    position: relative;
    margin-left: 20px;
    line-height: 50px;
    font-family: sans-serif;
    font-size: 15px;
}
.li:before, .li:after {
    content: '';
    left: -15px;
    position: absolute;
    height: 23px;
    width: 132px;
    border-left: 2px solid black;
    border-right: 2px solid black;
}
.li:before {
    border-top: 2px solid black;
    -webkit-transform-origin: 0% 0%;
    -moz-transform-origin: 0% 0%;
    -ms-transform-origin: 0% 0%;
    transform-origin: 0% 0%;
    -webkit-transform: skewX(30deg);
    -moz-transform: skewX(30deg);
    -ms-transform: skewX(30deg);
    transform: skewX(30deg);
    top: 0;
    box-shadow: inset 0 8px 0 8px #F5FBF1, inset -6px 8px 0 8px #F5FBF1;
}
.li:after {
    border-bottom: 2px solid black;
    -webkit-transform-origin: 0% 100%;
    -moz-transform-origin: 0% 100%;
    -ms-transform-origin: 0% 100%;
    transform-origin: 0% 100%;
    -webkit-transform: skewX(-30deg);
    -moz-transform: skewX(-30deg);
    -ms-transform: skewX(-30deg);
    transform: skewX(-30deg);
    bottom: 0;
    box-shadow: inset 0 -8px 0 8px #F5FBF1, inset -6px -8px 0 8px #F5FBF1;
}
.li:hover {
    background: #C0EBA4;
}
.li:hover:before { box-shadow: inset 0 8px 0 8px #C0EBA4, inset -6px 8px 0 8px #C0EBA4;}
.li:hover:after { box-shadow: inset 0 -8px 0 8px #C0EBA4, inset -6px -8px 0 8px #C0EBA4;}

/*First and Last styles*/
.li:first-of-type {
    left: -15px;
    box-shadow: 15px 0 0 0 #F5FBF1;
    border-left: 2px solid black;
}
.li:first-of-type:before, .li:first-of-type:after {
    left: -1px;
    width: 135px;
    border-left: 0;
}
.li:first-of-type:hover {box-shadow: 15px 0 0 0 #C0EBA4;}
.li:last-of-type {
    left: 0px;
    width: 115px;
    box-shadow: inset -2px 0 0 0 black, inset 0 -2px 0 0 black, inset 0 2px 0 0 black;
    border: 0;
}
.li:last-of-type:before, .li:last-of-type:after {
    left: -15px;
    border-right: 0;
}
.li:last-of-type:hover {background: #C0EBA4;}
<div class="li">Tab one</div>
<div class="li">Tab two</div>
<div class="li">Tab three</div>
<div class="li">Tab four</div>
<div class="li">Tab five</div>

FIDDLE (окончателен)

Изход:

въведете описание на изображението тук

person The Pragmatick    schedule 26.02.2015