The best way I can describe this is via picture, since I am unable to do this using CSSGrid. I am starting with 3 columns, each column has n rows. Using CSSGrid, how can I collapse these columns into one column so that all of the members of the first column are above (see second image) the members of the next column?
Codepen to illustrate the problem: https://codepen.io/robbyjm0/pen/dydjVYa
Starting Point: 3 columns
Desired outcome
Uhm the way I see the structure of this is that you have 3 columns:
<div class='container'>
<div class='column'>
<div class='column__row'>
</div>
<div class='column__row'>
</div>
....
</div>
<div class='column'>
<div class='column__row'>
</div>
<div class='column__row'>
</div>
....
</div>
<div class='column'>
<div class='column__row'>
</div>
<div class='column__row'>
</div>
....
</div>
</div>
Each column can either be a grid or a flex-box (I would personally go with flex since they are just a bunch of rows)
.column {
display: flex;
flex-direction: row;
}
And to to make them display as 3 equal size columns next to each other:
.container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
To make them appear as 1 column stacking on 1 on top another:
.container {
display: grid;
grid-template-rows: 1fr 1fr 1fr;
}
If you don't have control over the order of the html elements, you can give each column a unique id and use grid-template-area
Related
I'm trying to arrange a set of statistics such that:
they are displayed on a single horizontal line
the enclosing element is no wider than it needs to be to contain the content
there should be a fixed gap between statistics
I tried implementing this using display: grid. Here is my approach:
.outer {
background-color: yellow;
display: inline-block;
}
.stats {
display: grid;
grid-gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
}
<div class="outer">
<div class="stats">
<div class="stat">
<strong>Value:</strong> 1,234,568
</div>
<div class="stat">
<strong>Another value:</strong> 98,765
</div>
<div class="stat">
<strong>Test value:</strong> 83,263
</div>
</div>
</div>
Unfortunately, this results in some strange overlapping. Despite there being plenty of room for the .outer element to expand, the statistics are wrapped over several lines and the text runs into other columns:
How can I avoid this problem? I tried adding:
.stat {
white-space: nowrap;
}
...but the text still "runs" together. What am I missing?
The main problem stems from this declaration:
grid-template-columns: repeat(auto-fit, minmax(0, 1fr))
You're setting the columns to shrink to zero width.
Also, 1fr does nothing here, because there is no free space in the container. (You have the primary container set to inline-block, i.e., min-width. This means no extra space.)
At a minimum, these commands appear to be confusing the inline-block algorithm.
Consider leaving the columns at auto width (a default setting).
And, perhaps, setting them to appear in the first row. (I used the grid-auto-flow: column technique.)
.outer {
background-color: yellow;
display: inline-block;
}
.stats {
display: grid;
grid-gap: 20px;
grid-auto-flow: column;
}
<div class="outer">
<div class="stats">
<div class="stat">
<strong>Value:</strong> 1,234,568
</div>
<div class="stat">
<strong>Another value:</strong> 98,765
</div>
<div class="stat">
<strong>Test value:</strong> 83,263
</div>
</div>
</div>
folks!
I m trying to create a widget qliksense card responsive but dont work its return one column always I need that work responsive em broke in another row in responsive mode.
Does Anybody knows?
<qw-console log="data">
<div class="container" ng-repeat="row in data.rows track by $index">
<div class=' sombra'>{{row.cells[0].qText}}</div>
<br/>
</div>
</qw-console>
my css has:
.container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
grid-template-rows: repeat(6, 100px) ;
grid-gap: 15px;
}
to resolve this question:
<qw-console log="data">
<div class="container">
<div ng-repeat="row in data.rows track by $index">
<div class=' sombra'>{{row.cells[0].qText}}</div>
<br/>
</div>
</div>
</qw-console>
I have started using css grids recently (https://css-tricks.com/snippets/css/complete-guide-grid/) but feel like I'm not fully exploiting them. My question concerns a situation where my displayed data is dynamic. For instance I want to display this:
In short:
each row of data can contain one or two columns
rows are separated by a divider row
data is dynamic, the css grid layout cannot be pre-set
It feels like css grids have a way of doing this (without dynamically generating the css), using repeat etc... but I don't really see how.
This is done under React, some dynamic rows are generated using a map, the code would looks something like this:
return (
<div>
<div> 1A </div>
<div> 1B </div>
<MyDivider />
<div> 2 </div>
<MyDivider />
{myData.map((row) => (
<div key={row.key}>
<div>{row.A}</div>
<div>{row.B}</div>
<MyDivider />
</div>
))}
// more rows, with single (merged) or dual columns...
</div>
);
Is it possible to do this without dynamically generating the grid css? Namely, defining grid settings for single / dual column lines, and divider lines? Also, due to the map function, under React, my dynamic content ends up wrapped in a div; do I need to break this down in multiple map's so that I don't have this wrapping div?
Thanks!
Edit 10/24/2020:
To clarify things, I don't want to literally display what is in this drawing, this is just a layout, with each '1A', '1B' block corresponding to some data cell, just like in a tabulator.
Assuming that you know if a row is single or dual columns.
You can make a cell span by using grid-column like the sample below
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 5px; // for demonstration purposes
}
.grid-item {
background-color: lightblue; // for demonstration purposes
}
.grid-item.single {
grid-column: span 2;
}
.grid-separator {
grid-column: span 2;
background-color: lightgreen; // for demonstration purposes
}
<div class="grid">
<div class="grid-item">A1</div>
<div class="grid-item">B1</div>
<div class="grid-separator">Separator</div>
<div class="grid-item single">A2</div>
<div class="grid-separator">Separator</div>
<div class="grid-item">A3</div>
<div class="grid-item">B3</div>
<div class="grid-separator">Separator</div>
<div class="grid-item">A4</div>
<div class="grid-item">B4</div>
<div class="grid-separator">Separator</div>
<div class="grid-item single">A5</div>
</div>
Note that you need to add the single class under some condition
Please show us your css or you can do it like that way...
.grid {
display: grid;
grid-template-columns: 1fr 1fr;
}
.grid div {
text-align: center;
background: #ddd;
margin: 2px;
padding: 10px;
}
.mydevider {
grid-column: 1 / span 2;
}
<div class="grid" >
<div> 1A </div>
<div> 1B </div>
<div class="mydevider">
<div> 1A </div>
</div>
<div> 1B </div>
<div> 1B </div>
<div class="mydevider">
<div> 1A </div>
</div>
<div> 1B </div>
<div> 2 </div>
</div>
I have created a form with two columns. But when I decrease the browser width, two columns are preserved even when their content overflows. I have tried to change the code to plain DIV with container class, specify cols count, set width but it resists.
Here is the codepen: https://codesandbox.io/s/stoic-goldberg-4ugt6
and the source code of the parent container:
<div class="container flex-wrap pt-3 w-75 ml-auto mr-auto mt-auto mb-5">
<div class="row">
<div class="col">
<b-card>
<SeriesForm />
</b-card>
</div>
<div class="col">
<b-card :header="captions[1]">
<SeriesForm :group="forms[1]" />
</b-card>
</div>
</div>
<div class="row">
<div class="col text-center p-4">
<b-button>Analyse</b-button>
</div>
</div>
</div>
How can I make it two columns when there is enough space and single column otherwise?
U can try class like col-sm-6 or col-xs-6 or col-md-6 or col-lg-6 according to your need.
<div class="container flex-wrap pt-3 w-75 ml-auto mr-auto mt-auto mb-5">
<div class="row">
<div class="col-sm-6">
<b-card>
<SeriesForm />
</b-card>
</div>
<div class="col-sm-6">
<b-card :header="captions[1]">
<SeriesForm :group="forms[1]" />
</b-card>
</div>
</div>
<div class="row">
<div class="col text-center p-4">
<b-button>Analyse</b-button>
</div>
</div>
</div>
The issue isn't with the bootstrap grid itself, the issue is with how your checkboxes are displayed.
You're defining in the .align-nicely class, that your checkbox group must always be 3 columns.
display: grid isn't that smart. So if you tell it to be 3 columns, it will be 3 columns and ignore everything else. This is why your content is overflowing.
So to fix the issue or improve it at least. You have to change how the display: grid columns are handled.
One method would be to use CSS #media queries, to define how many columns there should be at a given screen width. This way you can scale them down as the screen gets smaller.
The below CSS should work if you use <b-col xl='6'> with your current text.
.align-nicely {
display: grid;
grid-column-gap: 10px;
grid-row-gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
}
#media screen and (max-width: 1350px) {
.align-nicely {
grid-template-columns: 1fr 1fr;
}
}
#media screen and (max-width: 576px) {
.align-nicely {
grid-template-columns: 1fr;
}
}
Another solution could be to use the repeat() function combined with minmax().
This option will be a lot more dynamic than the first one, but will break the alignment across your different groups.
.align-nicely {
display: grid;
grid-column-gap: 10px;
grid-row-gap: 10px;
/*
The 110px inside minmax(), is how small each column is allowed to get.
So if there isn't space on the current row for the column to be over 110px,
it will be moved to a new row. So you will need to adjust this based on your content size.
*/
grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
}
This is happening because of the flex display,
what you need to do is set the columns with below your row for each form :
use this <div class='col-12 col-xl-6'> instead of <div class='col'> .. the spacing is a little bit tight so you might need to remove some of the margins and paddings
this will make each form take full width on big screens and below and will make them 50% width on xl screens
I have added attribute to your tags
If you will expand the screen then u will get the initial format.
Suppose we have a responsive grid container with indefinite number of child cells. Cells' widths and heights vary. Using only CSS (probably CSS Grid), how can we create such grid, that number of columns / rows and the width / height of each column / row is determined dynamically based on the container's size (without overflowing it) and cells' sizes in one of the following two ways:
Width / height for each column / row is determined based on the widest / tallest cell in that column / row,
Width / height for all the columns / rows is determined based on the widest / tallest cell in the grid?
When applied to column width, these two cases loosely correspond to, respectively, automatic and fixed layout algorithms for tables. Except we don't know the number of columns and rows; it needs to be somehow determined automatically.
The following examples demonstrate these two cases applied to column width. For each case there are two possible flow directions: row or column. Note that in the examples we had to set the number of columns and their sizes specifically. I would like those to be determined automatically.
Please try to replicate these examples in your answer without setting the exact number of columns, rows and any widths or heights.
* {
box-sizing: border-box;
}
.container {
display: grid;
flex-wrap: wrap;
grid-template-rows: repeat(3, auto);
justify-content: space-between;
border: 3px solid teal;
font-size: 20px;
}
.flex {
grid-template-columns: repeat(3, auto);
width: min-content;
}
.fixed {
grid-template-columns: repeat(3, 33.33%);
width: 28em;
}
.column {
grid-auto-flow: column;
}
.cell {
padding: 1em;
background: pink;
border: 1px dashed teal;
white-space: nowrap;
}
h3:not(:first-of-type) {
margin-top: 3em;
}
<h3>Flexible column width. Flow in rows</h3>
<div class="container flex row">
<div class="cell">One</div>
<div class="cell">Two</div>
<div class="cell">Buckle my shoe</div>
<div class="cell">Three</div>
<div class="cell">Four</div>
<div class="cell">Knock at the door</div>
<div class="cell">Five</div>
<div class="cell">Six</div>
</div>
<h3>Flexible column width. Flow in columns</h3>
<div class="container flex column">
<div class="cell">One</div>
<div class="cell">Two</div>
<div class="cell">Buckle my shoe</div>
<div class="cell">Three</div>
<div class="cell">Four</div>
<div class="cell">Knock at the door</div>
<div class="cell">Five</div>
<div class="cell">Six</div>
</div>
<h3>Fixed column width. Flow in rows</h3>
<div class="container fixed row">
<div class="cell">One</div>
<div class="cell">Two</div>
<div class="cell">Buckle my shoe</div>
<div class="cell">Three</div>
<div class="cell">Four</div>
<div class="cell">Knock at the door</div>
<div class="cell">Five</div>
<div class="cell">Six</div>
</div>
<h3>Fixed column width. Flow in columns</h3>
<div class="container fixed column">
<div class="cell">One</div>
<div class="cell">Two</div>
<div class="cell">Buckle my shoe</div>
<div class="cell">Three</div>
<div class="cell">Four</div>
<div class="cell">Knock at the door</div>
<div class="cell">Five</div>
<div class="cell">Six</div>
</div>
I had the same problem, using column, and this was fixed by adding grid-template-columns: repeat(auto-fit, minmax(baseValue,maxValue)); to the parent element