Responsive Product Data Tabs in WooCommerce

If you have added custom product data tabs to your woocommerce install, then you might have noticed that they don’t work well on a small screen. In this post I will modify the default tab template with a responsive design to make the tabs stack nicely on a mobile device.

On a desktop screen, I want the tabs to continue to work the same as normal, and on a mobile screen I want the tabs to display as an accordion. The default markup makes this hard to do, as the tabs and the content are in separate <div> tags.

There are two options to get around this. Modify the template and duplicate the content, then use css to show and hide the tab content. The other would be to use javascript to move the content into the correct place when a tab is clicked, avoiding the duplicate content.

I will choose the CSS route, as it’s a bit simpler and doesn’t interfere with the js that Woocommerce already adds to the page.

The template that lays out tabs is woocommerce/templates/single-product/tabs/tabs.php, so copy that from the woocommerce plugin and copy it to your theme inside the woocommerce folder.

<?php
/* CSS for responsive product tabs in WooCommerce. See my blog post here: https://www.timrosswebdevelopment.com/responsive-product-data-tabs-woocommerce */
/**
* Filter tabs and allow third parties to add their own.
*
* Each tab is an array containing title, callback and priority.
*
* This is a woocommerce template override and should be added to your custom theme in the following location:
* wp-content/themes/<YOUR-THEME>/woocommerce/single-product/tabs/tabs.php
*
* @see woocommerce_default_product_tabs()
*/
$product_tabs = apply_filters('woocommerce_product_tabs', array());
if (! empty($product_tabs)) : ?>
<!– Add a new class to style the responsive tabs –>
<div class="woocommerce-tabs wc-tabs-wrapper woocommerce-tabs-responsive">
<ul class="tabs wc-tabs" role="tablist">
<?php foreach ($product_tabs as $key => $product_tab) : ?>
<li class="<?php echo esc_attr($key); ?>_tab" id="tab-title-<?php echo esc_attr($key); ?>" role="tab" aria-controls="tab-<?php echo esc_attr($key); ?>">
<a href="#tab-<?php echo esc_attr($key); ?>">
<?php echo wp_kses_post(apply_filters('woocommerce_product_' . $key . '_tab_title', $product_tab['title'], $key)); ?>
</a>
<!– Add the content here that is only displayed on small screens –>
<div class="woocommerce-Tabs-accordion-content woocommerce-Tabs-accordion-content–<?php echo esc_attr($key); ?> entry-content" id="accordion-<?php echo esc_attr($key); ?>">
<?php
if (isset($product_tab['callback'])) {
call_user_func($product_tab['callback'], $key, $product_tab);
}
?>
</div>
</li>
<?php endforeach; ?>
</ul>
<?php foreach ($product_tabs as $key => $product_tab) : ?>
<div class="woocommerce-Tabs-panel woocommerce-Tabs-panel–<?php echo esc_attr($key); ?> panel entry-content wc-tab" id="tab-<?php echo esc_attr($key); ?>" role="tabpanel" aria-labelledby="tab-title-<?php echo esc_attr($key); ?>">
<?php
if (isset($product_tab['callback'])) {
call_user_func($product_tab['callback'], $key, $product_tab);
}
?>
</div>
<?php endforeach; ?>
<?php do_action('woocommerce_product_after_tabs'); ?>
</div>
<?php endif; ?>
view raw tabs.php hosted with ❤ by GitHub

In this template, I’ve duplicated the tab content inside each tab. I will use CS to hide and show this content on active tabs. I’ve also added a class name to the tab block so that we can use CSS to style the responsive tabs.

With that done, I can use CSS to make sure the tabs display correctly on small screens.

/* CSS for responsive product tabs in WooCommerce. See my blog post here: https://www.timrosswebdevelopment.com/responsive-product-data-tabs-woocommerce */
/* For small screens only */
@media screen and (max-width: 767px) {
.woocommerce-tabs.woocommerce-tabs-responsive ul li {
/* this rule needs to be important to override the default woocommerce style */
display: flex !important;
flex-direction: column;
width: 100%;
}
.woocommerce-tabs.woocommerce-tabs-responsive .woocommerce-Tabs-panel {
/* this rule needs to be important to override the default woocommerce style */
display: none !important;
}
.woocommerce-Tabs-accordion-content {
display: none;
}
.woocommerce-tabs.woocommerce-tabs-responsive ul li.active .woocommerce-Tabs-accordion-content {
display: block;
}
}
/* On larger screens make sure the accordion does not show. */
@media screen and (min-width: 768px) {
.woocommerce-Tabs-accordion-content {
display: none !important;
}
.woocommerce-tabs.woocommerce-tabs-responsive ul li {
display: inline-flex;
width: auto;
}
}

