horizontal scroll for varying amounts of div columns within an element

Viewed 110

I have several columns floated within a container. The container width is responsive (100%), and will be different widths based on users window sizes. When the columns cannot fit within the containers, I want it to automatically go into a horizontal scroll. I would have thought my styling would have achieved this, but it doesnt work. In the example I showed 9 columns, but based on various scenarios there may be different numbers from 3-15. There is also a preloader within there too. The children elements cannot be in-line block, or have overflow hidden.

#container {
  overflow-x: scroll;
  position: relative;
  white-space: nowrap;
  width: 100%;
}

.column {
  float: left;
  width: 300px;
}

#preloader {
  display: none;
  height: 100%;
  width: 100%
}

.clr {
  clear: both;
}
<div id="container">
  <div id="preloader"></div>
  <div id="columns">
    <div class="column">1</div>
    <div class="column">2</div>
    <div class="column">3</div>
    <div class="column">4</div>
    <div class="column">5</div>
    <div class="column">6</div>
    <div class="column">7</div>
    <div class="column">8</div>
    <div class="column">9</div>
    <div class="clr"></div>
  </div>
</div>

How can I make this work smoothly and seamlessly?

2 Answers

the div elements is block element so you need to convert it to inline or inline-block elements

A block-level element always starts on a new line and takes up the full width available (stretches out to the left and right as far as it can).

  • Just add display:inline-block to .column

Your Code must be like :

#container {
  overflow-x: scroll; 
  white-space: nowrap; 
  width: 100%; 
}

.column { 
  display: inline-block;
   width: 300px; 
}

#preloader {
  display: none;
  height: 100%;
  width: 100%
}

.clr {
  clear: both;
}
<div id="container">
  <div id="preloader"></div>
  <div id="columns">
    <div class="column">1</div>
    <div class="column">2</div>
    <div class="column">3</div>
    <div class="column">4</div>
    <div class="column">5</div>
    <div class="column">6</div>
    <div class="column">7</div>
    <div class="column">8</div>
    <div class="column">9</div>
    <div class="column">2</div>
    <div class="column">3</div>
    <div class="column">4</div>
    <div class="column">5</div>
    <div class="column">6</div>
    <div class="column">7</div>
    <div class="column">8</div>
    <div class="column">9</div>
    <div class="clr"></div>
  </div>
</div>

The problem is that float is wrapping the elements automatically once the hit the end of their parent element. On the other side, your div#columns will grows to max the width of your div#container (so the total screen width).

To resolve this, you have to assign your div#columns a width. Below a small example on how to do that dynamically by calculating the total width of the div.colum it contains.

var sum = 0;
$(".column").each(function(){sum += $(this).width()});
$("#columns").css('width', sum);
#container {
  overflow-x: scroll;
  position: relative;
  white-space: nowrap;
  width: 100%;
}

.column {
  float: left;
  width: 300px;
}

#preloader {
  display: none;
  height: 100%;
  width: 100%
}

.clr {
  clear: both;
}

   
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div id="container">
  <div id="preloader"></div>
  <div id="columns">
    <div class="column">1</div>
    <div class="column">2</div>
    <div class="column">3</div>
    <div class="column">4</div>
    <div class="column">5</div>
    <div class="column">6</div>
    <div class="column">7</div>
    <div class="column">8</div>
    <div class="column">9</div>
    <div class="clr"></div>
  </div>
</div>

This solution is based on this SO post and uses jQuery to calculate the total width of the elements, but you could do it as well with plain javascript.

Related