Unlimited rows in a grid container - javascript

I want to display an endless number of divs.
I want each div to be on new line.
For example now in wrapper I am setting:
wrap {
display: grid;
grid-template-rows: repeat(4, [row] 25px);
}
And for each div I am setting:
div1 { grid-row: "row" },
div2 { grid-row: "row 2"}
....etc...
How can I deal with it in CSS? What if I have 99999 divs? I can't manually for each div setting div[№] { grid-row: "row №" }.

If you want each grid item to occupy the entire row, then basically you're asking for a single-column grid container.
grid-container {
display: grid;
grid-template-columns: 1fr;
}
<grid-container>
<grid-item>1</grid-item>
<grid-item>2</grid-item>
<grid-item>3</grid-item>
<grid-item>4</grid-item>
<grid-item>5</grid-item>
<grid-item>etc.</grid-item>
</grid-container>
With grid-template-columns: 1fr, you're setting the container to a single column which occupies all available space.
You can create rows with the grid-template-rows property. These rows would be part of the explicit grid, which means the rows have been defined.
However, if you don't know how many rows there will be, the grid algorithm can create rows as necessary. These rows are part of the implicit grid, which means the rows have not been defined and are created automatically.
If you want to set a height for implicit rows, use the grid-auto-rows property.
grid-container {
display: grid;
grid-template-columns: 1fr;
grid-auto-rows: 25px;
grid-row-gap: 10px;
}
/* non-essential */
grid-container {
height: 100vh;
background-color: lightyellow;
}
grid-item {
display: flex;
align-items: center;
justify-content: center;
background-color: lightgreen;
}
body {
margin: 0;
}
<grid-container>
<grid-item>1</grid-item>
<grid-item>2</grid-item>
<grid-item>3</grid-item>
<grid-item>4</grid-item>
<grid-item>5</grid-item>
<grid-item>etc.</grid-item>
</grid-container>

Related

How to place images on a canvas in a grid pattern?

I'm looking to add different sized images in a tiled pattern to a set width and height HTML canvas.
Something like this:
This can be done with a div and CSS grid. Something like:
.gallery {
display: grid;
grid-gap: 15px;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-auto-rows: 200px;
grid-auto-flow: dense;
}
.wide {
grid-column: span 2;
}
.tall {
grid-row: span 2;
}
But to do this with the canvas element I need to work out their positions and dimensions.
Is there an npm package, algorithm, or technique that I could use to calculate the positions and dimensions of the images to be placed on to the canvas?
I am using React.

Single row container for grid-template-columns and responsive window

Suppose I have about 250 divs styled with class slider-item. I have a responsive grid in css A which wraps the divs as columns/items as the window scales. Minimum item width is 240px listed below.
https://streamable.com/l3ezfv
I'm trying to keep the grid responsive in a single row (nowrap with overflow horizontal). The problem is the property grid-template-columns: repeat(auto-fill..) grows/shrinks rows b/c the divs exceed the current window width
A
.slider-content {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
overflow: hidden;
margin: 20px 0;
scroll-behavior: smooth;
}
/* .slider-content > .slider-item {
min-height: 130px;
min-width: 240px;
} */
B
.slider-content {
display:grid;
grid-auto-flow:column;
grid-gap:10px;
margin:20px 0;
overflow:auto;
}
.slider-content > .slider-item {
min-height: 130px;
min-width: 240px;
}
Css B keeps the content in a single row with horizontal scroll, but the problem is its not responsive like css A
I need it later for a multiple column carousel.
Not interested in flexbox or slickjs; using css grid.
I think this achieves what you want:
.slider-content {
display: grid;
overflow-x: auto;
grid-auto-flow: column;
grid-auto-columns: minmax(240px, 1fr);
}
And don't forget to set a height on either .slider-content or .slider-item.
Update
I don't know how to disable CSS grid row wrapping. But, I found a way that works like on the video, but in one row with overflow. It is not the most elegant way, but works just fine. I didn't add all the media queries for up to 6 columns, but it is very easy to add them - just increment the media size up 240px, or whatever you want the minimal width to be, and change the grid-auto-columns value.
.slider-content {
/* Same as above, before update. */
}
#media (max-width: 479px) {
.slider-content {
grid-auto-columns: 100%;
}
}
#media (min-width: 480px) and (max-width: 719px) {
.slider-content {
grid-auto-columns: 50%;
}
}
#media (min-width: 720px) and (max-width: 959px) {
.slider-content {
grid-auto-columns: 33.3%;
}
}

