I'm trying to achieve the following with CSS Grid Layout:
A A
B B B B B B B B
C C E E E E E
D D D
F F F
I can add classes in the HTML but I cannot re-order the elements or add wrapping elements.
I have almost achieved this by using explicit grid-row values. Is it possible to position the last two rows starting at the fourth column without explicitly specifying the grid-column property individually for each element? (For brevity I've kept it to 6 here but there's more in the actual layout)
Here's what I have so far. As you can see, the two rows for E and F start on column 1.
I can add grid-column: 4 to .c13 but the subsequent elements in the row flow back to column 1.
.grid {
display: grid;
grid-template-rows: repeat(5, 2em);
grid-gap: 0.5em;
text-align: center;
}
.c2 {
grid-column: 8;
}
.c16 {
grid-column: 4;
}
.extra1 {
grid-row: 4;
}
.extra2 {
grid-row: 5;
}
.global1 { background-color: #ccc; }
.intra1 { background-color: lightblue; }
.intra2 { background-color: yellow; }
.intra3 { background-color: purple; color: white; }
.extra1 { background-color: orange; }
.extra2 { background-color: #f66; }
<p>You need a browser that supports CSS Grid Layout for this.</p>
<section class='grid'>
<div class='c1 global1'>A</div>
<div class='c2 global1'>A</div>
<div class='c3 intra1'>B</div>
<div class='c4 intra1'>B</div>
<div class='c5 intra1'>B</div>
<div class='c6 intra1'>B</div>
<div class='c7 intra1'>B</div>
<div class='c8 intra1'>B</div>
<div class='c9 intra1'>B</div>
<div class='c10 intra1'>B</div>
<div class='c11 intra2'>C</div>
<div class='c12 intra2'>C</div>
<div class='c13 extra1'>D</div>
<div class='c14 extra1'>D</div>
<div class='c15 extra1'>D</div>
<div class='c16 intra3'>E</div>
<div class='c17 intra3'>E</div>
<div class='c18 intra3'>E</div>
<div class='c19 intra3'>E</div>
<div class='c20 intra3'>E</div>
<div class='c21 extra2'>F</div>
<div class='c22 extra2'>F</div>
<div class='c23 extra2'>F</div>
</section>
You can add pseudo-elements to the .grid to block out the bits you don't want to use. CSS Grid will treat the pseudo-element as a grid-item and use up the space specified.
In your case these rules should work:
.grid:before{
content:'';
grid-column: 1 / 4;
grid-row: 4 / -1;
}
.grid:after{
content:'';
grid-column: 7 / 10;
grid-row: 4 / -1;
}
Here's an example of it for you to play with: https://codepen.io/chrisboon27/pen/Lddpqa
I added in the text and background-color to make it easier to see what is going on, but you would just remove those.
Related
I'm trying to recreate this design from frontendmentor.com.
My initial thought when I saw the design was to split the card section of the page into a 6x4 grid but so far it hasn't really worked. The grid isn't displaying the columns and rows the way I'd like. I tried building some placeholder rows in the areas where there's no content but that didn't work either.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Four Card Feature Section</title>
<link rel="stylesheet" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<main role="landing-page">
<section class="heading">
<header class="text">
<h1 class="title-text">Reliable, efficient delivery <br> Powered by technology </h1>
<p class="subtitle-text">Our Artificial Intelligence powered tools use millions of project data <br> points to ensure that your project is successful </p>
</header>
</section>
<div class="grid-container">
<!--Column 1 -->
<div class="column column-left">
<h2 class="title-card">Supervisor</h2>
<p class="subtitle-card">Monitors activity to identify project <br> roadblocks </p>
<img src="icon-supervisor.svg" class="icon" alt="supervisor-icon" /></img>
</div>
<!--Column 2 -->
<div class="column column-middle-a">
<h2 class="title-card">Team Builder</h2>
<p class="subtitle-card">Scans our talent network to create the <br> optimal team for your project </p>
<img src="icon-team-builder.svg" class="icon" alt="teambuilder-icon" /></img>
</div>
<div class="column column-middle-b">
<h2 class="title-card">Karma</h2>
<p class="subtitle-card">Regularly evaluates our talent to ensure <br> quality </p>
<img src="icon-karma.svg" class="icon" alt="karma-icon" /></img>
</div>
<!--Column 3-->
<div class="column column-right">
<h2 class="title-card">Calculator</h2>
<p class="subtitle-card">Uses data from past projects to provide <br> better delivery estimates </p>
<img src="icon-calculator.svg" class="icon" alt="calculator-icon" /></img>
</div>
</div>
</main>
</body>
</html>
CSS
* {
border: 1px solid black;
}
:root {
--gray-text: #696969;
--dark-text: #171717;
}
.column .icon {
right: -15em;
position: relative;
}
.heading {
text-align: center;
align-content: auto;
font-family: David;
}
.title-text {
color: var(--dark-text);
}
.subtitle-text {
color: var(--gray-text);
}
.column .subtitle-card {
color: var(--gray-text);
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto auto auto auto;
grid-gap: 10px;
padding: 20em;
}
/*
.empty-row-1 {
grid-column: 1 / 2;
grid-row: 1;
}
.empty-row-2 {
grid-column: 1 / 2;
grid-row: 4;
}
.empty-row-3 {
grid-column: 5 / 6;
grid-row: 1;
}
.empty-row-4 {
grid-column: 5 / 6;
grid-row: 4;
}
*/
.column-left {
grid-column: 1 / 2;
grid-row: 2 / 3;
text-align: left;
}
.column-middle-a {
grid-column: 3 / 4;
grid-row: 1 / 2;
text-align: left;
}
.column-middle-b {
grid-column: 3 / 4;
grid-row: 3 / 4;
text-align: left;
}
.column-right {
grid-column: 5 / 6;
grid-row: 2 / 3;
text-align: left;
}
I commented out the placeholder rows since they didn't work. I removed them from the html file for clutter purposes, but they were just: <div class="empty-row-x"></div>
I have 1px border on all elements just so I can better see what I'm doing. Of course that isn't meant to stick around forever.
I have a feeling that my "grid approach" is just not the easiest or "correct" way to build this design. Having the "floating" rows in columns 1 and 3 seems awkward and I haven't been able to find any such examples on the usual websites.
Thanks for any help!
Here, you have grid-template-columns: auto auto auto auto auto auto;. You also need grid-template-area property as well where you will describe how you want your grid to look like and then you apply that into elements in which you've applied grid.
For instance if I have three columns and I want it to be like:
Column1 Column2
Column1 Column3
then I have to apply grid-template-area where I will describe it as:
grid-template-areas: "item1 item2,
item1 item3"
then,I will put it in columns as well
column1 {
grid-area: item1;
}
column2 {
grid-area: item2;
}
column3 {
grid-area: item3;
}
First, it is a loop in React and assumed as a mobile version.
Within each loop of DIV, it will have a photo(150*150px) on the left-hand side.
On the photo's right-hand side, it will have 3 div and each of the div will have a p (name, car and salary). At the bottom, it will have a line and its length will be the same as the parent div.
One special is that the pof car will have many words, when the width of the phone is not enough, it will go to the next line. If it is still not enough, it will become Tesla, Honda, BMW,...
it is the Sample Image
I really try many methods(float, position,...), but I still cant deal with it,
Here is the HTML part (using React)
<div className='loop'>
<img className='image' src={value.image}></img>
<div>
<p className='title'>{value.name}</p>
</div>
<div class>
<p className='car'>Tesla, Honda, BMW, Porsch,Mitsubishi, Mazda, Toyota, Jaguar, KIA </p>
</div>
<div>
<p>{value.salary}</p>
</div>
<div className='linebreak'></div>
</div>
Try with grid :
.loop {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
column-gap: .5em;
width: 400px
}
.image {
grid-row: span 3;
}
.linebreak {
margin-top: .5em;
grid-column: span 2;
border: 2px solid #4f86f7;
}
.loop p, img {
border: 2px solid #777696;
margin: 0;
}
.title {
align-self: start;
}
.salary {
align-self: end;
}
<div class='loop'>
<img class='image' src="https://picsum.photos/100" />
<p class='title'>name</p>
<p class='car'>Tesla, Honda, BMW, Porsch,Mitsubishi, Mazda, Toyota, Jaguar, KIA </p>
<p class='salary'>salary</p>
<div class='linebreak'></div>
</div>
I have a few scenarios in my grid. I have 4 possible grid elements, but depending on a user selection from the previous screen, I might only display three of those.
I'm running into an issue where in a particular circumstance, I want to display only 3 elements (2 per row), with the third element on the bottom row placed to the far right, essentially leaving an empty space where the first element of the second row normally would be.
const MyGrid = styled(OtherGrid)`
#media (max-width: ${BP.SMALL - 1}px) {
div:nth-child(2) {
grid-row-start: 3;
}
div:nth-child(3) {
grid-row-start: 2;
}
}
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 1fr;
`;
My grid is styled from another grid, but all in all, acts like a basic grid.
<MyGrid>
<FormGroup
type={"number"}
name={"initial_moisture"}
label={"Initial Moisture (%)"}
step={0.1}
required
/>
<FormGroup
type={"number"}
name={"initial_temp"}
label={`Initial Temperature (${isMetric ? "C" : "F"})`}
step={1}
required
/>
{operatingMode != "auto_cool" && (
<>
<FormGroup
type={"number"}
name={"final_moisture"}
label={"Target Moisture (%)"}
step={0.1}
required
/>
</>
)}
{operatingMode != "auto_hydrate" && (
<>
<FormGroup
class={"auto-cool"}
type={"number"}
name={"final_temp"}
label={`Target Temperature (${isMetric ? "C" : "F"})`}
step={1}
required
/>
</>
)}
</MyGrid>
In the last possible state here (operatingMode != "auto-hydrate"), I want to place that element on the second row, but in the second column as well, and leave an empty space on the 2nd row, first column. Is there something within my parent container GoalsFieldGrid that I can define that will help me do this?
grid-column: -1; is what I'm looking for, but I'm not sure how to apply it in that specific scenario.
If I understand correctly you only require this when there are three elements only.
That being the case you can use :nth-child(3):last-child to select the element.
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: 1fr;
margin-bottom: 1em;
gap: .25em;
}
.item {
display: flex;
justify-content: center;
align-items: center;
padding: 1em;
border: 1px solid grey;
}
.item:nth-child(3):last-child {
grid-column: 2;
}
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
I have a html template like the following:
<div class="my-grid-container">
<div class="summary-card" ng-repeat="cardData in summaryCardsCtrl.summaryDetails" >
<div ng-include="'.....'"></div>
</div>
</div>
The included html looks like:
<div class="card">
<div class="card-title" id="{{cardData.label}}">{{cardData.label}}</div>
<div class="card-data">
<div class="card-ico">
.....
</div>
<div class="card-value">
<span title="{{cardData.rawValue}}">{{cardData.value}}</span>
<span>%</span>
</div>
</div>
</div>
I want the first card to span for two rows, like:
I am using CSS3 GridBox like the following:
.my-grid-container {
display: grid;
grid-template-columns: auto auto auto;
grid-gap: 10px;
padding: 10px;
}
.my-grid-container > div {
text-align: center;
padding: 20px 0;
font-size: 30px;
max-height: 70px;
}
div.my-grid-container > div.card:first-child {
grid-row: 1 / 2;
}
But it did not work till now. First div did not span two rows.
What am I doing wrong?
Your code:
div.my-grid-container > div.card:first-child {
grid-row: 1 / 2;
}
You're telling the grid item to span from grid row line 1 to grid row line 2. That spans one row.
If you want to span two rows, then use this instead:
div.my-grid-container > div.card:first-child {
grid-row: 1 / 3;
}
or this:
div.my-grid-container > div.card:first-child {
grid-row: 1 / span 2;
}
Keep in mind that in every grid the number of row lines is equal to the number of rows + 1, because the last row has an extra (final) line. The same concept applies to columns.
Firefox offers a useful tool for seeing this.
In Firefox dev tools, when you inspect the grid container, there is a tiny grid icon in the CSS declaration. On click it displays an outline of your grid.
More details here: https://developer.mozilla.org/en-US/docs/Tools/Page_Inspector/How_to/Examine_grid_layouts
I am working on the span size of a grid-column.
I have this code for my grid-columns:
.main_comp:nth-child(n+3) {
//background-color: yellow;
grid-template-columns: repeat(6, 1fr);
}
.main_comp:nth-child(n+3) .bigimg {
grid-row: 1;
grid-column: auto / span 3;
}
.main_comp:nth-childn+(n+3) .blog_art {
grid-row: 2;
grid-column: auto / span 2;
background-color: green;
}
The result I am getting is not quite what I want. I thought that:
grid-column: auto / span 2;
would span each blogart div 2 columns and three of blogart divs would span over all the 6 columns.
What I would like is something like this for all the divs from number three and onwards:
I have setup a codepen on my example and the issue I have mentioned here starts on line 66.
you need to span 2 cols. (edit similar answer as Naga Sai A, but with a different approach/selector)
you may overide your previous rule .blog_art:not(:nth-child(2)) with:
.bigimg + .bigimg ~ .blog_art {
grid-column: auto / span 2;
background: tomato;/* see us */
}
http://codepen.io/gc-nomade/pen/KmzXgx?editors=1100#0
To achieve expected result, use below option
Add below class to the blog_art
<div class="main_comp">
<div class="bigimg">image</div>
<div class="bigimg">image</div>
<div class="blog_art new">blog art</div>
<div class="blog_art new">blog art</div>
<div class="blog_art new">blog art</div>
</div>
.new:not(:nth-child(2)) {
grid-column: auto / span 2;
grid-row: 2;
background: orange;
}
Codepen URL: http://codepen.io/nagasai/pen/NjNaPX?editors=1100