Accordion Module scroll to top of accordion on click

Hello,

I’m making a landing page using the free accordion module with large amounts of content. When you read to the bottom and click to the next accordion, the large amount of content is collapsed and I’m left at the bottom of the page, way below the accordion module. It seems like the farther you have to scroll to get to the next accordion section, the farther down the page it puts you.

Anyone know any way to get it to not scroll me down when I open the next section of the accordion?

Here is the link to the template I’m using:

Here is the HTML

of

the module:

{% set accordionId = ‘{{ name }}’ %}
<div class=“st-accordionWhiter2 " id=”{{ accordionId }}" > {# << Should only one accordion be open at a time? #}
<ul>
{% for item in module.accordion %} {# << Loop through the accordians group #}
<li class=“st-accordion-wrapper”>
<a href=“#”>
{{ item.accordion_title }}
<span class=“st-arrow”>Open or Close</span>
</a>
<div class=“st-content”>
{{ item.content }}
</div>
</li>
{% endfor %}
</ul>
</div>

Here is the CSS of the module:

.st-accordionWhiter2{
width:100%;
min-width:270px;
margin: 0 auto;
}
.st-accordion-wrapper{
-webkit-box-shadow: 0px 0px 10px 0px rgba(50, 50, 50, 0.1);
-moz-box-shadow: 0px 0px 10px 0px rgba(50, 50, 50, 0.1);
box-shadow: 0px 0px 10px 0px rgba(50, 50, 50, 0.);
margin-top:20px;
border-radius:3px;
}
.st-accordionWhiter2 ul li{
height: 46px;
/*border-bottom: 1px solid #1f5c71;*/
overflow: hidden;
}
.st-accordionWhiter2 ul li:first-child{
border-top:none;
}
.st-accordionWhiter2 ul li > a{
font-size: 16px;
color: #393939;
/*Section header text normal color*/
display: block;
position: relative;
line-height: 46px;
padding-left: 46px;
outline:none;
-webkit-transition: color 0.2s ease-in-out;
-moz-transition: color 0.2s ease-in-out;
-o-transition: color 0.2s ease-in-out;
-ms-transition: color 0.2s ease-in-out;
transition: color 0.2s ease-in-out;
background-color: #fff;
/*Unclicked rectangle bg color*/
/**/
text-decoration:none;
border-bottom : 1px solid #eee;
}
.st-accordionWhiter2 ul li > a span{
background: transparent url({{ module_asset_url(“plus-dark.png”) }}) no-repeat center center;
text-indent:-9000px;
width: 26px;
height: 16px;
position: absolute;
top: 50%;
left: 0px;
margin-top: -8px;
margin-left: 16px;
opacity:1;
-webkit-transition: all 0.2s ease-in-out;
-moz-transition: all 0.2s ease-in-out;
-o-transition: all 0.2s ease-in-out;
-ms-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
}
.st-accordionWhiter2 ul li > a:hover{
color: #3c9fa0;
}
.st-accordionWhiter2 ul li > a:hover span{
opacity:1;
}
.st-accordionWhiter2 ul li.st-open > a{
color: #3c9fa0;
}
.st-accordionWhiter2 ul li.st-open:first-child{height:auto!important;}
.st-accordionWhiter2 ul li.st-open > a span{
background: transparent url({{ module_asset_url(“minus-dark.png”) }}) no-repeat center center;
right:0px;
opacity:1;
margin-top: -8px;
}
.st-accordionWhiter2 .st-content{
padding: 20px 20px 20px 0px;
background: #fff;
/*Content rectangle color*/
}
.st-accordionWhiter2 .st-content p{
color: #727272;
/*default content text color */
font-size: 16px;
padding-left: 50px;
}

@media screen and (max-width: 768px){
.st-accordionWhiter2 ul li > a{
font-size:16px;
}
}

@media screen and (max-width: 320px){
.st-accordionWhiter2 ul li > a{
font-size:14px;
}
}

Any help at all would be fantastic.

Thanks,

Nate

You can add this JS:

var accordionItems = document.querySelectorAll('.st-accordion-wrapper a');
accordionItems.forEach(item => {
 item.addEventListener('click', (e)=>{
 let top = e.target.offsetTop;
 window.scroll({
 top: top, // if you have a sticky nav, take the height of that off 'top' e.g. 'top - 100';
 behavior: 'smooth'
 });
 });
});

Hi @JNFultz ,
You can create your own module in Hubspot. and I will recommend you to use this code https://codepen.io/Chris5656/pen/wJbMEd
Create and edit modules in the design manager

Hope this helps!

If we were able to answer your query, kindly help the community by marking it as a solution.
Thanks and Regards.

Hey Piersg,

The code you sent worked great, thanks for that. I’m using the “top: X px;” to get it to scroll to wherever the top of the accordion is. The only issue I’m running into is if the content height above the accordion changes, it scrolls to the wrong spot. This height can change if another accordion the page is left open. Am I maybe utilizing the code wrong, or is there another way to do it so it anchors to wherever the top of the accordion is?

I tried at first to leave it so that top: top - 200px; but it didn’t seem to work until I changed it to a specific value. It would just scroll all the way to the top of the page.

Here is how I have the code right now:

var accordionItems = document.querySelectorAll('.st-accordion-wrapper a');
accordionItems.forEach(item => {
 item.addEventListener('click', (e)=>{
 let top = e.target.offsetTop;
 window.scroll({
 top: 1800, // if you have a sticky nav, take the height of that off 'top' e.g. 'top - 100';
 behavior: 'smooth'
 });
 });
});

});
});

Hi @JNFultz. Hmm… well with top: top - 200px you have to remove the ‘px’ so it should be top: top - 200.

But really the issue is that the page will scroll to the point at which you clicked, rather than where the clicked item is after content height changes/animations etc. Do you have a link I could take a look at?

The easiest way (bit of a shortcut maybe) is to use a timeout function that is the same length or just a bit longer than the animation length of the accordions shrinking and expanding (from your CSS it looks like this is 0.2s or 200ms). This just forces the click function to wait until after the animations are done to find where the clicked element is, instead of at the time of the click. See how that feels in terms of UX for you:

var accordionItems = document.querySelectorAll('.st-accordion-wrapper a');
accordionItems.forEach(item => {
 item.addEventListener('click', (e)=>{
 setTimeout(function(){
 let top = e.target.offsetTop;
 window.scroll({
 top: top - 200,
 behavior: 'smooth'
 });
 }, 200);
 });
});

Here is an example:

https://info.realhomeownership.com/accordiontest1234561093845709834

I’m working on the last accordion under “Other Resources”

This should work

var accordionItems = document.querySelectorAll('.st-accordion-wrapperr a'); //you've got an extra 'r' in the 'wrapperr' class names here by the way
accordionItems.forEach(item => {
 item.addEventListener('click', (e)=>{
 setTimeout(function(){
 let top = e.target.getBoundingClientRect().top + document.documentElement.scrollTop;
 window.scroll({
 top: top - 200,
 behavior: 'smooth'
 });
 }, 200);
 });
});

That seems to work perfectly, thank you!