Ahmad Reza
Ahmad Reza

Reputation: 913

horizontal layout when scroll

I want to have a horizontal layout in my page ... whenever user scrolls the page instead of top-to-bottom layout I want to have left-to-right layout ... with my code on big screens there is empty space after last section and on small screens last section won't appear.

calcBodyHeight();

function calcBodyHeight() {
  const sections = document.querySelectorAll('.section');
  let height = null;
  sections.forEach(section => {
    height += section.offsetWidth;
  })
  document.body.style.height = `${height}px`;
}
const container = document.querySelector('.container');
window.addEventListener('scroll', e => {
  const scroll = window.scrollY;
  container.style.left = `-${scroll}px`;
});
html,
body {
  height: 100%;
}

body {
  overflow-x: hidden;
  overflow-y: auto;
}

.container {
  width: fit-content;
  height: 100vh;
  display: flex;
  position: fixed;
  left: 0;
  top: 0;
}

.container .section {
  width: 100vw;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container .section:nth-child(1) {
  background-color: cornflowerblue;
}

.container .section:nth-child(2) {
  background-color: coral;
}

.container .section:nth-child(3) {
  background-color: lightgreen;
}

.container .section:nth-child(4) {
  background-color: teal;
}
<div class="container">
  <div class="section"></div>
  <div class="section"></div>
  <div class="section"></div>
  <div class="section"></div>
</div>

Upvotes: 5

Views: 187

Answers (2)

Mosh Feu
Mosh Feu

Reputation: 29337

The problem is that the initial height is missing from the calculation.

Let's take an example:

body.height: 800
body.width: 400

After calcBodyHeight, body height is 1600px (400 * 4) which means we need to have 1200px to scroll (the first 400px already presented). But, since body.height is 800px this leaves us with only 800ox to scroll.

My suggestion is to calculate a bit different

  1. Set the body height as section.length * section.height
  2. Get the window ratio (width / height)
  3. On scroll, scroll according the ratio
calcBodyHeight();
function calcBodyHeight() {
  const height = [...document.querySelectorAll('.section')]
    .reduce((prev, curr) => prev + curr.offsetHeight, 0);
  document.body.style.height = `${height}px`;
}

const container = document.querySelector('.container');
const ratio = window.innerWidth / window.innerHeight;
window.addEventListener('scroll', e => {
  const scroll = window.scrollY * ratio;
  container.style.left = `-${scroll}px`;
});

Demo

calcBodyHeight();
function calcBodyHeight() {
  const height = [...document.querySelectorAll('.section')]
    .reduce((prev, curr) => prev + curr.offsetHeight, 0);
  document.body.style.height = `${height}px`;
}

const container = document.querySelector('.container');
const ratio = window.innerWidth / window.innerHeight;
window.addEventListener('scroll', e => {
  const scroll = window.scrollY * ratio;
  container.style.left = `-${scroll}px`;
});
html,
body {
  height: 100%;
}

body {
  overflow-x: hidden;
  overflow-y: auto;
}

.container {
  width: fit-content;
  height: 100vh;
  display: flex;
  position: fixed;
  left: 0;
  top: 0;
}

.container .section {
  width: 100vw;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.container .section:nth-child(1) {
  background-color: cornflowerblue;
}

.container .section:nth-child(2) {
  background-color: coral;
}

.container .section:nth-child(3) {
  background-color: lightgreen;
}

.container .section:nth-child(4) {
  background-color: teal;
}
<div class="container">
  <div class="section"></div>
  <div class="section"></div>
  <div class="section"></div>
  <div class="section"></div>
</div>

Upvotes: 1

koder613
koder613

Reputation: 1596

Using pure CSS, we can create a container with items within the container. Then rotate the container 90 degrees anti-clockwise and rotate the items 90 degrees clockwise to be the right way up.

.horizontal{
  position:absolute;
  top:0;
  left:0;
  width: 200px;
  height: 500px;
  overflow-y: auto;
  overflow-x: hidden;
  transform: rotate(-90deg);
  transform-origin: right top;
}

.horizontal > div {
  width: 150px;
  height: 150px;
  transform: rotate(90deg);
  transform-origin: right top;
  background: green;
  border: 1px solid black;
}
<div class="horizontal">

  <div>Item 1</div>
  <div>Item 2</div>
  <div>Item 3</div>
  <div>Item 4</div>
  <div>Item 5</div>
  <div>Item 6</div>
  <div>Item 7</div>
  <div>Item 8</div>
 
</div>

Upvotes: 0

Related Questions