Horizontal scroll not working as expected - html

Hello I am trying to implement horizontal scrolling (using scroll bars)but I can't get it to work properly
I have 2 divs 1 for scroll and 1 main div I want to display the items on the main div but when I do that the whole div scrolls, instead of only the items. How can I get this to work?
scroll div
<div class="scrolling-wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
main div
<div class="main">
</div>
CSS
.scrolling-wrapper {
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
}
.item {
display: inline-block;
align-self: flex-start;
background-color: var(--pampas);
border-radius: 10px;
flex-shrink: 0;
height: 269px;
margin-left: 210px;
margin-top: 13px;
width: 200px;
}
.main {
align-items: center;
background-color: white;
display: flex;
flex-direction: column;
height: auto;
justify-content: flex-start;
min-height: 1080px;
padding: 26px 0;
width: 1920px;
}
Here is how it looks right now.
Thank you <3

If I understand your question correctly, you want all the items to scroll together (i.e. not each one individually) but only inside div.scrolling-wrapper which is a child of div.main.
This only works if you restrict the width of div.scrolling-wrapper.
You most likely need
.scrolling-wrapper {
width: 100%;
/* you can also use max-width instead */
}
The 100% refer to the parent's width, in this case that of div.main. This is necessary because you have display:flex set on div.main which has the effect that its child div.scrolling-wrapper gets the sum of its children' (the .items) widths as its default width.
As a sidenote: Please mind that the following rules related to flexbox that you set on .item:
align-self: flex-start;
flex-shrink: 0;
don't have any effect unless there is some rule that you didn't mention in your original post that sets .scrolling-wrapper to display:flex.

Related

Build cards in CSS

I want to build this kind of cards, that are in the same row, and which can be scroll through horizontally. Can you recommend any tool for doing so?
Cards
I'm using display:flex on my container but it doesn't do it.
You can set the overflow -x auto of the parent div container of the card, make it a flex container and flex-wrap with nowrap.
something like this
.parent-container {
display: flex;
width: 100%;
overflow-x: auto;
flex-wrap: nowrap;
}
.card-container {
min-width: 300px;
height: 380px;
background: green;
margin: 30px;
}
<div class="parent-container">
<div class="card-container"></div>
<div class="card-container"></div>
...
<div class="card-container"></div>
<div class="card-container"></div>
</div>
you can use display-flex; to parent div and with flex-direction: row;
to scroll add overflow-x: auto; scroll-behaviour: smooth; So it will adjust with you div element width;

Display:flex and scrolling inner divs

https://jsfiddle.net/wqmm0kxb/5/
html:
<div class="full">
<header><h1>header stuff</h1></header>
<section>
<div>
{lots and lots of content}
</div>
<div>b</div>
<div>c</div>
</section>
</div>
css:
.full {
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
header {
flex: 78px 0 0;
background: #ececec;
color: black;
padding-left: 33px;
}
section {
flex: auto 1 1;
display: flex;
align-items: stretch;
> div {
flex: auto 1 1;
overflow-y: auto;
}
}
}
My outer container, '.full', takes up the full width and height of the screen, and uses display:flex to make sure that the header + section children stretch to take up all the space beneath them.
Now, what I want is naturally for the header to take up 78px and the section to take up {full height - 78px} -- but without doing anything like calc preferrably. And I want to be able to scroll in the div children of section, without scrolling affecting the other divs or the page as a whole.
This works perfectly in Chrome, but open up my fiddle in firefox, edge, ie and it doesn't work as expected. Section gets the height of {lots and lots of content} rather than only taking the remaining space of '.full'
What should I do to achieve the Chrome-like layout that I'm expecting?
Apply the overflow-y:auto for your section also, that will fix the issue in IE and Firefox.
section {
flex: auto 1 1;
display: flex;
align-items: stretch;
overflow-y: auto;
> div {
flex: auto 1 1;
overflow-y: auto;
}
}
Fiddle DEMO

Horizontal Margins going outside of parent div in flexbox

