CSS Grid Expand / Collapse

From Level Access Web Labs
Jump to navigation Jump to search

Here's an example of a CSS Grid implementation of a 3 column layout.
The contents of each program's details are programmatically connected to the links that spawn the contents. Additionally, the program contens occur directly after the program within the reading order and the tab order.
Clicking on a program link will toggle the link's aria-expanded attribute, as well as display the relevant program details. Any previously selected programs will be automatically closed.
What this implementation does not do is provide for buttons within the displayed program details.

Apprenticeship Content
Lorem Ipsum

Arts & Media Content
Lorem Ipsum

Automotive Content
Lorem Ipsum

Business & Management Content
Lorem Ipsum

Computer Science Content
Lorem Ipsum

Criminal Justice Content
Lorem Ipsum

HTML

<div class="container">
    <div class="tab-topics row active-child">
        <div class="topic col-md-4 col-sm-6 col-xs-12 active">
             <div class="topic-inner" style="background-image: url(https://www.clackamas.edu/images/default-source/topics/apprenticeship_2-769x430.jpg?sfvrsn=4376b468_2)">
                <a id="program0" href="#" class="topic-title" aria-expanded="true" aria-controls="program0Details">
                    Apprenticeship
                </a>
            </div>
        </div>
        <div id="program0Details" class="topic-programs expanded" data-la-initdispnone="true" role="group" aria-labelledby="program0">
            <p>Apprenticeship Content <br/> Lorem Ipsum</p>
        </div>
        <div class="topic col-md-4 col-sm-6 col-xs-12">
            <div class="topic-inner" style="background-image: url(https://www.clackamas.edu/images/default-source/topics/arts_and_media-769x430.jpg?sfvrsn=4276b468_2)">
                <a id="program1" href="#" class="topic-title" aria-expanded="false" aria-controls="program1Details">
                    Art and Media
                </a>
            </div>
        </div>
        <div id="program1Details" class="topic-programs" data-la-initdispnone="true" role="group" aria-labelledby="program1">
            <p>Arts & Media Content <br/> Lorem Ipsum</p>
        </div>
        <div class="topic col-md-4 col-sm-6 col-xs-12">
            <div class="topic-inner" style="background-image: url(https://www.clackamas.edu/images/default-source/topics/automotive-769x430_small.jpg?sfvrsn=4176b468_2)">
                <a id="program2" href="#" class="topic-title" aria-expanded="false" aria-controls="program2Details">
                    Automotive
                </a>
            </div>
        </div>
        <div id="program2Details" class="topic-programs" data-la-initdispnone="true" role="group" aria-labelledby="program2">
            <p>Automotive Content <br/> Lorem Ipsum</p>
        </div>
        <div class="topic col-md-4 col-sm-6 col-xs-12">
            <div class="topic-inner" style="background-image: url(https://www.clackamas.edu/images/default-source/topics/business-and-management_1-760x430-.jpg?sfvrsn=4676b468_2)">
                <a id="program3" href="#" class="topic-title" aria-expanded="false" aria-controls="program3Details">
                    Business and Management
                </a>
            </div>
        </div>
        <div id="program3Details" class="topic-programs" data-la-initdispnone="true" role="group" aria-labelledby="program3">
            <p>Business & Management Content <br/> Lorem Ipsum</p>
        </div>
        <div class="topic col-md-4 col-sm-6 col-xs-12">
            <div class="topic-inner" style="background-image: url(https://www.clackamas.edu/images/default-source/topics/computer-science-760x430-.jpg?sfvrsn=5976b468_2)">
                <a id="program4" href="#" class="topic-title" aria-expanded="false" aria-controls="program4Details">
                    Computer Science
                </a>
            </div>
        </div>
        <div id="program4Details" class="topic-programs" data-la-initdispnone="true" role="group" aria-labelledby="program4">
            <p>Computer Science Content <br/> Lorem Ipsum</p>
        </div>
        <div class="topic col-md-4 col-sm-6 col-xs-12">
            <div class="topic-inner" style="background-image: url(https://www.clackamas.edu/images/default-source/topics/criminal_justice-769x430.jpg?sfvrsn=5376b468_2)">
                <a id="program5" href="#" class="topic-title" aria-expanded="false" aria-controls="program5Details">
                    Criminal Justice
                </a>
            </div>
        </div>
        <div id="program5Details" class="topic-programs" data-la-initdispnone="true" role="group" aria-labelledby="program5">
            <p>Criminal Justice Content <br/> Lorem Ipsum</p>
        </div>
    </div>
</div>

CSS

.container {
    width: 1550px;
}
.tab-topics {
  display: grid;
  grid-template-columns: auto auto auto;
  grid-auto-rows: 200px;
  grid-gap: 10px 5px;
}
.topic {
  outline: 1px solid black;
}
.topic-inner {
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;  
    height: 100%;
    position: relative;
}
.topic-title::after {
    content: "";
    height: 100%;
    left: 0;
    position: absolute;
    top: 0;
    width: 100%;
}
.topic-programs {
  display: none;
}

.topic-programs.expanded {
  display: initial;
  outline: 1px solid;
}
.topic-programs.expanded:nth-of-type(-n+6) {
  grid-column: 1 / 4 ;
  grid-row: 2;  
}
.topic-programs.expanded:nth-of-type(n+7):nth-of-type(-n+12) {
  grid-column: 1 / 4 ;
  grid-row: 3;  
}

JavaScript

/*Toggles True/False for values  */
function toggle (index,value) {
  var b = (value === 'true');
  return !b;
}

jQuery('.topic-title[aria-controls]').click(function(e){
  e.preventDefault();
  //Searches for any expanded grid items that are NOT the one controlled by the link that was clicked
  jQuery(this).parents('.topic').siblings('.topic-programs.expanded').not( "#" + jQuery(this).attr('aria-controls') ).toggleClass(function() {
    //If expanded grid items are found, toggles the aria-expanded attribute for the relevant expanding link
    jQuery( "#" + jQuery(this).attr('aria-labelledby') ).attr('aria-expanded', toggle);
    //and toggles the expanded class for this grid item
    return 'expanded';
  });
  jQuery(this).attr('aria-expanded', toggle);
  jQuery( "#" + jQuery(this).attr('aria-controls') ).toggleClass('expanded');
});