Split in half CTA flexbox content that expands in width on hover

JavaScript

// **************************************************
//  Locations Hover
// **************************************************
const locationsHover = (className) => {
    // get the required elements
    const locationsContainer = document.querySelector(className)

    // guard clause to make sure the '.locations-container' element exists on the page
    if (locationsContainer == null) {
        return
    }

    // get the required elements
    const locationItem = locationsContainer.querySelectorAll('.locations__item')

    locationItem.forEach((element, index) => {
        // count the index but +1 so we don't start with '0'
        index = index + 1

        // get the current element's previous and next elements
        let previousElement = element.previousElementSibling
        let nextElement = element.nextElementSibling
  
        // expand
        function mouseoverFocus() {
            // if even, else odd
            if (index % 2 === 0) {
                element.classList.add('locations__item--expand')
                if (previousElement) {
                    previousElement.classList.add('locations__item--shrink')
                }
            } else {
                element.classList.add('locations__item--expand')
                if (nextElement) {
                    nextElement.classList.add('locations__item--shrink')
                }
            }
        }
        element.addEventListener('mouseover', mouseoverFocus)
        element.addEventListener('focus', mouseoverFocus)
        
        // shrink
        function mouseoutBlur() {
            // if even, else odd
            if (index % 2 === 0) {
                element.classList.remove('locations__item--expand')
                if (previousElement) {
                    previousElement.classList.remove('locations__item--shrink')
                }
            } else {
                element.classList.remove('locations__item--expand')
                if (nextElement) {
                    nextElement.classList.remove('locations__item--shrink')
                }
            }
        }
        element.addEventListener('mouseout', mouseoutBlur)
        element.addEventListener('blur', mouseoutBlur)

        // get required elements
        const locationsInfo = element.querySelector('.locations__info')
        const locationsMore = element.querySelector('.locations__more')

        // get the width of each '.locations__item' element, add a percentage to it to make it match the width of the "expanded" content, then use the value to set the width of the '.locations__more' element
        const viewportWidth = window.innerWidth
        const locationsItemWidth = element.offsetWidth
        console.log('viewportWidth = ' + viewportWidth)
        if (viewportWidth >= 1024) {
            const percentage = 8;
            const percentageValue = ((percentage / 100) * locationsItemWidth) + locationsItemWidth
            locationsMore.style.width = percentageValue + 'px'
        } else {
            locationsMore.style.width = locationsItemWidth - 40 + 'px'
        }

        // get the height of each '.locations__more' element and then use the value to set the 'bottom' value of the '.locations__info' element
        let locationsMoreHeight = locationsMore.offsetHeight
        locationsInfo.style.bottom = '-' + locationsMoreHeight + 'px'
    })
}
locationsHover('.locations-container--1')
locationsHover('.locations-container--2')

HTML