I'm getting some unexpected behavior with my margins using flex and I would like some help in understanding why.
I'v got some simple html like so:
<div className="dashboard">
<div className="dashboard__inner-container">Inner Container</div>
</div>
And my scss file looks like this:
.dashboard {
text-align: center;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
flex: 1 1 auto;
background-color: #f4f6f8;
}
.dashboard__inner-container {
display: flex;
flex-direction: column;
background-color: #ffffff;
flex: 1 1 auto;
width: 100%;
margin: 100px 50px;
}
What I am expecting is that the inner container will completely fill up the parent container, minus 100px on the top and bottom and 50px on the right and left. The vertical margin works as expected, but the horizontal margin actually extends out of the parent div, so that the inner container still appears to be taking up the entire width of the parent div.
I'm not sure if this is related to flexbox or not.
Here is an isolated CodePen https://codepen.io/MaxMillington2/pen/EQWZoj
When using align-items: center with column direction, the item will collapse to its content width, instead of with its default, stretch, which makes it fill its parent's width.
Additionally, when setting width: 100% to the inner, it will override the default stretch, which will make the item be 100% of parent's width + margin.
For the expected output, remove align-items: center on the outer and width: 100% on inner.
Stack snippet
html {
height: 100%;
overflow: auto;
}
.outer {
display: flex;
justify-content: center;
flex-direction: column;
background-color: #f4f6f8;
height: 100%;
}
.inner {
display: flex;
flex-direction: column;
background-color: #ffffff;
flex: 1 1 auto;
text-align: center;
margin: 100px 80px;
}
<div class='outer'>
outer
<div class='inner'>
inner
</div>
</div>

Vertically centering with flexbox