CSS - How do I create a grid that takes up the remaining width of screen (without counting sidebar)

I am trying to create a grid in CSS, but I am not sure how to specify the width of the entire grid, such that it takes up only the remaining width of the screen (minus the sidebar) such that there should not be any scrolling horizontally allowed. Below is the screenshot of the issue I am facing.
As you can see, there is horizontal scrolling enabled, because the grid is too wide.
Here is my code for reference: (I am using ReactJS)
.analytics-grid {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
row-gap: 10px;
column-gap: 10px;
grid-template-areas: "conversion conversion-daily"
}
.daily-conversion-box {
grid-area: conversion-daily;
padding: 20px;
}
.conversion-box {
grid-area: conversion;
padding: 20px;
}
jsx (where CustomerConversion and CustomerConversionDaily are child components I call to render the charts)
<div className='analytics-grid'>
<div className='conversion-box'>
<CustomerConversion />
</div>
<div className='daily-conversion-box'>
<CustomerConversionDaily />
</div>
sidebar.js (where Sider is a component from a UI package AntD)
<div>
<Sider trigger={null} collapsible collapsed={collapsed}>
{menu()}
</Sider>
<div id='crm-header-layout'>
... *header goes here* ...
<div id="crm-content">
{props.children} //this is where the analytics grid from above end up
</div>
</div>
</div>
Is there a way for me to be able to specify the width of my grid such that it just nice takes up the remaining width of the screen minus the sidebar such that there is no horizontal scrolling to be done? Thanks all for the help, I am new to CSS, so do guide me along if there are any better solutions to accomplish what I want to accomplish! Thank you
when you set display: grid; it means the children of this node are arranged using grid. It doesn't set the div's height or width for you. You need to set it if you want to contain it.
There are multiple ways to set the width.
You can use the grid the same way you've used for container. Like this,
.container {
display: grid;
grid-template: 1fr / 80px 1fr;
}
.content-1 {
background-color: red;
}
.content-2 {
background-color: blue;
}
<div class="container">
<div class="content-1">Content 1</div>
<div class="content-2">Content 2</div>
</div>
You can contain both the appbar and the content in a flex, and set the flex-grow of container to 1.
.app{
display: flex;
}
.appbar{
flex-grow: 0;
}
.main-container{
flex-grow: 1;
}
or,
use CSS calc for container like this.
.analytics-grid {
display: grid;
grid-template-rows: auto;
grid-template-columns: 1fr 1fr;
row-gap: 10px;
column-gap: 10px;
grid-template-areas: "conversion conversion-daily";
width: calc(100vw - <appbar width>);
}
PS: grid-template is short hand to set both row and columns at a time. Refer https://developer.mozilla.org/en-US/docs/Web/CSS/grid-template

css grid to fill 100vh without affecting row height

