5

I need to have different layouts for a dashboard. I need only horizontal scroll for layout-container if the items exceed to fit in a visible viewport. I came across a layout with the following requirements.

This is the layout I required

I have created the layout style using CSS-flexbox, but could not get the horizontal scroll, got the vertical scroll only.

html,
body {
  height: 100%;
  margin: 0px;
}
* {
  box-sizing: border-box;
}
.flexbox {
  height: 100%;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  overflow-x: auto;
  background-color: lightgreen;
}
.item {
  min-width: 50%;
  min-height: 50%;
  flex: 1 0 0;
  border: 1px solid;
}
.item:nth-child(odd) {
  background-color: lightblue;
}

.item:nth-child(even) {
  background-color: lightslategray;
}
.item1 {
  min-width: 100%;
}
<div class="flexbox">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item1">4</div>
  <div class="item item2">5</div>
  <div class="item item3">6</div>
</div>

https://codepen.io/TechnoGeek/pen/GdZodo

So, I thought, CSS grid can help with this. So I tried something but did not understand how to get it.

html,
body {
  height: 100%;
  margin: 0px;
}

.grid {
  display: grid;
  height: 100%;
  background-color: lightgreen;
  grid-template-columns: repeat(2, 1fr);
  grid-template-row: repeat(2, 1fr);
  grid-gap: 5px;
  /*   grid-auto-flow: column; */
}

.item {
  border: 1px solid;
}

.item:nth-child(odd) {
  background-color: lightblue;
}

.item:nth-child(even) {
  background-color: lightslategray;
}

.item1 {
  grid-column: 1/3;
}
<div class="grid">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item1">4</div>
  <div class="item item2">5</div>
  <div class="item item3">6</div>
</div>

https://codepen.io/TechnoGeek/pen/BxKoaG

In the grid layout, items are shrinking to fit within the layout.

The number of items inside the container is dynamic. Irrespective of the item count the layout must maintain the structure for each visible group.

Can someone help how to achieve this?

Thanks in advance.

4
  • try overflow-x:scroll...may it helps Commented Apr 24, 2018 at 10:24
  • it is not working, can you check the code pens once? Commented Apr 24, 2018 at 10:25
  • for horizontal scroll,you need to add any specific width to the parent div. Commented Apr 24, 2018 at 10:31
  • @KhushbuVaghela, I have inserted code snippets in the question. I have added what you said. It is no use. I guess you are addressing container with display: block but I am using display: flex or grid; If I did not understand what you said, can you send the code snippet? Commented Apr 24, 2018 at 10:41

4 Answers 4

13

I found a satisfactory answer using CSS Grid layout.

In the grid layout, items are shrinking to fit within the layout.

I have defined the grid lines using fr in my question that is why the items are shrinking. Now I have used % because I want the cell items to flow out of visible area to produce scroll if needed.

and span keyword in defining grid cell areas helped a lot for auto placement of grid cells.

From MDN: span && [ <integer> || <custom-ident> ]

Contributes a grid span to the grid item’s placement such that the corresponding edge of the grid item’s grid area is n lines from the opposite edge.

html,
body {
  height: 100%;
  margin: 0px;
}

.grid {
  display: grid;
  height: 100%;
  background-color: lightgreen;
  grid-template-columns: repeat(2, 50%);
  grid-template-rows: repeat(2, 50%);
  /*grid-gap: 5px;*/
  grid-auto-columns: 50%;
  grid-auto-flow: column;
}

.item {
  border: 1px solid;
  grid-area: span 1 / span 1;
}

.item:nth-child(odd) {
  background-color: lightblue;
}

.item:nth-child(even) {
  background-color: lightslategray;
}

.item1 {
  grid-area: span 1/ span 2;
}
<div class="grid">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
  <div class="item item1">4</div>
  <div class="item item2">5</div>
  <div class="item item3">6</div>
</div>

Sign up to request clarification or add additional context in comments.

Comments

0

For horizontal scroll the simplest solution would be to create a separate container for each view. Then make the overall container (body) a flex container in row direction.

body {
  display: flex;
  margin: 0;
}

.flexbox {
  flex: 0 0 100vw;
  height: 100vh;
  display: flex;
  flex-wrap: wrap;
  background-color: lightgreen;
}

.item {
  flex: 1 0 50%;
  min-height: 50%;
  border: 1px solid;
}

.item1 {
  flex-basis: 100%;
}

.item:nth-child(odd) {
  background-color: lightblue;
}

.item:nth-child(even) {
  background-color: lightslategray;
}

* {
  box-sizing: border-box;
}
<div class="flexbox">
  <div class="item item1">1</div>
  <div class="item item2">2</div>
  <div class="item item3">3</div>
</div>
<div class="flexbox">
  <div class="item item1">4</div>
  <div class="item item2">5</div>
  <div class="item item3">6</div>
</div>

3 Comments

Hi Michael, My earlier approach was the same as mentioned now. The items count is dynamic and I am using angular ng-repeat to render the HTML for all components. So this approach giving some performance issues because of some other functionalities which must work with the layouts. Can you help me with the CSS Grid approach?
My approach with CSS Grid would be similar to flex. I'm not entirely clear on the problem. Maybe you could provide more details.
You see the image in my question,I have updated it, right! At first items[1,2,3] will be displayed in the viewport, where item[1] will occupy 100% width and others will occupy only 50% width. When I scroll, items[4,5,6] will come into view from rtl fashion(To achieve this, I need horizontal scroll). I get an array of items like, items = [1,2,3,4,5,6]. And I use angular 1. So, I render the Html content like <div class="flexbox"> <div class="item" ng-class="item.class" ng-repeat="item in items">{{item.text}}</div> </div>` . So I can not have separate container for each view.
0

The main trick is to add grid-auto-flow: column; to your container's display grid css styles.

For Example

.container-grid {
  display: grid;
  grid-gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 20rem));
  grid-auto-flow: column;
  overflow-x: auto;
}

Comments

-2

try to add class with this style to the element that you want to have horizontal scroll on it

display: block;
width: 99%;
overflow-x: auto;

1 Comment

I am asking for display: flex; or display: grid;, I knew what you said will work. But, I want to maintain the layout also with items inside the container. Did you check the code pens?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.