How can I make stackable table with CSS Grid? - html

So here is the result that I want
Is it possible to achieve that without HTML table tag with pure CSS Grid?
So this is my layout.
<div className="grid-Table">
<div className="headings">
<div>Name</div>
<div>Price</div>
</div>
<div className="contents">
<div>Name#1</div>
<div>Price#1</div>
</div>
</div>
And this is what I've tried so far with the styles.
.grid-Table {
display: grid;
background-color: #ffffff;
font-size: 20px;
grid-gap: 5px;
}
.grid-Table .headings, .contents{
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.grid-Table .contents {
grid-row-start: 2;
}
#media screen and (max-width: 600px) {
.grid-Table .headings div, .contents div {
grid-column: 1 / -1;
}
}
The PC version is fine, of course
But the mobile version is not

Related

Hide grid column with the rest of columns redistributing

everyone.
I'm trying to implement the grid column that hides when the wrapping container width goes below certain value, while the rest of columns should redistribute over the entire width:
Neither visibility: hidden, nor display: none for disappearing column did work (since the blank space is left in place of removed column, while the left column doesn't take the whole width).
My question is: how do I achieve desired behavior with pure CSS and without modifying grid-template-columns of the parent grid container?
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(100px, 1fr));
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnA {
grid-column-start: 1;
grid-column-end: 2;
}
.columnB {
grid-column-start: 2;
grid-column-end: 4;
}
#media (max-width: 800px) {
.columnA {
visibility: hidden;
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>
Simplify your code like below:
.grid {
display: grid;
grid-gap:5px;
grid-auto-columns: minmax(100px, 1fr); /* size of one column */
grid-auto-flow:column; /* column flow */
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnB {
grid-column:span 2; /* B takes 2 columns */
}
#media (max-width: 800px) {
.columnA {
display:none;
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>
If you want to keep the template (which is not needed) you can do like below:
.grid {
display: grid;
grid-gap:5px;
grid-template-columns: repeat(3, minmax(100px, 1fr));
}
.column {
background: blue;
color: #fff;
height: 150px;
display: flex;
align-items: center;
justify-content: center;
}
.columnB {
grid-column:span 2;
}
#media (max-width: 800px) {
.columnA {
display:none;
}
.columnB {
grid-column:span 3; /* B will take 3 columns when A is hidden */
}
}
<div class="grid">
<div class="columnA column">columnA</div>
<div class="columnB column">columnB</div>
</div>

CSS layout - grid or flex [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to create this layout.
https://pasteboard.co/K1C5o3k.jpg
I tried to use display: grid but the spacing was strange. What would be the best solution? Use grid or flexbox? How do I achieve this spacing using grid or flexbox?
<div class="wrap">
<div class="test-grid">
<div class="card box1">some text</div>
<div class="card box2">some text</div>
<div class="card">some text</div>
<div class="card box4">some text</div>
</div>
</div>
.wrap {
max-width: 600px;
}
.test-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 1em;
}
.card {
background-color: tomato;
width: 160px;
min-height: 220px;
}
.box1 {
margin-top: 40px;
}
.box4 {
grid-column-start: 2;
grid-column-end: 4;
grid-row-start: 2;
grid-row-end: 3;
}
On your grid layout, I use grid-template-row/columns to define the fraction amount and then grid-template-areas to layout the elements, for each child element you want to define the unique class as its grid-area. You can use gap to control the spacing between the elements. Once you define a height and width for the parent element, the children will fill in their respective fraction, along with any defined gap.
Then use a media query with flex for your mobile layout. You may need to tweek the CSS a bit to get it to look just as you want, but the following example should do the trick.
.test-grid {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 20px 20px;
grid-template-areas:
". two ."
"one two four"
"one three four"
". three .";
width: 100vw;
height: 100vh;
}
.one {
grid-area: one;
background-color: tomato;
}
.two {
grid-area: two;
background-color: tomato;
}
.three {
grid-area: three;
background-color: tomato;
}
.four {
grid-area: four;
background-color: tomato;
}
.box {
display: flex;
justify-content: center;
align-items: center;
}
#media only screen and (max-width: 600px) {
.test-grid {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.box {
width: 100%;
height: 100%;
}
}
<div class="test-grid">
<div class="one box">some text</div>
<div class="two box">some text</div>
<div class="three box">some text</div>
<div class="four box">some text</div>
</div>
Both Grid and flex will do the work, it just based on your preferences.
Snippet below will do the trick and when the screen became small (less than 500px). The grid will show as a list.
.wrap {
max-width: 600px;
}
.test-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 1em;
}
.card {
background-color: tomato;
width: 160px;
min-height: 220px;
}
.box1 {
grid-column: 1/span 1;
grid-row: 2/span 2;
}
.box2 {
grid-column: 2/span 2;
grid-row: 1/span 1;
}
.box3 {
grid-column: 3/span 2;
grid-row: 2/span 2;
}
.box4 {
grid-column: 2/span 2;
grid-row: 3/span 3;
}
#media (max-width: 500px) {
.test-grid {
display: flex;
flex-direction: column;
justify-content: space-between;
}
}
<div class="wrap">
<div class="container">
<div class="test-grid">
<div class="card box1">box1</div>
<div class="card box2">box2</div>
<div class="card box3">box3</div>
<div class="card box4">box4</div>
</div>
</div>
Here's an option using only grid. In this example we create many small grid rows (10px each) which then allows you to start each element at a specific row and adjust the boxes by 10 pixel increments.
.test-grid {
display: grid;
grid-template-columns: repeat(3, 160px);
grid-template-rows: repeat(45, 10px);
column-gap: 10px;
}
.card {
background-color: tomato;
width: 160px;
min-height: 220px;
}
.box1 {
grid-row-start: 10;
}
.box2 {
grid-row-start: 0;
grid-column-start: 2;
}
.box3 {
grid-row-start: 24;
grid-column-start: 2;
}
.box4 {
grid-row-start: 8;
grid-column-start: 3;
}
<div class="wrap">
<div class="test-grid">
<div class="card box1">some text</div>
<div class="card box2">some text</div>
<div class="card box3">some text</div>
<div class="card box4">some text</div>
</div>
</div>

