DJ Monzyk
DJ Monzyk

Reputation: 58

How to toggle sibling elements and related children properly?

I want to be able to "turn on/off" an item to make it visually active and have a hidden child element show using CSS, while also making the sibling elements opacity drop. This is working as expected.

Although I want to allow it, I don't want to force a user to deselect the same element in order to 'turn it off'. I want to be able to click any sibling to one of these items and have the newly selected one show active, as the other siblings (and children hidden elements) set to this more transparent display.

I had a similar question with a response that worked (How can I toggle sibling child elements?), but had to change up the UX for usablity reasons which forced me to re-factor the code re-introduced my problem in dealing with the siblings.

$(".feature-expand a.card").click(function(e) {
  e.preventDefault();
  $(this).parent().siblings().toggleClass("normal go-light");
  $(this).parent().toggleClass("active normal");

  let thisHiddenItem = $(this).siblings(".hidden-item");
  $('.hidden-item').not(thisHiddenItem).removeClass('shown');
  thisHiddenItem.toggleClass("shown");
});
.feature-wrapper {
  transition: all 0.5s ease;
}

.hidden-item {
  opacity: 0;
  transition: all 0.5s ease;
  display: none;
}

.feature-wrapper img {
  max-width: 130px;
  margin: 0 auto;
}

.go-light {
  opacity: 0.3;
}

.hidden-item.shown {
  opacity: 1;
  display: block;
  height: auto;
  width: calc(100% - 24px);
  margin: 0px 12px;
  position: absolute;
  z-index: 2;
  background: #fff;
}

@media ( min-width:992px) {
  .hidden-item.shown {
    opacity: 1;
    display: block;
    height: auto;
    width: calc(200% - 24px);
    margin: 0px 12px;
    position: absolute;
    z-index: 2;
    background: #fff;
  }
}

.hidden-item.shown.odd {
  left: 0;
}

