Tabbed Product description snippet for Shopify
{% comment %} | |
if combine_pretext is false, the text before the first <h6> will be shown above all tabs, otherwise added to the first tab | |
{% endcomment %} | |
{% assign combine_pretext = false %} | |
{% assign description = tabbed-description | default: product.description %} | |
{% if description contains "<h6>" %} | |
{% assign tab_heads = '' %} | |
{% assign tab_texts = '' %} | |
{% assign pretext = '' %} | |
{% assign chunks = description | strip | split: "<h6>" %} | |
{% for c in chunks %} | |
{% if c contains "</h6>" %} | |
{% assign chunk = c | split: "</h6>" %} | |
{% assign tab_heads = tab_heads | append: ",," | append: chunk.first %} | |
{% assign tab_texts = tab_texts | append: ",," %} | |
{% if pretext != blank and combine_pretext %} | |
{% assign tab_texts = tab_texts | append: pretext | append: "<br>" %} | |
{% assign pretext = '' %} | |
{% endif %} | |
{% assign tab_texts = tab_texts | append: chunk.last %} | |
{% elsif forloop.first %} | |
{% assign pretext = c %} | |
{% endif %} | |
{% endfor %} | |
{% assign tab_heads = tab_heads | remove_first: ",," | split: ",," %} | |
{% assign tab_texts = tab_texts | remove_first: ",," | split: ",," %} | |
{% assign index = 1 %} | |
<div> | |
{% if pretext != blank and combine_pretext == false %} | |
<span class=pretext>{{ pretext }}</span> | |
{% endif %} | |
<ul class="tabs"> | |
{% for head in tab_heads %} | |
<li><a href="#tab-{{- index -}}">{{ head }}</a></li> | |
{% assign index = index | plus: 1 %} | |
{% endfor %} | |
</ul> | |
{% assign index = 1 %} | |
{% for text in tab_texts %} | |
<div id="tab-{{- index -}}">{{ text }}</div> | |
{% assign index = index | plus: 1 %} | |
{% endfor %} | |
</div> | |
<script> | |
document.addEventListener( 'DOMContentLoaded', function () { | |
function findTabContent( link ){ | |
if( link && link.nodeName == "A" ){ | |
var contentID = link.attributes.href.value.replace('#',''); | |
return document.getElementById( contentID ); | |
} | |
else | |
return null; | |
} | |
function hide( element ){ | |
if( element ) | |
element.style.display="none"; | |
} | |
function show( element ){ | |
if( element ) | |
element.style.display=""; | |
} | |
function setActive( element ){ | |
if( element ){ | |
element.classList.add('active'); | |
var c = findTabContent( element ); | |
show(c); | |
} | |
} | |
var tabHeads = Array.from( document.getElementsByClassName('tabs') ); | |
tabHeads.forEach( function( tablist ){ | |
var links = document.querySelectorAll('.tabs a'), | |
tabs = document.querySelectorAll('.tabs li'); | |
if( links.length == 0 ) | |
return; | |
var active = links[0], | |
content = findTabContent( active ), | |
totalWidth = 0, currentMode; | |
setActive( active ); | |
links.forEach( function( el, index ){ | |
if( index > 0 ) | |
hide( findTabContent( el ) ); | |
}); | |
/* event listener for clicking tabs */ | |
tablist.addEventListener( 'click', function(e){ | |
var clicked = e.target; | |
if( clicked.nodeName !== "A" ) | |
return; | |
e.preventDefault(); | |
active.classList.remove('active'); | |
hide( content ); | |
active = clicked; | |
content = findTabContent( clicked ); | |
setActive( clicked ); | |
return false; | |
}); | |
function onResize( e ){ | |
if( e.type == 'load' ){ | |
/* how wide are all our tab headers together? calculate this once, on load */ | |
tabs.forEach( function( el, i ) { | |
totalWidth += el.offsetWidth ; | |
}); | |
} | |
/* will they fit on one line? check on every resize/rotate */ | |
if( tablist.clientWidth > totalWidth ){ | |
if( currentMode !== 'wide' ) { | |
tablist.classList.remove('vertical'); | |
currentMode = 'wide'; | |
} | |
} else{ | |
if( currentMode !== 'narrow' ) { | |
tablist.classList.add('vertical'); | |
currentMode = 'narrow'; | |
} | |
} | |
} | |
window.addEventListener( 'resize', onResize ); | |
window.addEventListener( 'load', onResize ); | |
}); | |
}); | |
</script> | |
<style> | |
ul.tabs { | |
border-bottom: 1px solid #DDDDDD; | |
display: block; | |
margin: 0 0 20px; | |
padding: 0; | |
} | |
ul.tabs li { | |
display: block; | |
float: left; | |
height: 30px; | |
margin-bottom: 0; | |
padding: 0; | |
width: auto; | |
} | |
ul.tabs li a { | |
-moz-border-bottom-colors: none; | |
-moz-border-image: none; | |
-moz-border-left-colors: none; | |
-moz-border-right-colors: none; | |
-moz-border-top-colors: none; | |
background: none repeat scroll 0 0 #F5F5F5; | |
border-color: #DDDDDD !important; | |
border-style: solid; | |
border-width: 1px 1px 0 1px; | |
display: block; | |
font-size: 13px; | |
height: 29px; | |
line-height: 30px; | |
margin: 0; | |
padding: 0 20px; | |
text-decoration: none; | |
width: auto; | |
color: #303030; | |
border-bottom:none !important; | |
} | |
ul.tabs li a.active { | |
background: none repeat scroll 0 0 #FFFFFF; | |
border-left-width: 1px; | |
border-top-left-radius: 2px; | |
border-top-right-radius: 2px; | |
color: #111111; | |
height: 30px; | |
margin: 0 0 0 -1px; | |
padding-top: 4px; | |
position: relative; | |
top: -4px; | |
} | |
ul.tabs li:first-child a.active { | |
margin-left: 0; | |
} | |
ul.tabs li:first-child a { | |
border-top-left-radius: 2px; | |
border-width: 1px 1px 0; | |
} | |
ul.tabs li:last-child a { | |
border-top-right-radius: 2px; | |
} | |
ul.tabs:before, ul.tabs:after { | |
content: " "; | |
display: block; | |
height: 0; | |
overflow: hidden; | |
visibility: hidden; | |
width: 0; | |
} | |
ul.tabs:after { | |
clear: both; | |
} | |
/* update for better mobile look */ | |
ul.tabs.vertical> li { | |
width: 100%; | |
} | |
</style> | |
{% else %} | |
{{ description }} | |
{% endif %} |
This comment has been minimized.
This comment has been minimized.
Would be amazing to have a Vanilla JS version of this. Shopify's putting a lot of emphasis on page speed, jQuery has fallen out of favor. |
This comment has been minimized.
This comment has been minimized.
Vanilla JS version is here :) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.
Hello,
I am using this code for my shop - works great.
However, when I am changing the styling, e.g. background color when tab active from #FFFFFF to #ff0266 for example, nothing changes.
It seems like something is overwriting my styling - how can I fix this?
Best,
OKAY