6 thoughts on “Responsive Product Data Tabs in WooCommerce

  1. Hey Tim

    I am trying to get this going cause it sure looks promising. I have added php to functions and css to child theme. When inspecting, I don’t think I see the responsive class, but not sure and not a champ at inspecting. I use Twenty Twenty Four theme.

    I have purged all after saving code, and I do not see any change on mobile for the tabs, so what did I do wrong? I am wondering if Woo changed things since your code? Maybe for block editor and blocks…

    Since I haven’t seen this in action yet, I assume I could apply the accordions to also large screens. I just tired of the tabs, that’s all.

    Thanks for your efforts here. Very inspiring and I really hope to get it working. Looking forward for your reply.

    Henrik

    1. Hi Henrik,
      This code is a few of years old now, and untested with recent versions of woocommerce, so it could be that the markup has changed in recent versions. I haven’t worked on any woocommerce projects recently, so I haven’t checked. If I get some time I’ll spin up a new woocommerce site and test if it works. I might not be quick enough to help you with your problem though.

      I agree I don’t like the tabs, on the default template, and wish they would implement a different ui.
      Thanks for reading.
      Tim

      1. Thanks Tim

        Can I add the php code to functions.php? And then it should do it’s thing? I am guessing it should work, though woo is introducing blocks and then tabs in a block. But they still look equally ugly, and all css I came across seems to work on same classes. Including yours above, but not for mobile. I will wait and see what you come up with, but just let me know on the functions question. That’s where I have the code now. If it does not work, maybe rewrite so that it does work from functions and people can stay out of core plugin…

        Thx for your efforts

        1. The php code is a woocommerce template override, so it should live in your theme folder. Following the woocommerce rules, that means all the php code above should be placed in to a file:
          wp-content/themes/<YOUR-THEME>/woocommerce/single-product/tabs/tabs.php
          Then woocommerce should see the template override and use that file instead of the default.
          The CSS should be loaded in your theme CSS file.

          1. Hey Tim

            Everything works. It’s beautiful. This is just so awesome. Can you confirm that it will not overwrite, when my theme updates? I guess I will need to recreate the folders and file inside a new theme if switching….

            Finally: I have background color on my active tab. That color continues as background behind content container. How can I differentiate in css and only have the header bar colored? And why does it do this? As tabs old style it works fine as intended. You can check from mobile here: https://svalinnart.com/product/italian-girl-in-denmark/

            Also text get’s the tab colours applied. When changing content background back to none, the text will be white on white…. So I guess the style hooks needs better specification in your css.

            I would like to test this full width for all screens. How do I alter the “@media screen” snippets to work everywhere? Is there a min width function in CS3?

            If you happen to know… Inside “Additional Info” there is a table defined. I want it to not alternate background and have no cell borders. Do you know how?

            Here is my other tab styling in case this is where I need to change things:

            /*** Single Product Page – Tab Styles ***/
            .woocommerce div.product .woocommerce-tabs ul.tabs li::before,
            .woocommerce div.product .woocommerce-tabs ul.tabs li::after,
            .woocommerce div.product .woocommerce-tabs ul.tabs::before {
            display:none;
            }

            /*** All Tabs ***/
            .woocommerce div.product .woocommerce-tabs ul.tabs li {
            border-radius:0;
            background:transparent;
            border: 0;

            }

            /*** Active Tab ***/
            .woocommerce div.product .woocommerce-tabs ul.tabs li.active {
            background:#B1C5A4;
            color:#fff;
            }

            /*.woocommerce div.product .woocommerce-tabs ul.tabs li {
            background:transparent;
            border: 0;

            a {
            padding: 1rem;
            }
            }*/

            .woocommerce div.product .woocommerce-tabs ul.tabs {
            padding:0;
            }

            .woocommerce div.product .woocommerce-tabs ul.tabs
            {
            border-bottom: 1px solid #636363;
            }

            Thx Henrik

          2. Hey Tim

            I see two issues since introducing this code:

            1) Accordion works on mobile. My tabs background are green with white text. That is also applied to tabs content. How can i avoid that? See this on mob: https://svalinnart.com/product/visage/

            2) Since introducing this code, first tab “description” is not open on load both computer and mob. How can I change this for computer, so that it starts open.

            3) How can I test accordion on large screen? Do I just remove the small screen passage?

            Thx

Leave a Reply

Your email address will not be published. Required fields are marked *