I have problem with grid. I want create some like this:
I want this schema repeat a few times.
But my code is not flexie.
.grid {
margin: 0 auto;
display: grid;
grid-template-columns: 32% 32% 32%;
grid-column-gap: 20px;
grid-row-gap: 20px;
grid-template-areas: "a b c"
"d e f"
"g g g"
"h i j"
"k l m"
"o o o";
}
.item1 {
grid-area: a;
}
.item2 {
grid-area: b;
}
.item3 {
grid-area: c;
}
.item4 {
grid-area: d;
}
.item5 {
grid-area: e;
}
.item6 {
grid-area: f;
}
.item7 {
grid-area: g;
}
.item {
background: red;
border: 4px solid black;
height: 20px;
width: 100%;
}
<div class="grid">
<div class="item item1"></div>
<div class="item item2"></div>
<div class="item item3"></div>
<div class="item item4"></div>
<div class="item item5"></div>
<div class="item item6"></div>
<div class="item item7"></div>
</div>
how to improve the grid?
I want to repeat the scheme 3 3 1. If I have about 100 elements this solution will be unbearable
You can simplify like below. No need for grid-template-areas or grid-template-columns
.grid {
margin: 0 auto;
display: grid;
grid-gap: 20px;
}
.grid > .item:nth-child(7n) {
/* this will create 3 columns layout and force each 7th element to span all of them */
grid-column:span 3;
}
.item {
background: red;
border: 4px solid black;
height: 20px;
}
<div class="grid">
<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 class="item"></div>
</div>
Related
I'm building a horizontal list of items:
Once scrolled to the end of the list, the second last item needs to be in center, and the last item takes all of the remaining space after it.
I've had a success in making the list of items, but not sure what's the best way to implement the desired behaviour of having second last item centered and last item taking remaining space. Here is my current code:
I would appreciate any help or advice for guiding me in the right direction. Thank you!
/* layout */
.container {
display: flex;
overflow-x: auto;
gap: 21px;
}
.item {
min-width: 212px;
height: 254px;
}
/* visuals */
.container {
padding-left: 11px;
}
.item {
background: #D9D9D9;
}
.item.green {
background: #099F9F;
}
.item.red {
background: #FF6262;
}
<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 green"></div>
<div class="item red"></div>
</div>
You can define the width as calc((100% - item_wdith - 2*gap)/2)
.container {
display: flex;
overflow-x: auto;
padding-left: 10px;
gap: 20px;
}
.item {
width: 220px;
flex-shrink: 0;
height: 254px;
background: #D9D9D9;
}
.item.green {
background: #099F9F;
}
.item.red {
background: #FF6262;
width: calc((100% - 220px - 2*20px)/2);
}
/* to illustrate the center */
html {
background: linear-gradient(red 0 0) 50%/2px 100% no-repeat;
min-height: 100%;
}
<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 green"></div>
<div class="item red"></div>
</div>
Im trying to implement a list of items, that correctly fits into my layout. I'd like the list to be scrollable if its intrinsic content size exceeds its parent element's dimensions. As you can see in the snippet below, instead of scrolling my list resizes hence ignoring the overflow: scroll rule. So far I've tried to manipulate the overflow(-y), maxHeight, height, flex-grow, shrink and basis properties but did not manage to solve my problem. Im may be only one style-rule but so far I did not manage to prevent the list from overgrowing and thereby destroying the layout.
Any help would be highly appreciated. Thanks!
.layout {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 1fr 1fr;
column-gap: 10px;
row-gap: 10px;
padding: 15px;
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.container {
background-color: lightGrey;
border-radius: 15px;
}
.leading-upper {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.leading-lower {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
.trailing {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
}
.header {
padding-left: 20px;
border-bottom: 1px solid;
}
.list {
overflow: scroll;
display: flex;
flex-flow: column nowrap;
row-gap: 10px;
padding: 10px;
overflow: scroll;
}
.item {
height: 50px;
background-color: red;
border-radius: 10px;
}
<div class="layout">
<div class="container leading-upper"></div>
<div class="container leading-lower"></div>
<div class="container trailing">
<div class="header">
<h1>Title</h1>
</div>
<div class="list">
<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 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>
</div>
</div>
The trailing class should be the flexbox container and not the list class. Just put the following three lines in the trailing class and it almost works.
display: flex;
flex-direction: column;
row-gap: 10px;
In the list class, remove one overflow: scroll and change the other to overflow-y: scroll as horizontal scrolling is not required.
There is no gap between item's so add margin-bottom: 10px;, for example.
.layout {
display: grid;
grid-template-columns: 1fr 3fr;
grid-template-rows: 1fr 1fr;
column-gap: 10px;
row-gap: 10px;
padding: 15px;
position: absolute;
left: 0px;
top: 0px;
right: 0px;
bottom: 0px;
}
.container {
background-color: lightGrey;
border-radius: 15px;
}
.leading-upper {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 1;
grid-row-end: 2;
}
.leading-lower {
grid-column-start: 1;
grid-column-end: 2;
grid-row-start: 2;
grid-row-end: 3;
}
.trailing {
grid-column-start: 2;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
display: flex;
flex-direction: column;
row-gap: 10px;
}
.header {
padding-left: 20px;
border-bottom: 1px solid;
}
.list {
padding: 10px;
overflow-y: scroll;
}
.item {
height: 50px;
background-color: red;
border-radius: 10px;
margin-bottom: 10px;
}
<div class="layout">
<div class="container leading-upper"></div>
<div class="container leading-lower"></div>
<div class="container trailing">
<div class="header">
<h1>Title</h1>
</div>
<div class="list">
<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 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>
</div>
</div>
I have a series of inline-block divs that can wrap onto a second line depending on how wide the browser is at a given time. Here's a fiddle example. For example, it might look like this:
However if the viewport is of a certain width, it can end up with just one orphaned inline-block on the next line:
Is there a CSS method that is essentially some form of "orphan control" (CSS orphan doesn't seem to apply in this situation) so that if there are fewer than a certain number of elements on the second line, it'd wrap more of them down there to even things out?
.container {
width: 100%;
}
.item {
display: inline-block;
width: 50px;
background-color: blue;
}
<div class="container">
<div class="item">
Item 1
</div>
<div class="item">
Item 2
</div>
<div class="item">
Item 3
</div>
<div class="item">
Item 4
</div>
<div class="item">
Item 5
</div>
<div class="item">
Item 6
</div>
<div class="item">
Item 7
</div>
</div>
Here is an idea using CSS grid where the trick is to make sure your div has a width expressed as a multiple of a fixed amount to make sure you never have an orphan element.
.wrapper {
--w: 100px; /* width of one item */
display: grid;
grid-template-columns: repeat(auto-fit, calc(2*var(--w))); /* the item will break two by two*/
justify-content:center;
}
.container {
grid-column: 1/-1;
display:flex;
flex-wrap:wrap;
justify-content:center;
}
.item {
width: calc(var(--w) - 10px);
margin: 5px;
}
/* irrelevant styles */
.container {
counter-reset: num;
}
.item {
height: 150px;
background-color: blue;
color: #fff;
}
.item::before {
color: #fff;
content: attr(class) " " counter(num);
counter-increment: num;
}
<div class="wrapper">
<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 class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
If we use 3
.wrapper {
--w: 100px; /* width of one item */
display: grid;
grid-template-columns: repeat(auto-fit, calc(3*var(--w)));
justify-content:center;
}
.container {
grid-column: 1/-1;
display:flex;
flex-wrap:wrap;
justify-content:center;
}
.item {
width: calc(var(--w) - 10px);
margin: 5px;
}
/* irrelevant styles */
.container {
counter-reset: num;
}
.item {
height: 150px;
background-color: blue;
color: #fff;
}
.item::before {
color: #fff;
content: attr(class) " " counter(num);
counter-increment: num;
}
<div class="wrapper">
<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 class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</div>
You could use flex and flex-wrap for this with break points so you can decide how many items are in the top row on each width. Where it is inevitable that there is a single item on the last row this snippet goes for minimising the number of rows.
It would have been nice to use CSS variables for all of this so the choice is easily altered, but you can't use variables in media queries so we have to put them in by hand.
.container {
width: 104px; /* item width plus 2 lots of padding */
margin: 0;
padding: 0;
justify-content: center;
display: flex;
flex-wrap: wrap;
}
#media (min-width: 312px) {
.container {
width: 312px;
}
}
#media (min-width: 416px) {
.container {
width: 416px;
}
}
#media (min-width: 728px) {
.container {
width: 728px;
}
}
.item {
r-sizing: border-box;
width: 100px;
background-color: cyan;
text-align: center;
flex: 0 0 100px; /* made 100px so easier to test on different widthe */
margin: 2px;
}
<div class="container">
<div class="item">
Item 1
</div>
<div class="item">
Item 2
</div>
<div class="item">
Item 3
</div>
<div class="item">
Item 4
</div>
<div class="item">
Item 5
</div>
<div class="item">
Item 6
</div>
<div class="item">
Item 7
</div>
</div>
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>
This question already has answers here:
One flex/grid item sets the size limit for siblings
(6 answers)
How can you set the height of an outer div to always be equal to a particular inner div?
(2 answers)
Closed 3 years ago.
I want to display two areas in two columns using CSS Grid. However height of left column must be the same as height in right column.
If left column is higher than right column the content in left column should be scrollable.
What I want to achieve:
I cannot to this without hardcoding heights in pixels. Is is possible to do that by CSS only? Or I need to use JavaScript to recalculate left column height?
I attached jsFiddle to take a look.
https://jsfiddle.net/rafalcypcer/2teonuhy/17/
Thanks,
Rafal
.gridwrapper {
display: grid;
grid-template-columns: 0.5fr 1.5fr;
grid-auto-rows: 200px;
grid-gap: 10px;
grid-template-rows: auto;
}
.column {
background: green;
}
.dynamic-content {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
background: pink;
margin: 20px;
}
.list {
overflow-y: auto;
margin: 20px;
height: 100%;
}
.item {
height: 50px;
background: yellow;
border: 2px solid black;
}
<div class="gridwrapper">
<div class="column">
<div class="list">
<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>
</div>
<div class="column">
<div class="dynamic-content">Some dynamic content with random height</div>
</div>
</div>
Since the width is known you can consider position:absolute for the content so it doesn't affect the height and simply stretch it using top:0;bottom:0;
.gridwrapper {
display: grid;
grid-template-columns: 0.5fr 1.5fr;
grid-auto-rows: 200px;
grid-gap: 10px;
grid-template-rows: auto;
}
.column {
background: green;
position:relative;
}
.dynamic-content {
display: flex;
justify-content: center;
align-items: center;
height: 300px;
background: pink;
margin: 20px;
}
.list {
position:absolute;
overflow-y: auto;
margin: 20px;
top:0;
bottom:0;
left:0;
right:0;
}
.item {
height: 50px;
background: yellow;
border: 2px solid black;
}
<div class="gridwrapper">
<div class="column">
<div class="list">
<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>
</div>
<div class="column">
<div class="dynamic-content">Some dynamic content with random height</div>
</div>
</div>