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.
*
* @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;
}
}