In the example provided, the horizontal scroll container scrolls left and right as it should, while the vertical scroll container expands the page off the screen while not allowing for any scrolling. The scroll bar appears, but it is disabled.
The idea is to have the Vertical scroll container cover the remainder of the screen after the Horizontal scroll container.
Considering the Horizontal container is 40px high in this example, I set the max-height to the vertical container as calc(100% - 40px)
#container-scroll-horiz
{
width: 100%;
height: 40px;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid blue;
}
#container-scroll-horiz .item
{
display: inline-block;
width: 20vw;
height: 50px;
border: 1px solid black;
}
#container-scroll-vert
{
width: 100%;
max-height: calc(100% - 40px);
overflow-x: hidden;
overflow-y: scroll;
border: 1px solid red;
}
#container-scroll-vert .item
{
width: 100%;
height: 20vh;
border: 1px solid purple;
}
<div id="container-scroll-horiz">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="container-scroll-vert">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Because the vertical scroll's element has nothing to set its 100% height against.
When using percent on an element's height, its parent need a fixed height.
If all parents use percent, it need to be passed on all the way up to the body, which will use the viewport's fixed height.
You can either
use viewport units, max-height: calc(100vh - 40px); (sample 1)
set a height on the body, html, body { height: 100%; } (sample 2)
Sample 1
html, body {
margin: 0;
}
#container-scroll-horiz
{
width: 100%;
height: 40px;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid blue;
box-sizing: border-box;
}
#container-scroll-horiz .item
{
display: inline-block;
width: 20vw;
height: 50px;
border: 1px solid black;
}
#container-scroll-vert
{
width: 100%;
max-height: calc(100vh - 40px);
overflow-x: hidden;
overflow-y: scroll;
border: 1px solid red;
box-sizing: border-box;
}
#container-scroll-vert .item
{
width: 100%;
height: 20vh;
border: 1px solid purple;
}
<div id="container-scroll-horiz">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="container-scroll-vert">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Sample 2
html, body {
margin: 0;
height: 100%;
}
#container-scroll-horiz
{
width: 100%;
height: 40px;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid blue;
box-sizing: border-box;
}
#container-scroll-horiz .item
{
display: inline-block;
width: 20vw;
height: 50px;
border: 1px solid black;
}
#container-scroll-vert
{
width: 100%;
max-height: calc(100% - 40px);
overflow-x: hidden;
overflow-y: scroll;
border: 1px solid red;
box-sizing: border-box;
}
#container-scroll-vert .item
{
width: 100%;
height: 20vh;
border: 1px solid purple;
}
<div id="container-scroll-horiz">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="container-scroll-vert">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
It is because use 100% in setting max-height of the vertical container, it will expand combining its children's height since the vertical container doesn't have anything to reference its height from. you can use 100vh instead this way it will use viewport height limiting the max height viewable to window. Check my answer if this is what your trying to implement on your code. Goodluck
#container-scroll-horiz
{
width: 100%;
height: 40px;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid blue;
}
#container-scroll-horiz .item
{
display: inline-block;
width: 20vw;
height: 50px;
border: 1px solid black;
}
#container-scroll-vert
{
width: 100%;
overflow-x: hidden;
overflow-y: scroll;
border: 1px solid red;
max-height : calc(100vh - 60px); /* 40px plus 20px for horizontal scrollbar */
}
#container-scroll-vert .item
{
width: 100%;
height: 20vh;
border: 1px solid purple;
}
<div id="container-scroll-horiz">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="container-scroll-vert">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Html:
<div id="container-scroll-horiz">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div id="container-scroll-vert">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Css:
html, body {
margin: 0;
height: 100%;
}
#container-scroll-horiz {
width: 100%;
height: 40px;
overflow-x: scroll;
overflow-y: hidden;
white-space: nowrap;
border: 1px solid blue;
box-sizing: border-box;
}
#container-scroll-horiz .item {
display: inline-block;
width: 20vw;
height: 50px;
border: 1px solid black;
}
#container-scroll-vert {
width: 100%;
max-height: calc(100% - 40px);
overflow-x: hidden;
overflow-y: scroll;
border: 1px solid red;
box-sizing: border-box;
}
#container-scroll-vert .item {
width: 100%;
height: 20vh;
border: 1px solid purple;
}
Related
I make a 6 item column using the PHP loop, and I want to set the third child of each row border to none and I don't want to set the 3times in 2 rows because I want to show the theme center when the page is going smaller.
how to set the border to none for third child of each row(third child, 6th child, and ... 3*rownumber child)
<div class="full-container">
<div class="row">
<?php for($i=0;$i<6;$i++): ?>
<div class="document-item">
<a href="#">
<div class="document-img">
<img src="assets/images/book.jpg" alt="book"/>
</div>
<div class="document-detail text-middlegreen">
<h2>
<span class="parent-position">عنوان کتاب</span>
</h2>
<p>نام نویسنده</p>
<p>موضوع</p>
<p>تاریخ</p>
</div>
</a>
</div>
<?php endfor; ?>
</div>
</div>
.full-container {
width: calc(100% - 40px);
padding: 20px;
}
.row{text-align: center;}
.document-item{
width: calc(33% - 32px);
min-width: 300px;
border-left: 1px solid #5bbcb8;
margin-left: 30px;
display: inline-block;
margin-bottom: 30px;
margin-top: 30px;
}
.document-img{
width: 180px;
display: inline-block;
line-height: 100%;
text-align: center;
}
.document-img img{
width: 80%;
vertical-align: middle;
}
.document-detail{
display: inline-block;
vertical-align: middle;
}
.document-detail> h2{
margin: 10px 0;
}
.document-detail> h2>span{
font-size: 110%;
font-weight: bold;
}
.document-detail> h2>span::before{
content: '';
display: block;
width: 100%;
height: 1px;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: -2px;
background-color: #5bbcb8;
}
.document-detail> p:first-of-type{
font-size: 90%;
margin: 10px 0;
}
.document-detail> p:nth-last-of-type(2){
font-size: 90%;
margin: 10px 0;
}
.document-detail> p:last-of-type{
font-size: 90%;
margin: 10px 0;
}
is that any way to set multiplication of 3 of each element border to set none in CSS?
You can select every 3rd child using nth-child(3n).
.grid-wrapper {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-gap: 20px;
}
.item {
width: 100%;
height: 50px;
background-color: red;
}
.item:nth-child(3n) {
background-color: blue;
}
<div class="grid-wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
or
You can use nth-child(3n+1) to select every 3rd child including the first one.
Like so:
.grid-wrapper {
display: grid;
grid-template-columns: repeat(3,1fr);
grid-gap: 20px;
}
.item {
width: 100%;
height: 50px;
background-color: red;
}
.item:nth-child(3n+1) {
background-color: blue;
}
<div class="grid-wrapper">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
here is flex element with flex: column wrap; and max-height: 150px;. My problem is that justify-content not working. But working with height: 150px. For container with max-width: 100%; & flex-direction: row; aligment works properly
.container {
max-height: 150px;
display: flex;
flex-flow: column wrap;
justify-content: center;
}
.item {
width: 25%;
height: 50px;
border: 1px solid #000;
box-sizing: border-box;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Result
Expected result
Not sure if it's a bug or an intended result but you can fix it if you consider an extra wrapper where you apply the max-height property:
.container {
display: flex;
flex-flow: column wrap;
justify-content: center;
width:100%;
}
.item {
width: 25%;
height: 50px;
border: 1px solid #000;
box-sizing: border-box;
}
.extra {
max-height: 150px;
display:flex;
}
<div class="extra">
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
Worth to note that if you consider height instead of max-height it works fine:
.container {
display: flex;
flex-flow: column wrap;
justify-content: center;
height: 150px;
}
.item {
width: 25%;
height: 50px;
border: 1px solid #000;
box-sizing: border-box;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
I want to make equal gap for the children of flexbox. I used margin-right zero for each child, then applied the margin right back on the last child. But the margin right somehow doesn't applied. You can see after you scrolled to the end of the child.
see demo below
.flex {
display: flex;
background: pink;
width: 80px;
overflow: auto;
}
.item {
min-width: 20px;
height: 20px;
background: black;
margin: 8px;
margin-right: 0;
}
.item:last-child {
margin-right: 4px;
}
<div class="flex">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
add another parent div and give overflow for parent div. For .flex class apply display:inline-flex; then it will works
.flex-parent{
overflow: auto;
width: 80px;
}
.flex {
display: flex;
background: pink;
min-width:100%;
float:left;
}
.flex-parent{
overflow: auto;
width: 80px;
}
.flex {
display: inline-flex;
background: pink;
/*min-width:100%;
float:left;*/
}
.item {
min-width: 20px;
height: 20px;
background: black;
margin: 8px;
margin-right: 0;
}
.item:last-child {
margin-right: 4px;
}
<div class="flex-parent">
<div class="flex">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
.flex {
display: flex;
background: pink;
width: 200px;
overflow: auto;
justify-content: space-between;
}
.item {
min-width: 20px;
height: 20px;
background: black;
}
<div class="flex">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
I got the container, which width is the half of a page. That container includes several item collections (rows). Each row includes big amount of items. You can see only limited count of items, other ones can be discovered by horizontal scroll.
Please, see the snippet below.
.container {
width: 50%;
overflow-x: scroll;
overflow-y: hidden;
}
.items {
height: 100px;
background: #ccc;
white-space: nowrap;
}
.item {
display: inline-block;
width: 30%;
height: 50px;
background: #efc;
border: 1px solid;
}
.shadow {
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
<div class="container">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="items shadow">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
I have shadow class, which adds bright borders and shadow to an element. I want to be able to apply that class to any item collection (row). I mean, not only for visible part, but for the whole.
The problem is that width of a row element is equal to visible part. How can I make that width to be equal to the full long width (based on all items' width)?
UPDATE: layout (mostly) and scrolling behaviour should remain the same
Thank you.
I guess you not something like it.
.container {
width: 50%;
overflow-x: scroll;
overflow-y: hidden;
}
.items {
height: 100px;
background: #ccc;
white-space: nowrap;
}
.item {
display: inline-block;
width: 30%;
height: 50px;
background: #efc;
border: 1px solid;
}
.shadow {
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
<div class="container">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
<div class="items shadow">
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
The actual default behavior is buggy tbh, I would have assumed it would have worked as you intended it to from the get go.
Anyway, I don't think it's doable without javascript but I could be wrong.
The reason is that your item are of width: 30%, so if you changed the width of items to get the appropriate border, then the width of item would change as well.. See where I'm getting at ?
Having the shadow class on items is a no go, since even if we changed its width, it would change the width of contained items, so we have to put it somewhere else.
-
.shadow{
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
So with that out of the way, how would we give the correct width to shadow ? I don't think we can without js.
With some javascript you can grab the width of the container and apply it to a "shadow" div.
let ctnr = document.querySelector(".container");
let width = ctnr.scrollWidth;
let sel = document.querySelectorAll(".shadow");
sel.forEach( s => {
s.style.width = width + "px";
});
.container {
width: 50%;
overflow-x: auto;
overflow-y: hidden;
background: #ccc;
}
.items {
height: 100px;
white-space: nowrap;
}
.item {
display: inline-block;
width: 30%;
height: 50px;
background: #efc;
border: 1px solid;
}
.outer{
}
.sel{
position: relative;
}
.shadow{
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
outline: none;
border: 2px solid #3a53ed;
box-shadow: 0 0 10px #9ecaed;
}
<div class="container">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="items sel">
<div class="shadow"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
I'm trying to make a div stay at a fixed location inside another div. The containing div is scrollable and his location is not fixed in the screen.
This is what I got so far JSFiddle
The text "fixed text" should stay at the top right corner of the container when scrolling.
I made 2 copies of the div and kept the same class in order to simulate 2 different locations of the div.
Can it be done with CSS only?
HTML
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
CSS
.cont{
width: 400px;
height: 130px;
border: 1px solid black;
margin: 10px;
overflow-x: auto;
overflow-y: hidden;
position: relative;
}
.items{
width: 600px;
}
.item{
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt{
position: absolute;
top: 2px;
right: 10px;
}
You can use overflow: auto on items instead of cont element.
.cont {
width: 400px;
height: 130px;
border: 1px solid black;
margin: 10px;
overflow-x: hidden;
position: relative;
}
.items {
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
}
.item {
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt {
position: absolute;
top: 2px;
right: 10px;
}
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
Create an extra wrapper and apply height and overflow to that - I have added a div inner wrapping all the contents of cont and applied this to it:
.inner {
overflow-x: scroll;
overflow-y: hidden;
height: inherit;
}
See demo below to see what I mean:
.cont {
width: 400px;
height: 130px;
border: 1px solid black;
margin: 10px;
/*overflow-x: auto;*/
/*overflow-y: hidden;*/
position: relative;
}
.items {
width: 600px;
}
.item {
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt {
position: absolute;
top: 2px;
right: 10px;
}
.inner {
overflow-x: scroll;
overflow-y: hidden;
height: inherit;
}
<div class="cont">
<div class="inner">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
</div>
Add the fixed height and overflow to .items instead, so that .items scrolls instead of .cont, and .txt will stay where it is since it is positioned relative to .cont and .cont isn't scrolling.
.cont{
width: 400px;
border: 1px solid black;
margin: 10px;
overflow-x: auto;
overflow-y: hidden;
position: relative;
}
.items{
width: 600px;
height: 130px;
overflow: scroll;
}
.item{
width: 80px;
height: 80px;
background-color: blue;
margin-top: 22px;
margin-left: 3px;
display: inline-block;
}
.txt{
position: absolute;
top: 2px;
right: 10px;
}
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>
<div class="cont">
<div class="items">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<div class="txt">
fixed text
</div>
</div>