I'm trying to center a div on a webpage using flexbox. I'm setting the following CSS properties. I see that it's being centered horizontally, but not vertically.
.flex-container {
display: flex;
align-items: center;
justify-content: center;
}
Here's the fiddle: JSFIDDLE
Can you explain what I'm doing wrong?
A <div> element without an explicit height defaults to the height of it's contents, as all block elements do. You'd probably want to set it to 100% of it's parent, the <body>, but that's not enough, since that is also a block element. So again, you need to set that to 100% height, to match it's parent, the <html>. And yet again, 100% is still required.
But once all that is done, you get that annoying vertical scroll bar. That's a result of the default margin the body has, and the way the box model is defined. You have several ways you can combat that, but the easiest is to set your margins to 0.
See corrected fiddle.
html, body {
height: 100%;
margin: 0px;
}
.flex-container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.item {
background-color: blue;
height: 50px;
width: 50px;
}
<div class="flex-container">
<div class="item">
</div>
</div>
You just need to set html, body, and your flex container to height: 100%. The reason it wasn't working is that your flex container didn't have an explicit height set, so it defaulted to the height of its contents.
Live Demo:
html, body {
height: 100%;
}
.flex-container {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.item {
background-color: blue;
height: 50px;
width: 50px;
}
<div class="flex-container">
<div class="item">
</div>
</div>
JSFiddle Version: http://jsfiddle.net/d4vkq3s7/3/

Make items to stretch inside the container with same gap

I have four items with same width. I need them to be stretched inside the fluid container. Whenever I resize the window, the gap between each item should adjust in such a way that the items are still stretching inside the container. Here is the image of what I want.
Here is the code, I have tried:
.parent {
margin-top: 40px;
background-color: beige;
}
.parent::after {
content:"";
clear: both;
display: block;
}
.child {
width: 20px;
height: 20px;
background-color: tomato;
margin-left: 20%;
float: left;
}
Fiddle
For limited known items:
Suppose, we know the number of items present in a container. Lets say the items to be 4. Lets wrap those items in separate sections each and give those sections float: left and width: 25%. Here I am giving width: 25% because there are four sections which need to cover the container completely i.e 100/4 = 25%. This will result in something similar view as shown below in the image:
As you can see in the above image, the items are still not aligned to each other. We can see gap between the last item and the container. But if you ignore the gap, you can see that the items are equally aligned to each other.
So now we should just be able to remove the width of the section holding the last item. This can be done using :last-child selection. Since, the last item holder is now hidden, we need to stretch other child holders. Hence, we need to divide 100% by 3 instead of 4.
.child-holder{
width: 33.3%; /* Instead of 25% */
}
.child-holder:last-child {
width: 0px;
}
It stretches the items but this hides the last item. As you can see in the below image:
We can solve this by giving negative margin-left to each item with value equal to the items. Applying so, will now hides the first item. So, give margin-left to the container equal to the item's width (positive value).
.parent {
margin-left: 20px; /* This value is equal to the item's width */
}
.child {
width: 20px;
height: 20px;
background-color: black;
margin-left: -20px; /* negative margin equal to its width */
}
Hence, this will give the solution we want:
Working Fiddle
For unknown number of items:
For unknown number of items, we will replace float: left to the item holding sections with display: table-cell and to stretch those sections, we will apply display: table; width: 100%; to the parent container. and since we must apply margin-left value equal to the item's width, we will have a parent wrapper, to which we apply margin-left instead. (Because, if we apply margin-left and width: 100% to same element, then the element will overflow)
Though we are giving width: 0px to the last item holder section, it is still occupying the space.
This can be solved by applying table-layout: fixed to the parent container. This will give us the solution:
Working Fiddle
This solution will work for any number of items, added dynamically or static. It will get automatically adjusted.
For Unknown number of items with unequal widths:
For unequal/unknown width of items, we should definitely go with javascript. Here is the small code which I wrote to use in one of the projects:
function setAlign(parentClass, childCommonClass) {
var childDivs = document.getElementsByClassName(childCommonClass);
var childDivsTotalWidth = 0;
var childDivsLength = childDivs.length;
var parentElement = document.getElementsByClassName(parentClass)[0];
var parentElementWidth = parentElement.offsetWidth;
for (var i = 0; i < childDivsLength; i++) {
childDivsTotalWidth += childDivs[i].offsetWidth;
}
var remainingWidth = parentElementWidth - childDivsTotalWidth;
var gap = remainingWidth / (childDivsLength - 1);
var leftWidth = 0;
for (var j = 0; j < childDivsLength; j++) {
if (j > 0) {
leftWidth += gap + childDivs[j - 1].offsetWidth;
}
childDivs[j].style.left = leftWidth + "px";
}
}
window.onload = setAlign('row', 'box');
window.onresize = function () {
setAlign('row', 'box');
}
Working Fiddle
Flex
This can be done with display: flex; or flexbox
Property your after is justify-content: space-between; this will display all the item evenly distributed along the container with the fist and last element at the start and end of the container.
.container {
margin-top: 50px;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
background-color: whitesmoke;
}
.item {
width: 50px;
height: 50px;
background-color: tomato;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
THERE is so much more
Different sizes
Lets say the content size is not known:
.container {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: space-between;
background-color: whitesmoke;
align-items: center;
}
.item {
width: 50px;
height: 50px;
background-color: tomato;
}
.one {
width: 100px;
height: 20px;
}
.two {
width: 20px;
height: 100px;
}
.three {
width: 50px;
height: 70px;
}
.four {
width: 70px;
height: 70px;
}
.headline {
font-size: 20px;
}
<h2>Different sizes</h2>
<div class="container">
<div class="item one"></div>
<div class="item two"></div>
<div class="item three"></div>
<div class="item four"></div>
</div>
Column
More of a vertical person then a horizontal one?
No problem.
.container {
display: inline-flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-around;
background-color: whitesmoke;
align-items: center;
height: 500px;
}
.item {
width: 50px;
height: 50px;
background-color: lime;
}
.item2 {
width: 150px;
height: 50px;
background-color: tomato;
}
<div class="container">
<div class="item"></div>
<div class="item2"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Can i use it?
The support is really good, its just that IE is a tiny bit behind the rest...
So only IE10 (semi) IE 11 full
Links:
MDN Good thorough documentation
CSS-tricks My person favorite