Как сделать эту стрелку только в CSS?

Я создаю мастер-подобный процесс заказа, где у меня есть это меню: menu

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

как сделать эту стрелку, используя только CSS?:

arrow

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

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

левое изображение: enter image description here

изображение:enter image description here

Я нашел ответ SO, который делает часть этого: стрелка с CSS, однако у меня проблемы с отступом слева.

Если у вас есть лучшее представление о том, как это сделать, пожалуйста, дайте мне знать!

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>

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

в основном реализация выглядит следующим образом:

  1. есть один div для каждого шага / элемента, и он содержит текст, который должен быть отображен. Скажем height этой div is x (50px в этом образец.)
  2. два псевдо-элементы (:before и :after) создаются со своими width то же самое, что и родитель div и height как половина (x/2) родителя. The :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 элемент, как в приведенном ниже фрагменте будет решить. (Спасибо в 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>

скриншоты: (с наведением на второй пункт)

enter image description here


отзывчивая реализация с прозрачным фоном:

для отзывчивой версии панели отслеживания прогресса с полупрозрачными коробками посетите эта ручка. Ширина каждого шага / элемента назначается таким образом, чтобы их сумма всегда составляла 100% от доступной ширины и каждый предмет всегда имел тот же размер, что и остальные.

JavaScript используется для следующих функций: (все эти функции добавленной стоимости и могут быть удалены в зависимости от потребностей. Обратите внимание, что при удалении JS соответствующие свойства CSS должны быть помещены в файл CSS.)

  • автоматически отрегулируйте ширину каждого деталя в зависимости от Нет. пунктов, которые присутствуют в в баре
  • автоматическая регулировка ширины каждого элемента при изменении размера окна
  • автоматическая настройка внешнего вида элементов при увеличении или уменьшении высоты панели с помощью ползунка.

enter image description here


вот некоторые большие стрелки для вас

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>

источник

Примечание

этой также позволяет градиентные фоны / etc


для других форм, я видел это codepen на днях тоже


если вы хотите прозрачные пробелы между вкладками, текущий ответ Гарри-это путь.

но если вы хотите удалить проблемы с наведением, вы можете попробовать следующее. Он использует 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>

скрипка


финал версия

вы можете навести его плавно. Он включает в себя плоские края первой и последней вкладок.

.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>

скрипка (итоговой)

выход:

enter image description here