Im using the following tabs and would like to be able to swipe through them on mobile.
By swiping the content of an active tab.
Also, is it possible to add a smooth-scroll effect that after swiping the viewport stops exactly on a tab, instead of somewhere in between?
const btn = [].slice.call(document.getElementsByTagName('button'))
btn.forEach((item, index) => {
item.addEventListener('click',function(){
btn.forEach((item) => {item.classList.remove('active')})
item.classList.add('active')
document.getElementById('tab').setAttribute('data-tab', index)
})
}
)
.wrapper {
overflow: hidden;
}
.tabs {
position: relative;
-webkit-transition: all .9s ease-in-out;
-moz-transition: all .9s ease-in-out;
-ms-transition: all .9s ease-in-out;
-o-transition: all .9s ease-in-out;
transition: all .9s ease-in-out;
}
.tabs> * {
width: 100%;
}
.tabs[data-tab='1'] {
transform: translateX(-100%);
}
.tabs[data-tab='2'] {
transform: translateX(-200%);
}
.tabs[data-tab='3'] {
transform: translateX(-300%);
}
.tabs[data-tab='4'] {
transform: translateX(-400%);
}
.inliner {
white-space: nowrap;
}
.inliner > * {
display: inline-block;
*display: inline;
*zoom: 1;
font-size: 1rem;
letter-spacing: normal;
vertical-align: top;
word-spacing: normal;
white-space: normal;
}
<div >
<button> Tab 1</button>
<button> Tab 2</button>
<button> Tab 3</button>
<div id="tab" >
<div>
<h2>Content 1</h2>
</div>
<div>
<h2>Content 2</h2>
</div>
<div>
<h2>Content 3</h2>
</div>
</div>
</div>
I read about making a div fully responsive / touchable on mobile but didnt really understand a thing and im not able to reproduce it for my tabs. Same goes for smooth-scrolling.
Any help is much appreciated
CodePudding user response:
First give the parent div following rules.
#tab {
display: flex;
overflow: auto;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
scroll-snap-type make it mandatory for one of the tabs to be always on the viewport.
Now give all of the children following rules.
#tab > * {
flex-shrink: 0;
width: 100%;
scroll-snap-align: start;
scroll-margin-top: 1rem;
padding: 1rem 0.4rem;
}
flex-shrink: 0 will change the default behavior of a flex child and stop it from shrinking. scroll-snap-align tells the child where to align the scrolling behavior. scroll-margin-top will maintain a margin on top while scrolling.
Now a bit of changes in the js.
const btn = [].slice.call(document.getElementsByTagName("button"));
btn.forEach((item, index) => {
item.addEventListener("click", function () {
document.getElementById("tab").children[index].scrollIntoView();
});
});
scrollIntoView() scrolls any element to the viewport if not already into it.
This way you can also perform touch scroll on mobile. Now combining all the spells you get what you asked.
const btn = [].slice.call(document.getElementsByTagName("button"));
btn.forEach((item, index) => {
item.addEventListener("click", function () {
document.getElementById("tab").children[index].scrollIntoView();
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#tab {
display: flex;
overflow: auto;
scroll-behavior: smooth;
scroll-snap-type: x mandatory;
}
#tab > * {
flex-shrink: 0;
width: 100%;
scroll-snap-align: start;
scroll-margin-top: 1rem;
padding: 1rem 0.4rem;
}
<div >
<button>Tab 1</button>
<button>Tab 2</button>
<button>Tab 3</button>
<div id="tab" >
<div>
<h2>Content 1</h2>
</div>
<div>
<h2>Content 2</h2>
</div>
<div>
<h2>Content 3</h2>
</div>
</div>
</div>