CSS media query not responding in GRID

index.html
This is the index file with a hero image and hero content(title and subtitle)
<section class= 'container main-section grid'>
<div class="hero-content">
<div class="title">
<h1>Hi, I'm Megha</h1>
</div>
<div class="subtitle">
<p>I’m a software engineer, where I like spending my day with programming and a bit of designing in general.</p>
</div>
</div>
<div class='image-wrapper'>
<div class='girl-image'></div>
</div>
styles.css
Code for overlapping hero content and hero image using CSS grid.
.grid {
display: grid;
grid-template-columns: 2fr 2fr 1fr 1fr;
grid-template-rows: 1fr 2fr;
margin-top: 80px;
gap: 20px;
}
.hero-content {
grid-column: 1 / span 2;
grid-row: 2 / span 2;
z-index: 1;
margin-top: -50px;
align-content: center;
max-width: 80vh;
}
.hero-content .title {
font-family: blackjack;
font-size: 24px;
color: #16161D;
}
.hero-content .subtitle {
font-family: futurapt;
font-size: 22px;
color: #363636
}
.image-wrapper {
grid-column: 2/span 3;
grid-row: 1/span 2;
}
index.css
Code for changing responsive layout with hero content on top and image on the bottom.
#media only screen and (max-width: 1249px) {
header, .hero-content, .social-icons, .image-wrapper {
margin: 0 20px;
}
}
#media only screen and (max-width: 535px) {
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 2fr 2fr 2fr;
}
.hero-content {
grid-column: 1;
grid-row: 1 / span 2;
}
.image-wrapper {
grid-column: 1;
grid-row: 3 / span 4;
}
}
The code does not work for responsive design for max-width 535px. I've been looking for a long while. Any help would be much appreciated.
Basically I want to change layout for mobile with a single column and 4 rows. This doesn't work. Why??
I've added a bit of CSS to your girl-image class so we could visualize where it currently lands in your grid. Your hero content DOES overlap your hero image at higher viewport widths. But on mobile, the hero image is under your hero content.
.girl-image {
background-color: cornflowerblue;
height: 100%;
width: 100%;
}
This is what your mobile layout looks like right now:
If you go above 535px, you get the image below:
.grid {
display: grid;
grid-template-columns: 2fr 2fr 1fr 1fr;
grid-template-rows: 1fr 2fr;
margin-top: 80px;
gap: 20px;
}
.hero-content {
grid-column: 1 / span 2;
grid-row: 2 / span 2;
z-index: 1;
margin-top: -50px;
align-content: center;
max-width: 80vh;
}
.hero-content .title {
font-family: blackjack;
font-size: 24px;
color: #16161d;
}
.hero-content .subtitle {
font-family: futurapt;
font-size: 22px;
color: #363636;
}
.image-wrapper {
grid-column: 2 / span 3;
grid-row: 1 / span 2;
}
.girl-image {
background-color: cornflowerblue;
height: 100%;
width: 100%;
}
#media only screen and (max-width: 1249px) {
header,
.hero-content,
.social-icons,
.image-wrapper {
margin: 0 20px;
}
}
#media only screen and (max-width: 535px) {
.grid {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 1fr 2fr 2fr 2fr;
}
.hero-content {
grid-column: 1;
grid-row: 1 / span 2;
}
.image-wrapper {
grid-column: 1;
grid-row: 3 / span 4;
}
}
<section class='container main-section grid'>
<div class="hero-content">
<div class="title">
<h1>Hi, I'm Megha</h1>
</div>
<div class="subtitle">
<p>I’m a software engineer, where I like spending my day with programming and a bit of designing in general.</p>
</div>
</div>
<div class='image-wrapper'>
<div class='girl-image'></div>
</div>
</section>

