Home > Enterprise >  Create transition effect over psuedo element in css
Create transition effect over psuedo element in css

Time:02-12

I am trying to create a manila folder like set of tabs in HTMl. I have achieved the desired look by using psuedo elements. My only issue is, when the user hovers their cursor over the actual "tab" element I want a color to come in from the right to show them that they are hovering over something clickable. My only problem with this approach is my lack of knowledge of psuedo elements.

I have a linear gradient as the background image, and have upped the background-size to only show one half of the linear gradient. As the user hover, the hover css changes the background position to the other color. This effect looks weird with my psuedo element, as it has to have its own rules. How can I achieve the desired effect in one fluid on and off animation??

Here is my code:

const $allTabs = document.body.querySelectorAll('.tab');

for (let i = 0; i < $allTabs.length; i  = 1) {
  const $tab = $allTabs[i];

  $tab.style.zIndex = $allTabs.length - i;
  
  $tab.addEventListener('click', () => {
   removeActive();
    $tab.classList.toggle('active')
  })
}

function removeActive() {
  const arrOfTabs = Array.from($allTabs);
 
   const $activeTab = arrOfTabs.find(tab => tab.classList.contains('active'));
  $activeTab.classList.toggle('active');
}
.navigation-tab {
    display: flex;
    height: 50px;
    width: 100%;
    justify-content: space-around;
    align-items: center;
    overflow: hidden;
    padding-top: 10px;
    background-color: white;
}

.tab.active {
    background-color: #f8f8f8;
    z-index: 90 !important;
    background-image: none;
}

.tab.active::before {
    background-color: #f8f8f8;
    z-index: 90 !important;
    background-image: none;
}
.tab.active::after {
    background-color: #f8f8f8;
    z-index: 90 !important;
    background-image: none;
}

.tab {
    height: 100%;
    width: 100%;
    display: grid;
    place-items: center;
    background-color: white;
    background-image: linear-gradient(120deg, white 0%, white 50%, #005289 50%);
    background-size: 220%;
    position: relative;
    z-index: 0;
    cursor: pointer;
    filter: drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.5));
    transition: all 0.2s;
    transition-delay: 0.2s;
}

.tab:not(.active):hover {
    background-position: 100%;
    color: white;
    font-weight: bold;
}

.tab::before {
    width: 30px;
    height: 100%;
    border-radius: 10px 10px 0px 0px;
    background-image: linear-gradient(120deg, white 0%, white 50%, #005289 50%);
    background-size: 280%;
    content: '';
    position: absolute;
    left: -20px;
    top: 0px;
    -webkit-transform: skewX(-20deg);
    transform: skewX(-20deg);
    z-index: -1;
    transition: all 0.2s;
    transition-delay: 0.4s;
}

.tab:not(.active):hover::before {
    background-position: 100%;
}

.tab::after {
    height: 100%;
    width: 30px;
    border-radius: 10px 10px 0px 0px;
    background-image: linear-gradient(120deg, white 0%, white 50%, #005289 50%);
    background-size: 280%;
    content: '';
    position: absolute;
    right: -20px;
    top: 0px;
    -webkit-transform: skewX(20deg);
    transform: skewX(20deg);
    z-index: -1;
    transition: all 0.2s;
}

.tab:not(.active):hover::after {
    background-position: 100%;
}
<div >
  <nav >
  <div >Overview</div>
  <div >New buys</div>
  <div >Budget</div>
  <div >Renewals</div>
  <div >Procs</div>
  <div >Work for me</div>
  </nav>
</div>

CodePudding user response:

The problem is the size of your psuedo element.

First, you only need the ::after pseudo element to achieve this effect. You can remove the gradient backgrounds on the ::before pseudo element and the main element. Next, set the size of that ::after pseudo element so it can actually cover the whole tab. I used a width of 110%. The result will be that the after pseudo element will come in from the right and make it all the way to the left side

Note: this is a lot of code and I don't understand all of it, so I left as much as I could untouched and just removed some of the hover style rules and edited the ::after:hover style rule. I will leave it to you to cut whatever else need to be cut.

Note #2. You have done some messy z-index stuff on the first tab. This meant the text rendered under the ::after element. I have removed the messy z-indexing.

const $allTabs = document.body.querySelectorAll('.tab');

for (let i = 0; i < $allTabs.length; i  = 1) {
  const $tab = $allTabs[i];

  $tab.style.zIndex = $allTabs.length - i;
  
  $tab.addEventListener('click', () => {
   removeActive();
    $tab.classList.toggle('active')
  })
}

function removeActive() {
  const arrOfTabs = Array.from($allTabs);
 
   const $activeTab = arrOfTabs.find(tab => tab.classList.contains('active'));
  $activeTab.classList.toggle('active');
}
.navigation-tab {
    display: flex;
    height: 50px;
    width: 100%;
    justify-content: space-around;
    align-items: center;
    overflow: hidden;
    padding-top: 10px;
    background-color: white;
}

.tab.active {
    background-color: #f8f8f8;
    z-index: 90 !important;
    background-image: none;
}

.tab.active::before {
    background-color: #f8f8f8;
    z-index: 90 !important;
    background-image: none;
}
.tab.active::after {
    background-color: #f8f8f8;
    background-image: none;
}

.tab {
    height: 100%;
    width: 100%;
    display: grid;
    place-items: center;
    background-color: white;
    background-image: linear-gradient(120deg, white 0%, white 50%, #005289 50%);
    background-size: 220%;
    position: relative;
    z-index: 0;
    cursor: pointer;
    filter: drop-shadow(0px 0px 1px rgba(0, 0, 0, 0.5));
    transition: all 0.2s;
    transition-delay: 0.2s;
}

.tab:not(.active):hover {
    background-position: 100%;
    color: white;
    font-weight: bold;
}

.tab::before {
    width: 30px;
    height: 100%;
    border-radius: 10px 10px 0px 0px;
    background-image: linear-gradient(120deg, white 0%, white 50%, #005289 50%);
    background-size: 280%;
    content: '';
    position: absolute;
    left: -20px;
    top: 0px;
    -webkit-transform: skewX(-20deg);
    transform: skewX(-20deg);
    z-index: -1;
    transition: all 0.2s;
    transition-delay: 0.4s;
}

.tab::after {
    height: 100%;
    width: 30px;
    border-radius: 10px 10px 0px 0px;
    background-image: linear-gradient(120deg, white 0%, white 50%, #005289 50%);
    background-size: 280%;
    content: '';
    position: absolute;
    right: -20px;
    top: 0px;
    -webkit-transform: skewX(20deg);
    transform: skewX(20deg);
    z-index: -1;
    transition: all 0.2s;
    width: 110%;
}

.tab:not(.active):hover::after {
    background-position: 100%;
}
<div >
  <nav >
  <div >Overview</div>
  <div >New buys</div>
  <div >Budget</div>
  <div >Renewals</div>
  <div >Procs</div>
  <div >Work for me</div>
  </nav>
</div>

  •  Tags:  
  • css
  • Related