<section class="content width-medium | locations-container locations-container--1">
  <div class="locations">
    <div class="locations__item" data-type="{{ TYPE }}" data-id="{{ ID }}" tabindex="0">
        <img src="https://images.unsplash.com/photo-1567745576351-5eb638a17443?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80" class="locations__image" loading="lazy" alt="{{ TITLE }}" width="825" height="460">
        <div class="locations__info">
            <h3 class="locations__title">Title of Thing</h3>
            <address class="locations__address">Portland, OR</address>

            <div class="locations__more">
                <p class="locations__content">Lorem ipsum consectetur adipiscing elit. Suspendisse iaculis ultrices nisl, sit amet dictum ante pretium et. Nam ligula purus, accumsan nec lorem in, gravida lobortis nisi. Duis pulvinar cursus tellus at hendrerit. Morbi tempor sit amet libero non rutrum. Aenean vel risus lectus. Nunc in neque pulvinar, posuere diam faucibus, pretium arcu. Ut in sollicitudin eros. Phasellus congue risus felis, id mattis ante mollis non. Vivamus id pellentesque ex. Integer nec leo posuere, posuere felis eget, venenatis purus. Etiam gravida, felis vitae fermentum malesuada, nisi sem rhoncus erat, sed aliquet justo felis sit amet erat. Nulla vehicula facilisis ligula eu suscipit.</p>
                <a href="https://www.alxwntr.com" target="_blank" rel="noreferrer" class="locations__link">Visit Website</a>
            </div>
        </div>
    </div>

    <div class="locations__item" data-type="{{ TYPE }}" data-id="{{ ID }}" tabindex="0">
        <img src="https://images.unsplash.com/photo-1567745576352-e404ee640705?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80" class="locations__image" loading="lazy" alt="{{ TITLE }}" width="825" height="460">
        <div class="locations__info">
            <h3 class="locations__title">Title of Thing</h3>
            <address class="locations__address">Portland, OR</address>

            <div class="locations__more">
                <p class="locations__content">Lorem ipsum consectetur adipiscing elit. Suspendisse iaculis ultrices nisl, sit amet dictum ante pretium et. Nam ligula purus, accumsan nec lorem in, gravida lobortis nisi. Duis pulvinar cursus tellus at hendrerit. Morbi tempor sit amet libero non rutrum. Aenean vel risus lectus. Nunc in neque pulvinar, posuere diam faucibus, pretium arcu. Ut in sollicitudin eros. Phasellus congue risus felis, id mattis ante mollis non. Vivamus id pellentesque ex. Integer nec leo posuere, posuere felis eget, venenatis purus. Etiam gravida, felis vitae fermentum malesuada, nisi sem rhoncus erat, sed aliquet justo felis sit amet erat. Nulla vehicula facilisis ligula eu suscipit.</p>
                <a href="https://www.alxwntr.com" target="_blank" rel="noreferrer" class="locations__link">Visit Website</a>
            </div>
        </div>
    </div>
  </div>
</div>

CSS

.locations {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1.5em;
}

.locations__item {
  flex-grow: 0;
  flex-shrink: 1;
  flex-basis: calc(50% - 0.75em);
  transition: all 1s;
  position: relative;
  isolation: isolate;
  overflow: hidden;

  &--expand {
    flex-basis: calc(60% - 0.75em);
  }

  &--shrink {
    flex-basis: calc(40% - 0.75em);
  }

  @media (max-width: 1024px) {
    flex-basis: 100%;
  }

  &:before {
    content: '';
    background-color: rgb(0 0 0 / 0);
    position: absolute;
    inset: auto;
    width: 100%;
    height: 100%;
    display: block;
    transition: all 1s;
  }

  &:hover,
  &:focus {
    &:before {
      background-color: rgb(0 0 0 / 0.75);
    }
  }

  &:after {
    content: '';
    background: linear-gradient(0deg, rgba(0,0,0,1) 0%, rgba(255,255,255,0) 100%);
    position: absolute;
    inset: auto auto 0 auto;
    width: 100%;
    height: 50%;
    display: block;
    z-index: 1;
  }
}

.locations__image {
  display: block;
  width: 100%;
  height: 460px;
  // max-height: 460px;
  object-fit: cover;
}

.locations__info {
  position: absolute;
  inset: auto auto 0 clamp(1em, 5vw, 2em);
  z-index: 2;
  transition: all 1s;
  pointer-events: none; // prevents bug that causes hover animation twitching in gaps

  >* {
    color: #fff;
  }
}

.locations__title {
  font-size: 1.35rem;
}

.locations__address {
    font-size: 1rem;
    text-transform: uppercase;
    margin-bottom: 2em;
}

.locations__more {
  color: #fff;
  margin-top: 0;
  opacity: 0;
  transition: all 1s;

  >* {
    color: #fff;
  }
}

.locations__content {
  font-size: 1rem;

  @media (max-width: 1024px) {
    line-height: 1.25;
  }
}

.locations__link {
    font-size: 1rem;
    text-transform: uppercase;
    margin-bottom: 2em;
}

.locations__item {
  outline: 0;

  &:hover,
  &:focus {
    .locations__info {
      bottom: 1em !important;
      pointer-events: all;
    }

    .locations__more {
      margin-top: -1.5em;
      opacity: 1;
    }

    .locations__content {
    }
  }
}