Making grid responsive

Any idea of how to make this grid responsive?
This is my CSS:
body {
margin: 40px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 100px 100px 100px;
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.a {
grid-column: 1 / 3;
grid-row: 1;
}
.b {
grid-column: 3 ;
grid-row: 1 / 3;
}
.c {
grid-column: 1 ;
grid-row: 2 ;
}
.d {
grid-column: 2;
grid-row: 2;
}
HTML
<div class="wrapper">
<div class="box a">A</div>
<div class="box b">B</div>
<div class="box c">C</div>
<div class="box d">D</div>
</div>
I tried this code:
#media only screen and (max-width:500px) {
.box {
width: 100%;
margin-right: 0;
float: none;
margin-bottom: 20px !important;
}
What's the best way to accomplish this?
I agree with #Petra that you need to use fr, but use a media query if you want to display them stacked on a mobile device. You could also just change the display to block. Make sure you add these after the initial CSS so that it isn't overridden.
#media screen and (max-width: 512px) {
.wrapper {
grid-template-columns: 1fr;
}
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 1fr 1fr 1fr;
background-color: #fff;
color: #444;
}
ith CSS Grid Layout, we get a new flexible unit: the Fr unit. Fr is a fractional unit and 1fr is for 1 part of the available space.

How do I keep content centered in CSS Grid Layout?

