Custom CSS and JavaScript:
Limitation: Requires advanced coding knowledge and might affect performance.
Steps:
Create multiple sections with your desired content.
Use CSS to style them as a horizontal container.
Implement JavaScript to handle scrolling behavior.
<style>
/* Horizontal Scroll */
.mdw-horizontal-scroll{
--progress-bar: true;
--progress-bar-color: #FFFF00;
--progress-bar-height: 2px;
}
body{
--disable-movement-desktop: false;
--disable-movement-tablet: false;
--disable-movement-mobile: true;
--hide-default-scrollbar: false;
--disable-horizontal-scroll-mobile: false;
}
html.hide-scrollbar::-webkit-scrollbar{
display: none;
}
html.hide-scrollbar{
-ms-overflow-style: none;
scrollbar-width: none;
}
.mdw-horizontal-scroll{
overflow: hidden;
--initial-height: var(--min-height,100vh);
}
.mdw-horizontal-scroll:after{
content: "";
left: 0;
top: calc(100vh - var(--progress-bar-height,2px));
width: 100vw;
height: var(--progress-bar-height,2px);
background: var(--progress-bar-color,FFFF00);
transform: scaleX(calc(var(--progress,0)*100%));
position: fixed;
transform-origin: left;
will-change: transform;
transition: transform 0.1s linear;
opacity: 0;
}
.mdw-horizontal-scroll.fixed:after{
opacity: 1;
}
.mdw-horizontal-scroll.progress-bar-disabled:after{
display: none;
}
.mdw-horizontal-scroll > .e-con,
.mdw-horizontal-scroll > .e-container{
transition: none;
height: var(--initial-height,100vh);
}
body.tiny-scroll .mdw-horizontal-scroll > .e-con,
body.tiny-scroll .mdw-horizontal-scroll > .e-container{
will-change: transform;
transition: transform 1s cubic-bezier(0,.33,.07,1.03);
}
.mdw-horizontal-scroll.fixed > .e-con,
.mdw-horizontal-scroll.fixed > .e-container{
position: fixed;
top: 0;
left: 0;
}
.mdw-horizontal-scroll.bottom{
justify-content: flex-end;
}
.mdw-horizontal-scroll > .e-con > *,
.mdw-horizontal-scroll > .e-container > *{
height: var(--min-height, 100vh);
}
.mdw-horizontal-scroll.hs-disabled{
height: auto !important;
}
.mdw-horizontal-scroll.hs-disabled:after{
display: none;
}
.mdw-horizontal-scroll.hs-disabled > .e-con,
.mdw-horizontal-scroll.hs-disabled > .e-container{
flex-direction: column;
height: auto;
}
.mdw-horizontal-scroll.hs-disabled.fixed > .e-con,
.mdw-horizontal-scroll.hs-disabled.fixed > .e-container{
position: relative;
}
.mdw-horizontal-scroll.hs-disabled > .e-con > *,
.mdw-horizontal-scroll.hs-disabled > .e-container > *{
height: auto;
}
.mdw-horizontal-scroll.hs-disabled > .e-con > .e-con,
.mdw-horizontal-scroll.hs-disabled > .e-container > .e-container{
width: 100%;
}
/* Scrolling Movement */
.e-con[class^='mdw-hs-movement'],
.e-con[class*=' mdw-hs-movement'],
.e-container[class^='mdw-hs-movement'],
.e-container[class*=' mdw-hs-movement'],
.elementor-widget[class^='mdw-hs-movement'] .elementor-widget-container,
.elementor-widget[class*=' mdw-hs-movement'] .elementor-widget-container{
transform: translateX(calc(var(--e-transform-translateX,0px) + var(--translateX,0)*-1px)) translateY(calc(var(--e-transform-translateY,0px) + var(--translateY,0)*1px)) rotate(calc(var(--rotateZ,0deg) + var(--rotate,0)*1deg));
transition: none;
}
body.tiny-scroll .e-con[class^='mdw-hs-movement'],
body.tiny-scroll .e-con[class*=' mdw-hs-movement'],
body.tiny-scroll .e-container[class^='mdw-hs-movement'],
body.tiny-scroll .e-container[class*=' mdw-hs-movement'],
body.tiny-scroll .elementor-widget[class^='mdw-hs-movement'] .elementor-widget-container,
body.tiny-scroll .elementor-widget[class*=' mdw-hs-movement'] .elementor-widget-container{
will-change: transform;
transition: transform 1s cubic-bezier(0,.33,.07,1.03);
}
.e-con[class^='mdw-hs-movement-translate-x'],
.e-con[class*=' mdw-hs-movement-translate-x'],
.e-container[class^='mdw-hs-movement-translate-x'],
.e-container[class*=' mdw-hs-movement-translate-x'],
.elementor-widget[class^='mdw-hs-movement-translate-x'] .elementor-widget-container,
.elementor-widget[class*=' mdw-hs-movement-translate-x'] .elementor-widget-container{
--translateX: calc(var(--parallax,0)*var(--speed-x,10)*var(--direction-x,1));
}
.e-con[class^='mdw-hs-movement-translate-y'],
.e-con[class*=' mdw-hs-movement-translate-y'],
.e-container[class^='mdw-hs-movement-translate-y'],
.e-container[class*=' mdw-hs-movement-translate-y'],
.elementor-widget[class^='mdw-hs-movement-translate-y'] .elementor-widget-container,
.elementor-widget[class*=' mdw-hs-movement-translate-y'] .elementor-widget-container{
--translateY: calc(var(--parallax,0)*var(--speed-y,10)*var(--direction-y,1));
}
.e-con[class^='mdw-hs-movement-rotate'],
.e-con[class*=' mdw-hs-movement-rotate'],
.e-container[class^='mdw-hs-movement-rotate'],
.e-container[class*=' mdw-hs-movement-rotate'],
.elementor-widget[class^='mdw-hs-movement-rotate'] .elementor-widget-container,
.elementor-widget[class*=' mdw-hs-movement-rotate'] .elementor-widget-container{
--rotate: calc(var(--parallax,0)*var(--speed-r,10)*var(--direction-r,1));
}
/* Reveal Animtion */
.mdw-reveal-animation,
.mdw-reveal-animation-left,
.mdw-reveal-animation-right,
.mdw-reveal-animation-top,
.mdw-reveal-animation-bottom{
animation: none !important;
transition: all 1s ease-in-out !important;
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
.mdw-reveal-animation:not(.animated),
.mdw-reveal-animation-left:not(.animated),
.mdw-reveal-animation-right:not(.animated),
.mdw-reveal-animation-top:not(.animated),
.mdw-reveal-animation-bottom:not(.animated){
opacity: 0;
}
.mdw-reveal-animation:not(.animated),
.mdw-reveal-animation-bottom:not(.animated){
transform: translateY(2em);
clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0% 100%);
}
.mdw-reveal-animation-left:not(.animated){
transform: translateX(-2em);
clip-path: polygon(0 0, 0 0, 0 100%, 0% 100%);
}
.mdw-reveal-animation-right:not(.animated){
transform: translateX(2em);
clip-path: polygon(100% 0, 100% 0, 100% 100%, 100% 100%);
}
.mdw-reveal-animation-top:not(.animated){
transform: translateY(-2em);
clip-path: polygon(0 0, 100% 0, 100% 0, 0 0);
}
/* For Mobile Devices */
@media (max-width: 767px){
.mdw-horizontal-scroll > .e-con,
.mdw-horizontal-scroll > .e-container{
transition: transform 0.1s linear;
}
}
</style>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
if(!MDWNonce109){
var MDWNonce109 = true
;(function($){
function init(){
$('body').append('<div class="mdw-100vh" style="height: 100vh;display: none;"></div>')
if($('body').css('--hide-default-scrollbar') && $('body').css('--hide-default-scrollbar').trim() == 'true'){
$('html').addClass('hide-scrollbar')
}
}
function getValue(text, defaultValue){
return (text.match(/\d+/) ? text.match(/\d+/)[0] : defaultValue)/100
}
function getDirection(text){
return text.search('reverse') > -1 ? -1 : 1
}
function horizontalScroll(scroll, windowWidth, windowHeight, disableMobile){
$('.mdw-horizontal-scroll').each(function(){
var $this = $(this),
container = $this.find('.e-con, .e-container').eq(0),
containerTop = $this.offset().top,
totalWidth = 0,
extraWidth = 0,
passed = scroll - containerTop,
translate = passed,
minHeight = $this.css('--min-height') ? $this.css('--min-height') : '100vh'
container.children().each(function(){
totalWidth += $(this).outerWidth() + parseFloat($(this).css('margin-left')) + parseFloat($(this).css('margin-right'))
})
if( windowWidth < 768 && disableMobile ){
totalWidth = windowWidth
$this.addClass('hs-disabled')
}else{
$this.removeClass('hs-disabled')
}
$this.attr('total-width', totalWidth)
if(totalWidth > windowWidth){
extraWidth = totalWidth - windowWidth
}
$this.height('calc(' + minHeight + ' + ' + extraWidth + 'px)')
if(passed < 0){ translate = 0 }
if(passed > extraWidth){ translate = extraWidth }
var progress = translate/extraWidth
if(progress <= 0){
$this.removeClass('fixed bottom')
}
if(progress > 0 && progress < 1){
$this.addClass('fixed')
$this.removeClass('bottom')
}
if(progress >= 1){
$this.removeClass('fixed')
$this.addClass('bottom')
}
container.css('transform', 'translateX(-' + translate + 'px)')
$this.css('--progress', progress)
if($this.css('--progress-bar') && $this.css('--progress-bar') == 'true'){
$this.removeClass('progress-bar-disabled')
}else{
$this.addClass('progress-bar-disabled')
}
})
}
var parallaxUpdate = false
function scrollMovement(scroll, windowWidth, windowHeight, disableMobile){
var enableMovement = false
if(windowWidth > 0){
enableMovement = !$('body').css('--disable-movement-mobile') || $('body').css('--disable-movement-mobile').trim() != 'true'
}
if(windowWidth > 767){
enableMovement = !$('body').css('--disable-movement-tablet') || $('body').css('--disable-movement-tablet').trim() != 'true'
}
if(windowWidth > 1024){
enableMovement = !$('body').css('--disable-movement-desktop') || $('body').css('--disable-movement-desktop').trim() != 'true'
}
if(enableMovement){
$("[class^='mdw-hs-movement'], [class*=' mdw-hs-movement']").each(function(i){
var $this = $(this),
className = $this.attr('class'),
element = $this.hasClass('elementor-widget') ? $this.find('.elementor-widget-container') : $this,
parent = element.parent(),
elementRect = element.get(0).getBoundingClientRect(),
parentRect = parent.get(0).getBoundingClientRect(),
isHorizontal = $this.closest('.mdw-horizontal-scroll').length,
offset = 100,
elementVisible = elementRect.right > -1*offset && elementRect.left - windowWidth < offset && elementRect.top - windowHeight < offset && elementRect.bottom > -1*offset,
parentVisible = parentRect.right > -1*offset && parentRect.left - windowWidth < offset && parentRect.top - windowHeight < offset && parentRect.bottom > -1*offset,
hasChild = $this.find("div[class^='mdw-hs-movement'],div[class*=' mdw-hs-movement']").length,
totalWidth = parseFloat($this.closest('.mdw-horizontal-scroll').attr('total-width')),
parallax
$this.css({
'--speed-x': 0,
'--speed-y': 0,
'--speed-r': 0
})
className.split(' ').forEach(function(c){
if(c.startsWith('mdw-hs-movement-translate-x')){
$this.css('--speed-x', getValue(c, 10))
$this.css('--direction-x', getDirection(c))
}
if(c.startsWith('mdw-hs-movement-translate-y')){
$this.css('--speed-y', getValue(c, 10))
$this.css('--direction-y', getDirection(c))
}
if(c.startsWith('mdw-hs-movement-rotate')){
$this.css('--speed-r', getValue(c, 10))
$this.css('--direction-r', getDirection(c))
}
})
if( windowWidth < 768 && disableMobile ){ isHorizontal = false }
if(isHorizontal){
var HSRect = $this.closest('.mdw-horizontal-scroll').find('.e-con, .e-container').get(0).getBoundingClientRect(),
leftPos = Math.round(elementRect.left + element.outerWidth()/2 - parseFloat(element.css('transform').split(' ')[4]) - HSRect.left)
if(leftPos < windowWidth/2 || totalWidth < windowWidth){
parallax = - HSRect.top - HSRect.left
}else if(leftPos > totalWidth - windowWidth/2){
parallax = - HSRect.top - HSRect.left - totalWidth + windowWidth
}else{
parallax = windowWidth/2 - elementRect.left - element.outerWidth()/2 - HSRect.top
}
}else{
var topPos = Math.round(elementRect.top + scroll + element.outerHeight()/2 - parseFloat(element.css('transform').split(' ')[5]))
if(topPos < windowHeight/2 || $('body').outerHeight(true) < windowHeight){
parallax = scroll
}else if(topPos > $('body').outerHeight(true) - windowHeight/2){
parallax = scroll - $('body').outerHeight(true) + windowHeight
}else{
parallax = windowHeight/2 - element.outerHeight()/2 - elementRect.top
}
}
if(parentVisible || elementVisible || hasChild || parallaxUpdate){
$(this).css('--parallax', parallax)
}
})
}else{
$("[class^='mdw-hs-movement'], [class*=' mdw-hs-movement']").css('--parallax', 0)
}
}
var currentTime, lastTime
function scrollActivity(delayCall=true){
var scroll = $(window).scrollTop(),
windowWidth = $(window).width(),
windowHeight = $('.mdw-100vh').height(),
disableMobile = $('body').css('--disable-horizontal-scroll-mobile') && $('body').css('--disable-horizontal-scroll-mobile') == 'true'
lastTime = new Date()
setTimeout(function(){
currentTime = new Date()
if(currentTime - lastTime > 200 && delayCall){
scrollActivity(false)
}
},500)
horizontalScroll(scroll, windowWidth, windowHeight, disableMobile)
scrollMovement(scroll, windowWidth, windowHeight, disableMobile)
}
function scrollToSection(){
var link = $(this).attr('href')
if( link && link != '#' && link[0] == '#' ){
var el = $('.' + link.substr(1)).eq(0),
parentHS = el.closest('.mdw-horizontal-scroll'),
disableMobile = $('body').css('--disable-horizontal-scroll-mobile') && $('body').css('--disable-horizontal-scroll-mobile') == 'true'
if(parentHS.length){
var scrollAmount = parentHS.offset().top + el.offset().left - parentHS.find('.e-con, .e-container').eq(0).offset().left
if($(window).width() < 768 && disableMobile){
scrollAmount = el.offset().top
}
$('html, body').stop().animate({scrollTop:scrollAmount}, 300, 'linear')
}
}
}
$(document).ready(function(){
init()
scrollActivity()
$('body').on('click', 'a', scrollToSection)
})
function runParallax(){
if(parallaxUpdate) return
parallaxUpdate = true
setTimeout(function(){
parallaxUpdate = false
},1000)
var repeatParallax = setInterval(function(){
if(parallaxUpdate){
scrollActivity()
}else{
clearInterval(repeatParallax)
}
},100)
}
var currentIsTrackpad,
previosIsTrackpad
function detectScrollResolution(e){
if(e.wheelDeltaY !== undefined && e.deltaY !== undefined){
var del = e.deltaY != 0 ? e.deltaY : 1,
delVal = Math.abs(e.wheelDeltaY/del),
currentIsTrackpad = delVal > 2.9 && delVal <= 3
if(currentIsTrackpad && previosIsTrackpad){
$('body').addClass('tiny-scroll')
}else{
$('body').removeClass('tiny-scroll')
}
previosIsTrackpad = currentIsTrackpad
}else{
$('body').removeClass('tiny-scroll')
}
}
$(window).on('load resize', function(){
runParallax()
setTimeout(runParallax, 1000+100)
})
$(window).on('load resize scroll', scrollActivity)
window.addEventListener('mousewheel', detectScrollResolution)
$('body').on('keydown', function(e) {
if (e.key == " " || e.code == "Space" || e.keyCode == 32){
$('body').removeClass('tiny-scroll')
}
})
$('body').on('click', function(){
$('body').removeClass('tiny-scroll')
})
})(jQuery)
}
</script>