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 this code in my megamenu – "About Sandfire".
However, when I click on the button (which is set to toggle) the hidden content turns on but then is hidden straight away. Not sure what I have done wrong here.
jQuery(function($){
var buttons = {
'.rv_button_1': {
'toggle': '.toggle-on-click-1',
'hide' : '.hide-on-click-1'
},
'.rv_button_2': {
'toggle': '.toggle-on-click-2',
'hide' : '.hide-on-click-2'
}
};
$.each(buttons, function(button, elements) {
$(button).click(function(e){
e.preventDefault();
$(elements.toggle).slideToggle();
$(elements.hide).hide();
$(button).toggleClass('rv_button_opened rv_button_closed');
});
});
});
and my hidden content has the classes: toggle-on-click-1 hide-on-click-2
the menu-items code looks like this:
About Sandfire
Our Purpose and Values
Would really appreciate what i have down wrong.
Hey Georgia, The issue is interference between the code in the "About Sandfire" section and the "Sustainability" section. You're essentially repeating the same code twice, so when you click on, for example, a button in the "About Sandfire" section, the code in that section toggles the content to make it visible, but then straight after the code in the "Sustainability" section toggles it closed again.
Since you only have two buttons in the "About Sandfire" section the issue is only affecting the top 2 buttons in the "Sustainability" section – the lower 2 aren't impacted and work as expected.
You should be able to solve this by giving each of the two sections its own unique classes. For example, change the code in the "About Sandfire" section to something like this:
And then update the classes on the buttons / revealed elements in that section to match.
Hopefully that makes sense, but let me know if not.
Hi! Thanks so much for this. I have gotten the toggle on click and the hide on click to work wonderfully but I need the element that gets hidden to come back on a second click. (Essentially, I need them both to toggle but opposite.)
Any tips?
Hey Megan, I think you just need to set them both to toggle – i.e. instead of setting one to hide on click, set it to toggle instead. Toggle just alternates repeatedly between visible and hidden, so an initially visible item would become hidden on the first click, and then come back on the second click, etc. An element that is hidden initially would instead become visible on the first click and then hidden again on the second click, etc. Hope that makes sense!
P.S. I tried to take a look at the link in your comment, but it's currently password protected, so I couldn't see how you have things set up at the moment. If you want me to take a look, perhaps you can send through the details via the contact form?
Hi Dan, awesome Post. I tried adapting your code to use it with other elements as buttons. I added some Text elements positioned in a grid as i try to style it similar to tabs, but maybe i adopted wrong. Do you have a hint what to change on jquery?
Hey Christian, in theory it should work on any element – just apply the button classes (e.g. "rv_button_1 rv_button_closed") as the CSS class in a text module instead of a button module. No need to rename them or anything like that. The only part that wouldn't work on other elements is the setting / changing of the icon (you'd need to, at a minimum, change the occurrences of "et_pb_button" to "et_pb_text", but I don't know if it will look / work right). Is there any chance you're able to point me to the page you're working on so that I can take a look for you? I checked the URL linked in your comment, but couldn't find the tabs there… maybe I missed them? Thanks!
Hello, I have implemented this function on my dev site. Instead of using slideup/down, I'm using fadein/out. However it looks like there is some sort of bug with the first module. It looks like it's doing a fade out and then fade in when clicking the button? It only happens on the first module on the page load. I tried deleting the first module of that first row but the same bug would then apply to next module. Do you have any suggestions? Thanks!
Hey Jon, when I've seen this sort of behavior before, it's been because the element being shown / hidden is referenced twice (e.g. if it's marked to be both toggled and shown). The fact it's happening on the first row makes it sound like there's a reference by order class in there somewhere, e.g. "et_pb_text_0" or similar – the "0" denoting the first module of a particular type on the page. But it's hard to say for sure without seeing the page itself. Is there any chance you're able to set up a demo of the issue on a live page so that I can take a looK? Thanks!
I attached a link to the page in the website field. Thanks again for helping me look into this.
Hi Jon, thanks for the link. You have some transition styling on the first blurb, like so:
I think this is causing the issue. When I disable it, the flash effect goes away. If you remove these styles from the page, I think that will solve the issue. I'm sure exactly where it's being added – either your custom CSS or in the "Blurb Settings > Advanced > Transitions" area. Let me know if you can't locate them and I'll try to help track them down. Hope that helps!
That was it. I had left that snippet in my custom CSS. Thanks for the help, Dan!
You’re welcome, Jon!
Hi
First of all, I love this scenario. I got the first part working. Unfortunately I am struggeling with the toggle effect, as I have multiple buttons that reveal/hide the text (4 in total). Unfortunately, I am a bit too stupid to figure out what I did wrong:
I am using the following code:
jQuery(function($){
var revealButtons = {
'.rv_button_1': '.rv_element_1',
'.rv_button_2': '.rv_element_2',
'.rv_button_3': '.rv_element_3',
'.rv_button_4': '.rv_element_4'
};
$.each(revealButtons, function(revealButton, revealElement) {
$(revealButton).click(function(e){
e.preventDefault();
$(revealElement).slideToggle();
$(revealButton).toggleClass('rv_button_opened rv_button_closed');
});
});
});
And have implemented the toggle-on-click on all text modules. But it still does not work.
Any idea?
many thanks for your feedback
Hi Mario, are you still having problems with this? I just checked and on the page clicking each image module reveals the corresponding text. I don't think you need to worry about the toggle-on-click class in your case, since you are already targeting the elements using the rv_element classes, and the code is doing a slideToggle() on those elements. The toggle-on-click class is only needed in the case that you're doing other transition effects too (i.e. just "hide" or just "show" some of the elements). I hope that makes sense, but let me know if it still isn't working the way you'd like. Cheers!
Hello, could you help me, I have put the initial basic code and it works perfectly on PC, but in the mobile version the content is shown initially and is not hidden. Any solution?
Hi Claudio, it sounds like there might be some other CSS rule applying to the content on mobile which is overriding the CSS in this post. It there any chance you're able to point me to an example so that I can take a look for you?
Hi,
is there any way for your script to both show/hide section and enable existing link to be working?
In my case button normally links do page anchor. After giving extra CSS + jQuery this link does not work. I want them work both after one click
Hey Jakub,
Basically the "e.preventDefault();" line in the above code examples disables the button link, so deleting that line should enable it again. However, things are slightly more complicated if you try to link to an element which is being shown / hidden. The browser will only scroll to an element which is visible at the time of the click, and will continue to scroll to the element's initial position even if it subsequently hidden. By default the slideToggle() / slideUp() / slideDown() functions used by the code take 400ms to change the visibility of an element (since they animate the "slide" effect first). This means that an element which is being hidden can be linked to, but will be gone by the time the scroll ends, and an element being shown can't be linked to because it isn't there at the time of the click. One way to address this would, I think, be to eliminate the animation on these functions by specifying a duration of 0, e.g. slideToggle(0) / slideUp(0) / slideDown(0). But note that that makes the show / hide effect happen instantly.
Putting this together, for example, the first bit of code would become:
Incidently, I've already implemented support for button links in the show / hide button module.
Hope that helps / makes sense!
Hi!
I'm trying to use multiple buttons to hide and reveal sections on my page.
After writing the code you suggested, the sections does get hidden and I see the button. But when clicked it shows the hidden section for just a second after hiding it again.
Please help!
Hi Marthe, I've seen this type of behavior when the button has been configured to both show and toggle the target section. In this case, when the button is clicked the section is first shown, making it visible, and straight after toggled, hiding it again (since toggling makes a visible element hidden, and vice-versa). A similar thing can happen if a section is configured to be both shown and hidden, though that's a more obvious mistake to spot. Only applying one operation to the element, e.g. show or toggle, should solve it if this is the issue for you.
If that doesn't help, perhaps you can send through a link to the page you're working on, either here or privately via the contact form, so that I can take a look for you?
How can I make the button stay active while section is opened?
Hey Damion, one option is to use the "Grouping" setting described here:
https://divibooster.com/divi-show-hide-module-grouping-option/
It can be used to add an active class to the button, which can then be used to style it. I hope that does what you need.
Hi, I'm tring to hide the "hidden element" but any solution don't work :(
Adding CSS to the Divi Theme
body:not(.et-fb) .rv_element_1 { display: none; }
…
Adding JavaScript / jQuery to Divi
jQuery(function($){
$('.rv_button_1').click();
var revealButtons = {
'.rv_button_1': '.rv_element_1'
};
My "reveal button" is for hide|show an image gallery, and initially it should be closed.
Help me
Thx in advance
Hi Roberto, try removing this line from what you have above:
At the moment, it is performing a click on the reveal button as soon as the page loads. Presumably this would be causing the image gallery to be revealed right away.
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? I checked the link in your comment, but got a site under construction page.
Thanks!
Thank you for this solution!
I have a problem with Divi Sticky feature (Row Settings > Advanced > Scroll Effect). I'm using show/hide button to filter different content groups (e.g. 'All campaigns', 'Campaign 1', 'Campaign 2') and there's a "inner navigation" with sticky effect in each hidden content group ('Campaign 1', 'Campaign 2') to filter groups sub content.
Sticky row works otherwise but not with 'rv_element' class. When I add the class to the row settings the row disappears when scrolling the groups sub content.
Is it possible to fix this?
Hey Outi, it looks like the sticky feature is overwriting the visibility of the element as set by show / hide button, and not restoring it after the sticky effect is removed. As such, it's basically putting the row back into the hidden state. I'll try to come up with a proper fix for this and update here when I do. In the meantime, it looks like it's possible to workaround this by applying the "rv_element" class to an outer element and then apply the sticky settings to an inner element. So, for example, if you're able to (re)arrange your layout such that you can apply the "rv_element" to a section and the sticky effect to a row within it, that should work. Likewise, if you apply the "rv_element" to the row and then make the modules within the row sticky, that should work too. If that isn't going to be possible, let me know (with a link to an example page, if possible). Cheers!
Great post, but i have one problem.
I want the first button simulated as clicked so it hides the other rows, i tried adding the class rv_button_1 rv_button_opened to the button but does not work:
jQuery(function($){
var buttons = {
'.rv_button_1': {
'toggle': ",
'hide' : '.rv_element_2,.rv_element_3,.rv_element_4',
'show' : '.rv_element_1'
},
'.rv_button_2': {
'toggle': ",
'hide' : '.rv_element_1,.rv_element_3,.rv_element_4',
'show' : '.rv_element_2'
},
'.rv_button_3': {
'toggle': ",
'hide' : '.rv_element_1,.rv_element_2,.rv_element_4',
'show' : '.rv_element_3'
},
'.rv_button_4': {
'toggle': ",
'hide' : '.rv_element_1,.rv_element_2,.rv_element_3',
'show' : '.rv_element_4'
}
};
$.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');
});
});
});
Website: https://drive.demowebsite1.nl/
Hey Jeffrey, I can see two options that should work:
1) Hide the elements initially via CSS, such as:
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:
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.
I hope that helps, but let me know if not. Thanks!