.hidden-item.shown.even {
  left: -100%;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" type="text/css">
<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/[email protected]/dist/jquery.fancybox.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<link rel="stylesheet" href="https://kbmaxweb4.azureedge.net/wp-content/themes/kbmax/css/bootstrap.min.css?ver=4.2.1" type="text/css">
<link rel="stylesheet" href="https://kbmax.com/wp-content/themes/kbmax/style.min.css" type="text/css">
<link rel="stylesheet" href="feature-expand.css" type="text/css">

<div class="">
  <div class="container">
    <div class="row pt-5 d-flex feature-expand">
      <div class="col-md-6 p-2 feature-wrapper">
        <a href="#" class="text-decoration-none card rounded shadow-sm overflow-hidden">
          <div class="row">
            <div class="col-3 py-3 pr-3 pl-4 rounded bg-light d-flex flex-column justify-content-center slant-right">
              <i class="fas fa-check fa-4x mx-auto"></i></div>
            <div class="col-9 p-3 d-flex flex-column justify-content-center">
              <h5 class="text-tertiary m-0">
                <span class="text-primary">Robust rules</span> that provide consistency and control of the entire process. </h5>
            </div>
          </div>
        </a>
        <div class="hidden-item odd shadow-sm">
          <div class="row">
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Left column contents
            </div>
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Right column contents
            </div>
          </div>
        </div>
      </div>
      <div class="col-md-6 p-2 feature-wrapper">
        <a href="#" class="text-decoration-none card rounded shadow-sm overflow-hidden">
          <div class="row ">
            <div class="col-3 py-3 pr-3 pl-4 bg-light d-flex flex-column justify-content-center slant-right">
              <i class="fas fa-check fa-4x mx-auto"></i></div>
            <div class="col-9 p-3 d-flex flex-column justify-content-center">
              <h5 class="text-tertiary m-0">
                <span class="text-primary">Captivating visualization</span> to drive engagement with products and increase sales.</h5>

            </div>
          </div>
        </a>
        <div class="hidden-item even shadow-sm">
          <div class="row">
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Left column contents
            </div>
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Right column contents
            </div>
          </div>
        </div>
      </div>
      <div class="col-md-6 p-2 feature-wrapper">
        <a class="text-decoration-none card rounded shadow-sm overflow-hidden" href="#">
          <div class="row">
            <div class="col-3 py-3 pr-3 pl-4 bg-light d-flex flex-column justify-content-center slant-right">
              <i class="fas fa-check fa-4x mx-auto"></i></div>
            <div class="col-9 p-3 d-flex flex-column justify-content-center">
              <h5 class="text-tertiary m-0">
                <span class="text-primary">Proposal automation</span> to shorten the sales cycle and relieve engineering.</h5>
            </div>
          </div>
        </a>
        <div class="hidden-item odd shadow-sm">
          <div class="row">
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Left column contents
            </div>
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Right column contents
            </div>
          </div>
        </div>
      </div>
      <div class="col-md-6 p-2 feature-wrapper">
        <a class="text-decoration-none card rounded shadow-sm overflow-hidden" href="#">
          <div class="row">
            <div class="col-3 py-3 pr-3 pl-4 bg-light d-flex flex-column justify-content-center slant-right">
              <i class="fas fa-check fa-4x mx-auto"></i></div>
            <div class="col-9 p-3 d-flex flex-column justify-content-center">
              <h5 class="text-tertiary m-0">
                <span class="text-primary">Powerful integration</span> that seamlessly connects business systems and processes.</h5>
            </div>
          </div>
        </a>
        <div class="hidden-item even shadow-sm">
          <div class="row">
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Left column contents
            </div>
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Right column contents
            </div>
          </div>
        </div>
      </div>
      <div class="col-md-6 p-2 feature-wrapper">
        <a class="text-decoration-none card rounded shadow-sm overflow-hidden" href="#">
          <div class="row">
            <div class="col-3 py-3 pr-3 pl-4 bg-light d-flex flex-column justify-content-center slant-right">
              <i class="fas fa-check fa-4x mx-auto"></i></div>
            <div class="col-9 p-3 d-flex flex-column justify-content-center">
              <h5 class="text-tertiary m-0">
                <span class="text-primary">Dynamic pricing</span> provides immediate feedback to enable your quote-to-cash vision.</h5>
            </div>
          </div>
        </a>
        <div class="hidden-item odd shadow-sm">
          <div class="row">
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Left column contents
            </div>
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Right column contents
            </div>
          </div>
        </div>
      </div>
      <div class="col-md-6 p-2 feature-wrapper">
        <a class="text-decoration-none card rounded shadow-sm overflow-hidden" href="#">
          <div class="row">
            <div class="col-3 py-3 pr-3 pl-4 bg-light d-flex flex-column justify-content-center slant-right">
              <i class="fas fa-check fa-4x mx-auto"></i></div>
            <div class="col-9 p-3 d-flex flex-column justify-content-center">
              <h5 class="text-tertiary m-0">
                <span class="text-primary">Manufacturing automation </span> provides CAD, BOMs, and cut sheets to the shop floor.</h5>
            </div>
          </div>
        </a>
        <div class="hidden-item even shadow-sm">
          <div class="row">
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Left column contents
            </div>
            <div class="col-lg-6 px-4 py-2 d-flex flex-column justify-content-center">
              Right column contents
            </div>
          </div>
        </div>
      </div>
    </div>

  </div>
</div>
<div class="pt-5">
  <div class="container">
    <div class="row">
      <div class="col-md-12">
      </div>
    </div>
    <div class="row">
      <div class="col-md-12">
      </div>
    </div>
  </div>


  <script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous" style=""></script>

</div>

Upvotes: 0

Views: 235

Answers (2)

DJ Monzyk
DJ Monzyk

Reputation: 58

After some trial and error, and a little help from a friend, I've got the solution I was looking for so wanted to share it back.

$(".feature-expand a.card").click(function(e) {
        e.preventDefault();
        let thisHiddenItem = $(this).siblings(".hidden-item");

        if (!$(this).parent().hasClass( "active")) {
            // Make this item active
            $(this).parent().addClass( "active");

            // Clear 'go-light' from other elements
            let thisOtherItem = $(this).parent().siblings(".feature-wrapper");
            $('.feature-wrapper').removeClass('go-light');
            thisOtherItem.removeClass( "active");
            thisOtherItem.addClass("go-light");

            // Re-hide the siblings' child hidden element
            $('.hidden-item').not(thisHiddenItem).removeClass('shown');
            thisHiddenItem.toggleClass("shown");    
        } else {
            // Remove active class from this
            $(this).parent().removeClass( "active");
            // Remove go-light class from siblings
            $(this).parent().siblings(".feature-wrapper").removeClass( "go-light");
            // Re-hide the child hidden element
            thisHiddenItem.removeClass("shown");    
        }
    });

Upvotes: 1

Rounin
Rounin

Reputation: 29453

I don't want to force a user to deselect the same element in order to 'turn it off'. I want to be able to click any sibling to one of these items and have the newly selected one show active

Two steps:

  1. Turn all the elements off (except the one the user just clicked on)
  2. Toggle the element the user just clicked on

In this situation:

[1 - Inactive] [2 - Active] [3 - Inactive] [4 - Inactive]

  • If the user clicks on [1], [3] or [4], then [2] will switch off and the new element will switch on;
  • If the user clicks on [2], then [2] will switch off

Upvotes: 1

Related Questions