CSS table layout with n rows and expanding as columns - html

I have been struggling with this CSS layout. I have n items that its amount might increase dynamically. And I want to only just have n rows and many or unlimited columns layout.
So, let's say that n is 2 and I have 3 items, This is how my items should look like,
-----------
| 1 || 3 |
-----------
| 2 |
-----------
For the same n, with 6 items,
-----------------
| 1 || 3 || 5 |
-----------------
| 2 || 4 || 6 |
-----------------
And so on..
I have tried tinkering it with float: left with no lucks. And now I am kinda learning flex layout, which leads me to stuck.
Please help :) Here's my Fiddle
Note: All my items will have the same width and height.

Something like this?
jsFiddle 1
.items {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
/* Below this is just styling */
.items {
background-color: #0f9c8a;
padding: 4px;
height: 250px;
width: 100%;
}
.item {
width: 100px;
height: 100px;
background-color: #6f6ac2;
border: 1px solid #fff;
margin: 2px;
text-align: center;
line-height: 100px;
}
<div class="items">
<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>
Update: since you need to align the .item divs to the left just add align-content:flex-start; to the container .items, like this:
jsFiddle 2
.items {
display: flex;
flex-direction: column;
flex-wrap: wrap;
align-content: flex-start;
}
/* Below this is just styling */
.items {
background-color: #0f9c8a;
padding: 4px;
height: 250px;
width: 1000px;
}
.item {
width: 100px;
height: 100px;
background-color: #6f6ac2;
border: 1px solid #fff;
margin: 2px;
text-align: center;
line-height: 100px;
}
<div class="items">
<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>

Related

Wrap items to the next column when height is overflowing?

I have a container with items inside it.
This container has a height set. I'd like to wrap the items inside this container to a new column by maintaining the order of them to the next column. How do I do this?
For example, if I have 5 items, I'd like to wrap them like this:
1 4
2 5
3
and not like
1 2
3 4
5
Here is a photo for a reference:
From this photo, I'd like to create a new column with the 11th and 12th item
You can use flexbox with flex-direction: column:
.container {
display: flex;
flex-direction: column;
flex-wrap: wrap;
max-height: 20rem;
width: 20rem;
border: 1px solid black;
padding: 5px;
gap: 5px;
}
.item {
font-size: 5rem;
border: 1px solid black;
text-align: center;
}
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>

Centering buttons regardless of how many in list

I've created a relatively simple layout using two DIVs. The idea is that everything is centered within their own DIVs but if there's not enough to fill a row the ones below would center also.
.row {
display: table;
width: 95%;
text-align: center;
margin-left: 2.5%;
margin-right: 2.5%;
margin-top: 2.5vh;
margin-bottom: 2.5vh;
}
.item {
width: 16.6%;
float: left;
}
#media only screen and (max-device-width: 500px) {
.item {
width: 33.3%;
float: left;
}
}
<div class="row">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
<div class="item">
6
</div>
</div>
</div>
These work fine and are all aligned. The issue comes when there's an odd number of items.
For example:
| 1 | 2 | 3 |
| 4 | 5 | 6 |
Works fine on mobile but...
| 1 | 2 | 3 |
| 4 | 5 | |
doesn't. I'd want something like this...
| 1 | 2 | 3 |
| 4 | 5 |
That means no matter how many items are added within the HTML they'll distribute properly when those rules are broken. Thanks in advance :)
Hopefully this makes sense.
Here you go with a solution using Flexbox
.row {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.item {
display: flex;
width: 20%;
height: 100px;
border: 1px Solid;
justify-content: center;
align-items: center;
margin: 5px;
}
<div class="row">
<div class="item">
1
</div>
<div class="item">
2
</div>
<div class="item">
3
</div>
<div class="item">
4
</div>
<div class="item">
5
</div>
</div>
jsfiddle

Using CSS, how to display another div on top of original on the hover

I have 4 divs in a some kind of boxes and I would like to hide original div (on hover) with another pair of hidden divs. So at the beginning it would looks like
_______ _______
| Q1 | | Q2 |
|_______| |_______|
_______ _______
| Q3 | | Q4 |
|_______| |_______|
and after hover on Q1 pair of hidden divs would appear and hide Q1, something like:
___ ___ _______
| Y || N | | Q2 |
|___||___| |_______|
_______ _______
| Q3 | | Q4 |
|_______| |_______|
Is it possible to get this behavior using CSS?
My code so far looks like this (there is just changing colors on hovering, every time I add new div it messes up my table:
.table {
display: grid;
grid-template-columns: 100px 100px;
grid-gap: 10px;
background-color: #eee;
color: #232794;
}
.boxes {
background-color: #232794;
color: #fff;
border-radius: 7px;
padding: 33px;
text-align: center;
transition: 0.3s;
}
.boxes:hover {
background-color: #000000;
}
<body>
<div class="table">
<div class="boxes">Q1</div>
<div class="boxes">Q2</div>
<div class="boxes">Q3</div>
<div class="boxes">Q4</div>
</div>
Basically you need to add elements inside your boxes to hide/show. You can either do this with pseudo-elements or by adding something to the DOM. Since I assume you're going to be able to click the "yes/no" actions, you should actually add an element.
.table {
display: grid;
grid-template-columns: 100px 100px;
grid-gap: 10px;
background-color: #eee;
color: #232794;
}
.boxes {
width: 100px;
height: 100px;
background-color: #232794;
color: #fff;
border-radius: 7px;
text-align: center;
transition: 0.3s;
}
.boxes .question, .boxes .answer {
/* center horizontally & vertically */
display: flex;
justify-content: center;
align-items: center;
height: 100%;
width: 100%;
}
.boxes .answer {
/* hide this until hover */
display:none;
}
.boxes:hover {
cursor:pointer;
}
.boxes:hover .question {
/* hide question */
display:none;
}
.boxes:hover .answer {
/* show answer */
display:block;
}
<body>
<div class="table">
<div class="boxes">
<div class="question">Q1</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
<div class="boxes">
<div class="question">Q2</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
<div class="boxes">
<div class="question">Q3</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
<div class="boxes">
<div class="question">Q4</div>
<div class="answer">
<button>Yes</button>
<button>No</button>
</div>
</div>
</div>

Unable to align the second flexbox column to the left

My problem is this: I have a flexbox that places a summary section and an image section in a row. The summary section is a nested flexbox that displays the 3 lists as the first column and the horizontal soiltype list as the second column. The problem is that the content of the second column is placed in the center while i want it to align to the left at the same starting position as the lists column above. Here is an image of the current situation:
I have tried using justify-content: flex-start, align-items: flex-start, margin-left: 0px; margin-right: auto; and margin-left:-500px, but everytime the second column remains fixed in the center. Can anyone please tell me what i should do to move the content of the second column to the right? Thank you,
Here is the code:
HTML:
<div class="flexBox flexItem">
<div class="summary">
<div class="flexBox flexItem test">
<ul class="details">
<li><strong>Days until harvest:</strong> {{seedDetails.growthTime}}</li>
<li><strong>Required sun exposure:</strong> {{sunExposure}}</li>
<li><strong>Plant height:</strong> {{seedDetails.plantHeight | measure : distancePipeArgument : true}}</li>
<li><strong>Plant width:</strong> 15 inch</li>
</ul>
<ul class="details">
<li><strong>Germinates after:</strong> 14 days</li>
<li><strong>Germination temperature:</strong> {{seedDetails.growthTemperature | measure: temperaturePipeArgument : true}}</li>
<li><strong>Row spacing:</strong> {{seedDetails.rowSpacing | measure : distancePipeArgument : true}}</li>
<li><strong>Plant spacing:</strong> {{seedDetails.plantSpacing | measure : distancePipeArgument : true}}</li>
</ul>
<ul class="details">
<li><strong>Sow depth:</strong> {{seedDetails.sowDepth | measure : distancePipeArgument : true}}</li>
<li><strong>Life cycle:</strong> {{seedDetails.lifeCycleType | titlecase}}</li>
<li><strong>Hardy at:</strong> {{seedDetails.hardiness | measure: temperaturePipeArgument : true}}</li>
<li><strong>Maximum temperature:</strong> {{seedDetails.maximumTemperature | measure: temperaturePipeArgument : true}}</li>
</ul>
</div>
<div class="soils">
<ul>
<li class="inline"><strong>This plant grows well in:</strong></li><li class="inline">
<mat-chip-list>
<mat-chip style="margin-right:8px; background-color:aquamarine;" *ngFor="let soilType of soilTypes" [selectable]="selectable" (click)="showDialog(soilType)">
{{soilType}}
</mat-chip>
</mat-chip-list></li>
</ul>
</div>
</div>
<figure class="carousel">
<div class="crop shadow">
<input type="image" [src]="seedDetails.imagePreview" class="thumbnail" (click)="showDialog(image)"/>
</div>
<small>Click to view full image</small>
</figure>
</div>
CSS:
.flexItem {
max-width: 1100px;
}
.flexBox{
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
}
ul.details{
margin-left: 0px;
padding-left: 0px;
flex: 1 1 300px;
}
.inline{
display: inline-block;
}
.soils{
align-items: flex-start;
}
.summary{
display:flex;
flex-direction:column;
justify-content: flex-start;
align-items: flex-start;
/* justify-content: flex-start;
text-align: left; */
width:85%;
/* align-items: flex-start; */
/* border: solid grey 1; */
}
.carousel{
width: 250px;
height: 250px;
/* overflow:hidden; */
background-color: gray;
flex: 1 1 250px;
/* margin-left: 0px; */
}
.crop{
width: 250px;
height: 250px;
overflow:hidden;
}
.shadow{
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.4);
border: 0.5px solid black;
}
.test{
width:850px;
/* border: solid black; */
}

How can I get even heights of unknown elements inside a column? [duplicate]

This question already has answers here:
Equal height flex items in flex columns
(3 answers)
Closed 5 years ago.
I'm using flex to create even columns and vh to make them the same height. That's working fine but inside the columns I can have an x number of items in them. I'd like for elements in each column to be even height depending on how many items are present (using css).
1 = 100%
2 = 50%
3 = 33.33%
etc.
I know I can do this through JS but I'd like to automate this through css via flex, grid, or something elese.
I've tried replicating your problem. Use flex: 1 on .items so that each and every item take equal space (according to the problem statement).
Have a look at the snippet below:
body {
margin: 0;
}
.parent {
width: 80%;
padding: 20px;
display: flex;
border: 1px solid red;
}
.child {
flex: 1;
display: flex;
flex-direction: column;
align-items: stretch;
justify-content: flex-end;
padding: 20px;
border: 1px solid blue;
height: 60vh;
}
.item {
flex: 1;
background: lightGreen;
border: 1px solid green;
}
<div class="parent">
<div class="child">
<div class="item">33.33%</div>
<div class="item">33.33%</div>
<div class="item">33.33%</div>
</div>
<div class="child">
<div class="item">50%</div>
<div class="item">50%</div>
</div>
<div class="child">
<div class="item">100%</div>
</div>
</div>
Hope this is what you are trying to achieve.
This is all you need to make it work with the Flexbox:
.flex-container {
display: flex;
}
.flex-item {
display: flex;
flex-direction: column;
flex: 1;
}
.item {
flex: 1;
border: 1px solid;
}
<div class="flex-container">
<div class="flex-item">
<div class="item">1/1</div>
</div>
<div class="flex-item">
<div class="item">1/2</div>
<div class="item">1/2</div>
</div>
<div class="flex-item">
<div class="item">1/3</div>
<div class="item">1/3</div>
<div class="item">1/3</div>
</div>
<div class="flex-item">
<div class="item">1/4</div>
<div class="item">1/4</div>
<div class="item">1/4</div>
<div class="item">1/4</div>
</div>
</div>