Responsive arrow progress bar with transparent bor

2019-06-24 04:59发布

I am trying to build a progress bar as seen often within checkouts.

Transparent border progress bar

The problem is, that the borders between the arrows are transparent and the whole thing should be responsive. I got it this far:

http://codepen.io/MrBambule/pen/rVBeoz

But I can't figure out how to get the items of the bar to span the whole width of the parent container (red border in the pen) and stay responsive.
I think I could figure it out with JS but I'd rather have a CSS solution.
Help would be much appreciated.

HTML

<ul class="progress-nav">
  <li class="active">
    <span>1. FOO</span>
  </li>
  <li>
    <span>2. BAR</span>
  </li>
  <li>
    <span>3. BAZ</span>
  </li>
</ul>

CSS

$bar-color: rgba(255, 255, 255, 0.2);
$bar-active-color: rgba(255, 255, 255, 0.6);
$arrow-size: 22px;

body {
  background: linear-gradient(left, #803689, #5eb6e4);
}

.progress-nav {
  position: relative;
  font-size: 0;
  margin: 100px auto;
  width: 80%;
  max-width: 900px;

  // dummy border to display the width problem 
  border: 1px solid red;

  li {
    position: relative;
    color: #fff;
    font-size: 12px;
    display: inline-block;
    width: 20%;
    margin-right: 48px;
    list-style: none;
    background: $bar-color;
    padding: $arrow-size 0;

    transition: background .5s, color .5s;

    span {
      position: absolute;
      width: 100%;
      top: 50%;
      left: 50%;
      transform: translateX(-33px) translateY(-35%);
    }

    &:before,
    &:after {
      content: '';
      position: absolute;
      display: block;
      top: 0;

      transition: all .5s;
    }
    &:before {
      border: $arrow-size solid $bar-color;
      border-left-color: transparent;
      left: -$arrow-size*2;
    }
    &:after {
      border: $arrow-size solid transparent;
      border-left-color: $bar-color;
      right: -$arrow-size*2;
    }
    &:first-child:before {
      border: none;
      width: $arrow-size*2;
      height: $arrow-size*2;
      background: $bar-color;
      border-radius: 4px 0 0 4px;
    }
    &:last-child:after {
      border: none;
      right: -$arrow-size;
      width: $arrow-size;
      height: $arrow-size*2;
      background: $bar-color;
      border-radius: 0 4px 4px 0;
    }

    &.active,
    &:hover {
      background: $bar-active-color;
      color: #000;

      &:before {
        border-color: $bar-active-color;
        border-left-color: transparent;
      }
      &:after {
        border-left-color: $bar-active-color;
      }
      &:first-child:before,
      &:last-child:after {
        background: $bar-active-color;
      }
    }
  }
}

1条回答
我命由我不由天
2楼-- · 2019-06-24 05:48

you could use something like:

.wrap {
  width: 100%;
  height: 30px;
  z-index:-2;white-space: nowrap;
  overflow:hidden;
}
.wrap div:first-child{margin-left:-2%;}
.progress {
  margin:0;
  margin-left:0.5%;
  height: 30px;
  width: 25%;
  position: relative;
  display: inline-block;
  text-align: center;
  line-height: 30px;
  transition: all 0.8s;
}
.progress:before,
.progress:after {
  content: "";
  position: absolute;
  transition: all 0.8s;
  z-index:-1;
}
.progress:before {
  height: 50%;
  width: 100%;
  top: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.2);
  -webkit-transform: skew(45deg);
  -moz-transform: skew(45deg);
  transform: skew(45deg);
}
.progress:after {
  height: 50%;
  width: 100%;
  top: 50%;
  left: 0;
  background: rgba(0, 0, 0, 0.2);
  -webkit-transform: skew(-45deg);
  -moz-transform: skew(-45deg);
  transform: skew(-45deg);
}
.progress:hover:before,
.progress:hover:after {
  background: tomato;
}
<div class="wrap">
  <div class="progress">
    simple
  </div>
  <div class="progress">
    as
  </div>
  <div class="progress">
    complex
  </div>
  <div class="progress">
    Web Development
  </div>
</div>

which is responsive to the width of the screen.

It makes use of the transform:skew property for the middle bars, and a small border hack for the two far elements. This results in the output shown below:

Result

enter image description here

NOTE

If you are creating these dynamically (and want them all along the same line), then you will need to alter the width stated in the first css rule (currently set to 23%).

查看更多
登录 后发表回答