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

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
});

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.

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>

Once horizontal scroll reaches endpoint, is it possible to automatically restart at the beginning, essentially creating a loop?

I have a Grid set up in CSS with multiple div's placed in a horizontal scroll bar. I'd like the scroll bar to restart back at the original div once it's reaches the end, essentially creating loop. Looking to avoid doing it with Javascript.
.scrollBottomList {
grid-area: scrollBottomList;
display: grid;
grid-template-columns: repeat(20, 15%); /*percentages adjust to the screen size*/
grid-template-rows: 50% 50%;
grid-column-gap: 10px;
grid-template-areas:
'column1 column2 column3'
'column1 column2 column3'
'column1 column2 column3';
overflow-x: auto;
overflow-y: hidden;
}
<div class="scrollBottomList">
<div class="column1">1</div>
<div class="column2">2</div>
<div class="column3">3</div>
<div class="column4">4</div>
<div class="column5">5</div>
</div>

Unlimited rows in a grid container

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>

Categories