CSS-only sliding underline tabs

时间:2018-09-18 19:56:00

标签: html css sass bootstrap-4

We had a set of tabs in our Bootstrap3-based site, which worked fine. We had this scss mixin which would

  1. calculate the number of tabs being used based on the class you applied to the nav
  2. put an ::after pseudo-element below the last-child li to make an "underline" the width of the li with a transition on translateX and a translateX of 0
  3. when a given li got a class of active applied to it by Bootstrap, translate the ::after element on the last-child the correct percentage to slide it underneath the active tab

So, now updating to Bootstrap 4.1, I discovered that it no longer applies the active class to the li, but to the a tag within it. So my sibling selector no longer works:

.tabs-sliding li:nth-child(2).active ~ li:last-child::after {
  transform: translateX(-300%);
}

I realize I could do this with javascript, but I'm still hoping for a scss-only solution. Here is a codepen with the entire code. The pink background when a tab is clicked was just a text to confirm the active class.

Here is the mixin (also in the codepen):

@mixin sliding-tabs($tab-number) {
  $children: $tab-number;
  //percentage function converts 1 to 100
  $width: percentage(1 / $children);

  //apply width to .nav-tabs li & a tags
  &.tabs-sliding .nav.nav-tabs li {
    width: $width;
  }

  //based on width of each tab, figure out the appropriate offset for the sliding ::after pseudo-element "underline"
  @for $i from 1 through $children {
    li:nth-child(#{$i}) a.active {
      background-color: pink !important;
    }
    li:nth-child(#{$i}) a.active ~ li:last-child::after {
      $offset: percentage($i - $children);
      transform: translateX(#{$offset});
    }
  }
}

Sample usage:

.tabs-sliding {
  @include sliding-tabs(5);
}

0 个答案:

没有答案