This post describes how to show, hide or toggle Divi Builder elements at the click of a button.
Reveal Elements on Click using Divi Show / Hide Module
Divi Show / Hide Button Module is a plugin I designed to make it easier to implement some of the effects described later in this post – without the need to mess around with jQuery code.
It is a modified version of the built-in Divi Button module. Rather than linking to another page, it lets you show, hide and toggle the visibility of elements on the same page. It can be styled the same way as the standard button module.
Check out the Divi Show / Hide Button Module here.
Reveal Elements on Click Using CSS / JQuery
Rob over at Divi Notes has a nice post on how to reveal a Divi section, row or module when a button is clicked. I've made what I think are a couple of improvements, which are shared below. The changes include:
- Preventing the hidden component from being briefly displayed when the page loads
- Support for multiple hidden sections / reveal buttons
- No hiding of the component in the visual builder for easier editing
Here are the steps to making a Divi Builder element (module, etc) displayed on the click of a button (and re-hidden if the button is clicked again).
Step 1: Add the "reveal" button and give it a class
Add a Button Module to your page that you want to use to show / reveal the target element.
Then set
Button Settings > Advanced > CSS ID & Classes > CSS Class
to
rv_button_1 rv_button_closed
like so:
Step 2: Add the hidden element and give it a class
Now add the element you want to show / hide. This can be a section, row or module. Go to the settings for the element, e.g.
{Element} Settings > Advanced > CSS ID & Classes > CSS Class
And add the following to the CSS Class field:
rv_element rv_element_1
Step 3: Add the following CSS / JavaScript code to your site
<style>
body:not(.et-fb) .rv_element { display: none; }
.et_pb_button.rv_button_opened:after { content:"\32"; }
.et_pb_button.rv_button_closed:after { content:"\33"; }
</style>
Related Post: Adding CSS to the Divi Theme
<script>
jQuery(function($){
var revealButtons = {
'.rv_button_1': '.rv_element_1'
};
$.each(revealButtons, function(revealButton, revealElement) {
$(revealButton).click(function(e){
e.preventDefault();
$(revealElement).slideToggle();
$(revealButton).toggleClass('rv_button_opened rv_button_closed');
});
});
});
</script>
Related Post: Adding JavaScript / jQuery to Divi.
Step 4: Publish and view the page
If all has gone well, the element should be hidden on the page. Clicking on the reveal button should reveal the element, and clicking a second time should hide it again.
If you have any trouble getting it to work, let me know in the comments or via the contact form.
It should look something like this:
Before:
Advanced: Adding more reveal buttons
If you want to add further reveal buttons (which reveal their own elements), you can do it like so:
- Give each new reveal button its own CSS class, for example "rv_button_2" for the second reveal button, "rv_button_3" for the third and so on.
- Give each new hidden element its own CSS class, for example "rv_element rv_element_2" for the second element, "rv_element rv_element_3" for the third, and so on.
- Modify the JavaScript code to include these new classes, e.g.
<script>
jQuery(function($){
var revealButtons = {
'.rv_button_1': '.rv_element_1',
'.rv_button_2': '.rv_element_2',
'.rv_button_3': '.rv_element_3'
};
$.each(revealButtons, function(revealButton, revealElement) {
$(revealButton).click(function(e){
e.preventDefault();
$(revealElement).slideToggle();
$(revealButton).toggleClass('rv_button_opened rv_button_closed');
});
});
});
</script>
Advanced 2: Showing and hiding elements on click
If you want to do something more than just revealing an element when the reveal button is clicked, here's an extended version of the code above, which adds the ability to show, hide and toggle multiple elements from the same button. This lets you do things like hide an element when revealing another, or replacing the reveal button with content (by hiding the reveal button once clicked).
<style>
body:not(.et-fb) .show-on-click,
body:not(.et-fb) .toggle-on-click {
display: none;
}
.et_pb_button.rv_button_opened:after { content:"\32"; }
.et_pb_button.rv_button_closed:after { content:"\33"; }
</style>
<script>
jQuery(function($){
var buttons = {
'.rv_button_1': {
'toggle': '.toggle-on-click',
'hide' : '.hide-on-click',
'show' : '.show-on-click'
}
};
$.each(buttons, function(button, elements) {
$(button).click(function(e){
e.preventDefault();
$(elements.toggle).slideToggle();
$(elements.show).slideDown();
$(elements.hide).slideUp();
$(button).toggleClass('rv_button_opened rv_button_closed');
});
});
});
</script>
The biggest change is that the buttons array now defines "toggle", "hide" and "show" values for the button(s).
- "toggle" takes a comma-separated list of CSS selectors which will be alternated between hidden and visible with each click of the reveal button. This is the default behavior of the earlier code examples.
- "hide" takes a comma-separated list of CSS selectors which will be hidden when the button is clicked. Subsequent clicks won't affect their visibility.
- "show" takes a comma-separated list of CSS selectors which will be displayed when the button is clicked. Subsequent clicks won't affect their visibility. It makes sense to hide such elements initially using CSS, as done for the ".show-on-click" class in the style block above.
Setup the button as per step 1, and give each element you want to be affected by the button the appropriate class (in the case of the example code this would be either "toggle-on-click", "hide-on-click" or "show-on-click").
Now you should see an effect similar to this (left column is set to toggle, center to show, and right to hide):
Initial state:
After first click:
After second click:
Advanced 3: Changing the Open / Close Icons
you can change the open / close icon from the default up / down arrow by changing these lines of CSS:
.et_pb_button.rv_button_opened:after { content:"32"; }
.et_pb_button.rv_button_closed:after { content:"33"; }
Here '32' is the code for the up arrow icon and '33' is the code for the down arrow icon. You can easily change this to another icon from this list:
https://www.elegantthemes.com/blog/resources/elegant-icon-font
Go to the "Complete Set and Unicode Reference Guide" section and then locate your desired icon(s). Take the part of the icon's code as shown here:
.et_pb_button.rv_button_opened:after { content:"42"; }
.et_pb_button.rv_button_closed:after { content:"43"; }
Advanced 4: Hiding Other "Tabs" Initially
If you have several reveal buttons and want to create a "tabbed" effect, you may wish to simulate a click on the first reveal button to hide the content of the other "tabs". Here's two ways to do it:
1) Hide the other tab content elements initially via CSS, such as:
.rv_element_2,.rv_element_3,.rv_element_4 {
display: none;
}
Note that you may need to change these class names to match your setup.
You can add this into your child theme style.css file or the "Divi > Theme Options > General > Custom CSS" box.
2) Trigger a click event on the button using jQuery. You should be able to do so by adding this after the jQuery code you've already added above:
jQuery(function($){
$('.rv_button_1').click();
});
Where "rv_button_1" is the class assigned to your first "tab" button.
The two options should achieve pretty much the same result, but there are some slight differences. The first option will apply immediately, while the second option only applies once the page is fully loaded, which might lead to the rows being briefly visible while the page is loading. The second option, though, more accurately simulates a button click which might be useful if you ever attach more complex behavior to the button.
Related post: Creating Tabs using the Divi Show / Hide Button Module
Advanced 5: Sliding the Revealed Element Left / Right
In the examples above, the element being revealed slides up / down as it is revealed / hidden. There isn't an equivalent way in jQuery to instead slide it left / right. However, we can achieve a left / right slide effect by additionally making use of the jQuery UI library.
First, install the jQuery UI library on your page / site following the instructions on the jQuery UI site. This will likely involve adding a script tag such as this to your site:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min.js" integrity="sha512-57oZ/vW8ANMjR/KQ6Be9v/+/h6bq9/l3f0Oc7vn6qMqyhvPd1cvKBRWWpzu0QoneImqr2SkmO4MSqU+RpHom3Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
Important: To get jQuery UI to work correctly, you may also need to disable Divi's jQuery Deferral option at:
Divi > Theme Options > General > Performance > Defer jQuery And jQuery Migrate
This in the original example (given at the top of this post), replace the line that reads:
$(revealElement).slideToggle();
With this (to slide right):
$(revealElement).toggle("slide", { direction: "left" }, 1000);
Or this (to slide right):
$(revealElement).toggle("slide", { direction: "right" }, 1000);
It is worth noting that loading jQuery UI and disabling Divi's jQuery Deferral may impact the page / site speed to some degree, so be sure to check that you are happy with the resulting site performance when implementing this.
Advanced 6: Deactivating Previously Active Buttons
In the above examples, a button which has been clicked becomes "active" and can be styled using the "rv_button_opened" class added to it. When the button is clicked again the class is removed, removing the active styling. However, buttons added using the instructions above act independently: activating one button doesn't "deactivate" the others. If you would actually like a newly active button to deactivate others (so you only have one button active at a time), then one way to handle this situation is to modify the code such that when the button is clicked, it removes the rv_button_opened class from the other buttons. Adding a line like this should do it:
$('.et_pb_button.rv_button_opened').not(revealButton).removeClass('rv_button_opened').addClass('rv_button_closed');
This is how it would look added to the code in the "Advanced: Adding more reveal buttons" section:
jQuery(function($){
var revealButtons = {
'.rv_button_1': '.rv_element_1',
'.rv_button_2': '.rv_element_2',
'.rv_button_3': '.rv_element_3'
};
$.each(revealButtons, function(revealButton, revealElement) {
$(revealButton).click(function(e){
e.preventDefault();
$(revealElement).slideToggle();
$(revealButton).toggleClass('rv_button_opened rv_button_closed');
$('.et_pb_button.rv_button_opened').not(revealButton).removeClass('rv_button_opened').addClass('rv_button_closed');
});
});
});
Note that if you use it with the code in "Advanced 2: Showing and hiding elements on click" you'd instead need to use:
$('.et_pb_button.rv_button_opened').not(button).removeClass('rv_button_opened').addClass('rv_button_closed');
(as it uses "button" as the variable name, instead of "revealButton").
For users of the Divi Show / Hide Button module, the grouping option can be used to make a set of buttons act as a group with only one button active at a time. The currently active button can then be styled using the active button styling options.
Advanced 7: Only Show the Button on Mobile
To only show the button on mobile:
1. Click on the "disable" option in the button module's menu:
2. Click on the "tablet" and "desktop" icons, to disable the button module on those devices. This will make the button show on mobile only.
3. Wrap the CSS code from the tutorial in a "media query" which will make the CSS code only apply on mobile (leaving the filters visible on tablet / desktop). For example, if you are using this CSS from above:
<style>
body:not(.et-fb) .rv_element { display: none; }
.et_pb_button.rv_button_opened:after { content:"\32"; }
.et_pb_button.rv_button_closed:after { content:"\33"; }
</style>
You'd change it to this:
<style>
@media only screen and (max-width: 980px) {
body:not(.et-fb) .rv_element { display: none; }
.et_pb_button.rv_button_opened:after { content:"\32"; }
.et_pb_button.rv_button_closed:after { content:"\33"; }
}
</style>
Hi, I have used advanced 2 code and almost things are working fine but there's a slight issue:
I have four buttons: rv_button_2 rv_button_3 rv_button_4 rv_button_5
Each button shows a different form set into different rows: rv_element_2 rv_element_3 rv_element_4 rv_element_5
now when rv_button_2 is clicked rv_element_2 element is shows perfect till here now when rv_button_3 is clicked rv_element_3 is shown but it doesn't hide the previously active button rv_button_2
I have added this code: $('.et_pb_button.rv_button_opened').not(button).removeClass('rv_button_opened').addClass('rv_button_closed');
but still not working am I missing something here?
Hey hasan, in your case, I'd modify the definition of the buttons in the Advanced 2 code to be:
So, when you click a button it both shows the corresponding row and hides all the others.
I hope that helps, but if not are you able to share a link so that I can take a look? Cheers!
Hi, thank you for this article. it help me a lot, it's working for me but the element ar not hide at the first but after touch the button, can you advise me please
Hi Khalil, you need to hide the element initially using CSS. From the JavaScrpt code in your linked page, it looks like your reveal elements are intended to have the IDs "reveal" and "reveal1". In this case, the CSS to hide them initially would be something like this:
(slightly modified from the CSS given in the post)
However, I don't actually see elements with these IDs in the page, or the reveal button. It looks like you might have rebuilt the page in Elementor, right? If you are still having problems getting it to work, and still want to, is there any chance you can point me in the direction of your reveal button / element? Thanks!
Thanks so much for this! I have a slight issue. My site is doing the opposite. My content that is supposed to be initially hidden is showing and then when I click the button it hides. I want it to be hidden when the page loads. Any suggestions?
Disregard. The first set of code – I was trying to add that in CSS rather than the header code. Sorry about that. User error… shocking.
Ha ha, no worries, Angela! I’m glad you got it figured out and thanks for the update :)
Hi Dan – thanks for the great tutorial. I got everything to work as expected.
However, I am trying to style only the active button's color. I did try following as suggested in a previous comment:
.et_pb_button.rv_button_opened {
color: red;
}
Unfortunately, it only changes back to the original "inactive" color when clicking on the same "active" button again, and not when clicking on another "inactive" button.
Is there a solution for changing the button color back to "inactive" color so that only the active button with revealed content is a different color? Ie. Active button with reveal content is "color A – red" and rest of the buttons with unrevealed content is "color B – blue?"
I tried adding the following, with no luck – as the result is the same (color only changes when clicking on the same active button) :
.et_pb_button.rv_button_closed {
color: blue;
}
Thanks in advance
Thanks for getting in touch and I'm really glad the tutorial has been of use :)
One way to handle this situation is to modify the code such that when the button is clicked, it removes the rv_button_opened class from the other buttons. Adding a line like this should do it:
This is how it would look added to the code in the "Advanced: Adding more reveal buttons" section:
Note that if you use it with the code in "Advanced 2: Showing and hiding elements on click" you'd instead need to use:
(as it uses "button" as the variable name, instead of "revealButton").
I hope that helps, but let me know if you have any issues with it. Cheers!
Hi dan, I have a slight issue I have four buttons:
rv_button_2 rv_button_closed
rv_button_3 rv_button_closed
rv_button_4 rv_button_closed
rv_button_5 rv_button_closed
Each button shows a different form which is in a different row with this classes:
rv_element rv_element_2
rv_element rv_element_3
rv_element rv_element_4
rv_element rv_element_5
Now when I click "rv_button_2 rv_button_closed" the element "rv_element rv_element_2" is shown but when I click "rv_button_3 rv_button_closed" the element "rv_element rv_element_3" is shown but rv_element rv_element_2 element doesn't gets hidden how can I hide previously active button element
Hey hasan, in your case, I'd modify the definition of the buttons in the Advanced 2 code to be:
So, when you click a button it both shows the corresponding row and hides all the others.
I hope that helps, but if not are you able to share a link so that I can take a look? Cheers!
I am wanting to slide this left and right. How do I make that happen??
Hey Ryan, I've just added a section to the end of the post with instructions on one way to do this. I hope it helps, but if it doesn't meet your needs, let me know. Thanks!
Hi and thanks for this great tutorial.
My problem is, that the section closes immediately after a second. :-(
What I'm doing wrong?
Hey Arndt, it looks like you are adding the jQuery code twice – once in a code module at the end of the bottom of the page (after the testimonial), and once in (I think) the "WP Dashboard > Divi > Theme Options > Integration" tab. When the button is run, the first instance of the code toggles the section, opening it, and then immediately after the second instance of the code toggles the section again, which this time closes it. If you remove one of the copies of the jQuery code, I think that should get it working correctly. Let me know if not. Thanks!
oh my dear … now it's working! :-)
Thanks again!!
Glad to hear it, Arndt! :)
Hello, thanks for the article and the very good explanation.
I've implemented successfully the basic setup. Now I'm trying to implement the advanced 2 but I can't seem to fully understand the steps:
do I have to use both codes or only the code you show on advanced2 section?
I have 7 buttons and 7 items to show or hide (one for each) and I want to show one and all the others to hide. Is it possible?
Thanks in advance, it would be very helpfull.
Hi Sofia,
The advanced 2 code replaces the earlier code – you only need it. Here's how I think you would need to modify it for your case. (To keep the example short I've just set it up for three buttons, but hopefully you get the idea):
<style>
body:not(.et-fb) .rv_element:not(.rv_element_1) {
display: none;
}
.et_pb_button.rv_button_opened:after { content:"\32"; }
.et_pb_button.rv_button_closed:after { content:"\33"; }
</style>
<script>
jQuery(function($){
var buttons = {
'.rv_button_1': {
'toggle': ",
'hide' : '.rv_element_2,.rv_element_3',
'show' : '.rv_element_1'
},
'.rv_button_2': {
'toggle': ",
'hide' : '.rv_element_1,.rv_element_3',
'show' : '.rv_element_2'
},
'.rv_button_3': {
'toggle': ",
'hide' : '.rv_element_1,.rv_element_2',
'show' : '.rv_element_3'
}
};
$.each(buttons, function(button, elements) {
$(button).click(function(e){
e.preventDefault();
$(elements.toggle).slideToggle();
$(elements.show).slideDown();
$(elements.hide).slideUp();
$(button).toggleClass('rv_button_opened rv_button_closed');
});
});
});
</script>
Give each button its own class ("rv_button_1", "rv_button_2", "rv_button_3", etc) and give the corresponding item classes like so ("rv_element rv_element_1", "rv_element rv_element_2", "rv_element rv_element_3", etc).
Now the code above will hide all of the items initially, except the one with the "rv_element rv_element_1" classes. And each button is set up so that when it is clicked it will show its own item and hide the other items.
I hope that helps, but let me know if it isn't clear or doesn't work for you. In that case, if you're also able to share a link to the page you're working on, please do. Thanks!
Thanks for this Dan, super-helpful!
Could you please tell me how I can reverse the direction of the hide and show options?
I have 4 buttons, and when I first open the page and click on button 1, the content slides down. Then as I move left to right and click button 2, it appears that the .rv_element_1 slides up and .rv_element_2 slides up to take its place. Then again with button 3, then button 4. Once .rv_element_4 is open, and I go backwards to 3 then 2 then 1, it appears that the content slides down and the new content slides down as well. I'd like to reverse this so as I move left to right, it appears that the new content slides down into position.
I've tried switching:
$(elements.show).slideDown();
$(elements.hide).slideUp();
to
$(elements.show).slideUp();
$(elements.hide).slideDown();
and it reverses the logic of the buttons, so button 1 now shows .rv_elements_2, 3 and 4 but not .rv_element_1, and the same for the other buttons.
Thanks so much for your time and expertise!
Hey Stuart, the names of the jQuery functions are a bit misleading here – they don't really "slide up" and "slide down". Rather, slideUp() shrinks an elements height to 0, while slideDown() increases the element height from 0 to its full height. So when you click, for example, on button 2, you're seeing .rv_element_1 shrinking in height while .rv_element_2 simultaneously expands in height. The combined height of the two remains the same throughout and the visual effect is that .rv_element_2 expands from the bottom to gradually reach full height. This suggests a solution – reverse the order of .rv_element_1 and .rv_element_2 in the layout, so that .rv_element_2 is before .rv_element_1. Then when you click button 2, .rv_element_2 would appear to expand from the top while .rv_element_1 shrinks down to the bottom. More generally, reverse the order of all the rv_elements in the layout, so that .rv_element_4 appears first in the layout. I think they should then behave the way you want. I hope that helps / makes sense!
Thanks, Dan, yes makes perfect sense. I tried changing the order of the buttons in the code but of course not actually reversing the order on the page. Thanks again, and cheers.
You’re welcome, Stuart :)
i create a new button made everything right and the button doesn't show up…
Hey Diego. Sorry to hear you're having trouble with it. First, clear any caches on your site and refresh the page. If that doesn't help, are you able to share a link to the page you're working on so that I can take a look? Cheers!
Hi, thank you for sharing this great code, it did exactly what I wanted it to. The only other thing I am looking to do is style the button when it has been clicked or is active. How would I go about doing that?
Hey Evan, I'm glad it helped. The code above should set the ".rv_button_opened" class on the button when it is clicked / active, and remove it again when re-clicked / deactivated (restoring the initial ".rv_button_closed" class).
So you should be able to style the active state of the button with some CSS like this:
I hope that helps, but let me know if you need any further help with it.
Note: for anyone using the show / hide button module, there's built-in support for styling the active state.
Thanks for the great tutorial Dan!
I am also trying to only change the active button's color which is currently revealing hidden content.
I got the original color (1) to change to alternative color (2) on click and it changes back to the color (1) when clicking the same button again. Unfortunately, it does not change back to original color (1) and stays on color (2) when clicking another button, which also reveals another hidden content section. It only changes to color (1) when clicking on same button again.
Is there a way to change the button alternative color (2) back to the original color (1) when clicking on another button?
I would like to only have the active button on color (1) and all other inactive buttons on color (2).
Thanks in advance!
Appologies – correction on last sentence on my comment above :
I would like to only have the active button with revealed content on color (2) and all other inactive buttons on original color (1).
Thanks deonk. I've replied to another of your comments with the solution, and have also added the solution to the post itself, in the "Advanced 6: Deactivating Previously Active Buttons" section. Hope it helps!
Hi,
Thank you for this great tutorial. I am having trouble with toggling between the two elements. Basically, I have one button to show a row of blurbs (row 1) and another button to show a different row of blurbs (row 2), but when row 2 is triggered I want row 1 to disappear. Am I missing something in the tutorial on how to do this?
Many thanks in advance
You're welcome, Leah. The section of the tutorial that covers this is "Advanced 2: Showing and hiding elements on click". It includes code for having the button hide elements, as well as show them. If you haven't already seen it, hopefully it will help you out. But if you still can't get it working, are you able to share a link to the page you're working on so that I can offer some more specific advice? Thanks!
Hi Dan,
have the same problem like leah, have two buttons each with an own element to show.
button 1 element has class rv_element_1 show-on-click, button 2 element has rv_element_2 show-on-click and css is .rv_element_2 { display: none; } to show only the first element on start. But how can I get the .rv_element_1 to hide when .rv_element_2 is showing?
Can you specify how to achieve this?
Thanks in advance!
Hey Maik,
If you use the code in the "Advanced 2" section of the post, then I think you'd want to have the "var buttons = { … }" bit set up something like this:
That way when you click on element button 1 it will show element 1 and hide element 2, and vice versa for button 2. You might need to replace the actual button classes in the above (i.e. rv_button_1 and rv_button_2) with your own, if you're using something different for them.
I hope that helps, but if you have any trouble getting it to work, please feel free to share a link to the page you're working on so that I can take a look for you. Cheers!
Hi, thank you for this article. I'm having a small issue. Everything works great when I'm logged into the site, but it doesn't work when users are not logged in. Any idea what could be causing that?
Hey Oliver – usually this is a caching issue. Many caching plugins will show the cached (i.e. old) version of a page to non-logged in users, but will show the non-cached (i.e. new) version of the page to logged in users (on the basis that they may be editing the page). Try clearing any caches in use on your site, particularly those of any performance plugins you're using. Clear your browser cache too. Then try refreshing the page to see if that sorts it out. If not, is there any chance you're able to send through a link to the page you're working on? Thanks!
Can you tell me why the images are going white on hover after I added this code? And also how can I remove that empty white space beneath the photos?
Hi Tina, I don't think it's related to the code. Rather, I think it's due to the settings of the background image in the column. Go into settings for one of the columns and then go to the background option. If you hover over the option's title you'll see (among other things) an "arrow pointer" icon – click that and then click the second "arrow pointer" tab that appears. This should be the background that appears on hover. I suspect this is configured to show no background, but has some setting active (e.g. the parallax option) that is causing the (empty) hover background to be applied. If you either set the hover background to match the non-hover version of the background, or reset all the hover background settings to their defaults, I think that should solve the issue.
For the empty white space beneath the photos – you have an empty section there. If you delete that, it should remove the gap.
I hope that helps, but let me know if not. Thanks!