I have a grid with 3 columns and a variable/dynamic number of rows. The grid has a colored background and when there are NOT enough rows as to vertically fill the window, the remaining, empty vertical space is un-colored:
.grid {
align-self: flex-start;
display: grid;
grid-template-columns: min-content 2fr 1fr;
grid-gap: 0px;
}
.index, .title {
background: red;
padding: 0 2vw 0 1vw;
}
.ticker {
background: yellow;
}
<div class="grid">
<div class="index">1</div>
<div class="title">Pigs are cute</div>
<div class="ticker">blah blah</div>
<div class="index">2</div>
<div class="title">Horses rise at night</div>
<div class="ticker">bleh bleh</div>
<div class="index">3</div>
<div class="title">Cats run in packs</div>
<div class="ticker">blih blih</div>
</div>
I would like this vertical space to be colored as the grid is. The apparently obvious solution is to give the grid a height of 100vh. But this expectedly stretches each row's height accordingly, which is not the result I am looking for, as I need row height to adapt to content.
.grid {
align-self: flex-start;
display: grid;
grid-template-columns: min-content 2fr 1fr;
grid-gap: 0px;
height: 100vh;
}
.index, .title {
background: red;
padding: 0 2vw 0 1vw;
}
.ticker {
background: yellow;
}
<div class="grid">
<div class="index">1</div>
<div class="title">Pigs are cute</div>
<div class="ticker">blah blah</div>
<div class="index">2</div>
<div class="title">Horses rise at night</div>
<div class="ticker">bleh bleh</div>
<div class="index">3</div>
<div class="title">Cats run in packs</div>
<div class="ticker">blih blih</div>
</div>
Is there any CSS grid way of expanding the grid vertically while still allowing row height to adapt to content?
An alternative javascript solution, such as adding blank rows to the grid until grid's height is >= the height of the window would also be acceptable.
A flex solution is, I believe, not acceptable, as I need a grid-like behaviour where columns and rows remain aligned.
Thank you
Since different columns have different colors, extending the grid would not work, because the grid itself can't have two different colors. This means only expanding the rows or adding new rows would work.
Since one of the question's requeriments is to leave row height untouched, and as per this question, adding an extra row and expanding only that row to take the remaining space is not possible with CSS grid (but flexbox), the only solution seems to add rows via JS until the grid height is >= window height :
var rowHeight = window.getComputedStyle(document.querySelector('.grid').firstElementChild).height;
var row = "<div class='index' style='height:"+ rowHeight +"'></div><div class='title' style='height:"+ rowHeight +"'></div><div class='ticker' style='height:"+ rowHeight +"'></div>";
while (parseFloat(window.getComputedStyle(document.querySelector('.grid')).height) < window.innerHeight) {
document.querySelector('.grid').innerHTML += row;
}
html, body {
margin: 0;
padding: 0;
}
.grid {
align-self: flex-start;
display: grid;
grid-template-columns: min-content 2fr 1fr;
grid-gap: 0px;
}
.index, .title {
background: red;
padding: 0 2vw 0 1vw;
}
.ticker {
background: yellow;
}
<div class="grid">
<div class="index">1</div>
<div class="title">Pigs are cute</div>
<div class="ticker">blah blah</div>
<div class="index">2</div>
<div class="title">Horses rise at night</div>
<div class="ticker">bleh bleh</div>
<div class="index">3</div>
<div class="title">Cats run in packs</div>
<div class="ticker">blih blih</div>
</div>

CSS Grid - Check if grid row has empty cells and fill

I wasn't able to find a solution for the following:
I've created a grid layout (320px each row), max 4 rows, changing rows via media queries.
.container {
display: grid;
grid-template-columns: 320px;
grid-template-rows: 50px;
grid-auto-rows: 50px;
grid-column-gap: 20px;
grid-row-gap: 4px;
grid-auto-flow: row dense;
}
I am filling this container with content from an API. The divs to fill into the container have two different sizes (320px by 300px) or (660px by 300px). Like a Masonry Layout with infinity scrolling. By design it has, depending on the content sometimes gaps in the layouts.
My question is: How can I check if a grid-row is empty and fill in a placeholder-div (company logo, ...).
Thanks in advance.
Edit: Add image to show issue
you mean this ?
$(".container").each(function(index, el) {
if ($(el).is(':empty')) $(el).html("is empty");
})
.container {
display: grid;
grid-template-columns: 320px;
grid-template-rows: 50px;
grid-auto-rows: 50px;
grid-column-gap: 20px;
grid-row-gap: 4px;
grid-auto-flow: row dense;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container"></div>
<div class="container">test</div>
<div class="container">test</div>
<div class="container"></div>
<div class="container">test</div>
You can use JQuery to check if the dev is empty, for example
if ($('.classNameOne').html() == "") {
//Do something useful here
});

Categories