Using CSS Grid Layout, I create a site whose layout changes a little with screen size.
Here, in order to keep the content (pink area) in the CSS Grid Layout central, I did the following styling.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.text {
color: #fff;
}
.bg {
background-color: #6c757d;
}
footer {
width: 100%;
display: grid;
grid-template-columns: minmax(20%, 1fr) auto minmax(20%, 1fr);
grid-template-rows: repeat(3, auto);
}
h1,
dl {
grid-column: 2;
background-color: pink;
}
p.h6 {
grid-row: 3;
grid-column: 3;
overflow-wrap: break-word;
}
#media (max-width: 800px) {
p.h6 {
grid-column: 2;
}
}
body>p {
text-align: center;
}
<footer class="bg text">
<h1>
heading
</h1>
<dl class="h6">
<dt>word1</dt>
<dd>desc1</dd>
<dt>word2</dt>
<dd>desc2</dd>
</dl>
<p class="h6">COPYRIGHT(C)loooooooooooooooooooooooooongtext</p>
</footer>
<p>↑<br>true center</p>
This seems to work well when the width is wide, but when the width is smaller, the pink area deviates from the "true center".
This also shows that minmax (20%, 1fr) does not work well.
How can I keep this pink area centered? Also, is there a better way than the one I thought above? (With CSS Grid Layout)
You can use grid-template-columns: 1fr auto 1fr for centering the middle column. Now add min-width: 0 on the p.h6 so that you override the default min-width: auto of grid items to allow it to shrink past content size (overflow value other than visible also works) - this allows overflow-wrap: break-word to take effect. See demo below:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.text {
color: #fff;
}
.bg {
background-color: #6c757d;
}
footer {
width: 100%;
display: grid;
grid-template-columns: 1fr auto 1fr; /* changed */
/*grid-template-rows: repeat(3, auto); <-- redundant */
}
h1,
dl {
grid-column: 2;
background-color: pink;
}
p.h6 {
grid-row: 3;
grid-column: 3;
overflow-wrap: break-word;
min-width: 0; /* added */
}
#media (max-width: 800px) {
p.h6 {
grid-column: 2;
}
}
body>p {
text-align: center;
}
<footer class="bg text">
<h1>
heading
</h1>
<dl class="h6">
<dt>word1</dt>
<dd>desc1</dd>
<dt>word2</dt>
<dd>desc2</dd>
</dl>
<p class="h6">COPYRIGHT(C)loooooooooooooooooooooooooongtext</p>
</footer>
<p>↑<br>true center</p>
Look at this rule:
p.h6 {
grid-column: 3;
}
When the width of the viewport is over 800px, the text in the p.h6 element, i.e. this: "COPYRIGHT(C)loooooooooooooooooooooooooongtext"
takes up the far right column, grid-column 3. The pink box in the center then can be very small. This is because you have set grid-template-columns for the footer element to this:
grid-template-columns: minmax(20%, 1fr) auto minmax(20%, 1fr);
In other words, the columns surrounding the pink box should be as big as possible (1fr), while the pink box should be as small as possible (auto, or the width of the text inside).
Now, when the viewport is less than 800px, the copyright text moves to the 2nd, or middle column:
#media (max-width: 800px) {
p.h6 {
grid-column: 2;
}
}
This forces the auto width of that column to be the entire width of the "loooooooongtext." That's why it overflows the viewport when you shrink it too small.
You can fix this by adding two property values to the direct children of the footer:
footer > *{
overflow-wrap: break-word;
overflow: hidden;
}
Both go in the max-width: 800px media query. Demo:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.text {
color: #fff;
}
.bg {
background-color: #6c757d;
}
footer {
width: 100%;
display: grid;
grid-template-columns: minmax(20%, 1fr) auto minmax(20%, 1fr);
grid-template-rows: repeat(3, auto);
}
h1,
dl {
grid-column: 2;
background-color: pink;
}
p.h6 {
grid-row: 3;
grid-column: 3;
overflow-wrap: break-word;
}
#media (max-width: 800px) {
p.h6 {
grid-column: 2;
}
footer{
grid-template-columns: 1fr 1fr 1fr;
}
footer > *{
overflow-wrap: break-word;
overflow: hidden;
}
}
body>p {
text-align: center;
}
<footer class="bg text">
<h1>
heading
</h1>
<dl class="h6">
<dt>word1</dt>
<dd>desc1</dd>
<dt>word2</dt>
<dd>desc2</dd>
</dl>
<p class="h6">COPYRIGHT(C)loooooooooooooooooooooooooongtext</p>
</footer>
<p>↑<br>true center</p>