CSS Grid System for Layout - html

I am developing a personal website, which is currently in a very crude state. I am working on improving the website's style.
I have finished and styled the top row, my name and the nav bar, using a file called grid.css, which can be seen in the source code of the site. I took that file from teamtreehouse.com in their "Build a Simple Website" tutorial because I thought it would be easy to implement that grid. For some reason, the grid works perfectly for the top row, with my name spanning 3 columns and the nav bar spanning 9, but when I did the same division for the image and the About Me blurb, the blurb goes down to the next row. Why?
The relevant code is below:
<div class="grid_3">
<img src="img/JayantSani.jpg" width="75%" height="75%" alt="Jayant Sani">
</div>
<div id="about" class="grid_9 omega">
<h2>About Me</h2>
<p>Hi there! I'm Jayant Sani. I'm currently a freshman at Harvard University interested in studying computer science. I expect to graduate in 2017. I like traveling, sports, and developing web and mobile apps.</p>
</div>
The grid_(number) classes come from the grid.css file, which is accessible via viewing the source of the website linked above.
Thanks for your help in advance.

The first <div class="grid_3">has a computed height in the broswer of 37 pixels and the Menu to the left has a computed height of 20px.
Your 2nd grid 3 (the image) is floating left under the 20px. because it does not have a clear:left css rule applied it is draw to the right of the first grid_3. The solution from the code recently posted is ...
<div class="grid_3" style="clear:left">
<img src="img/JayantSani.jpg" width="75%" height="75%" alt="Jayant Sani">
</div>
You used teamtreehouse.com's term CSS grid system for layout, not your fault but sparked a WTF response from me.
http://caniuse.com/css-grid CSS grid is new to CSS3 and not yet supported by browsers.
<style type="text/css">
#grid {
display: grid;
/* Two columns: the first sized to content, the second receives
* the remaining space, but is never smaller than the minimum
* size of the board or the game controls, which occupy this
* column. */
grid-template-columns: auto minmax(min-content, 1fr);
/* Three rows: the first and last sized to content, the middle
* row receives the remaining space, but is never smaller than
* the minimum height of the board or stats areas. */
grid-template-rows: auto minmax(min-content, 1fr) auto
}
/* Each part of the game is positioned between grid lines by
* referencing the starting grid line and then specifying, if more
* than one, the number of rows or columns spanned to determine
* the ending grid line, which establishes bounds for the part. */
#title { grid-column: 1; grid-row: 1 }
#score { grid-column: 1; grid-row: 3 }
#stats { grid-column: 1; grid-row: 2; justify-self: start }
#board { grid-column: 2; grid-row: 1 / span 2; }
#controls { grid-column: 2; grid-row: 3; align-self: center }
</style>
Update easiest CSS coding.
Add this CSS rule to any of the CSS files, you have to many to look though.
*[nextrow] {
clear:left;
}
Then use it as an attribute when you want to go to the next row.
<div class="grid_3" nextrow>

Related

Building a CSS grid layout with a repeating rows and a sparse header

I'm trying to use CSS grid for a layout and having trouble figuring out how to do so. Here's a sketch of the layout:
(empty) | (empty) | label | (empty)
---------------------------------------------
col1 | col2 | col3 | col4
The bit I'm having trouble with, is that I want to repeat the second row as many times as necessary.
Ideally, I'd also like to be able to just throw the child elements in the grid container and have them flow into the correct spots without having to specify grid-area on them.
That is, ideally I can produce this layout with this markup:
<div class="grid-container">
<div>label</div>
<div>col1</div>
<div>col2</div>
<div>col3</div>
<div>col4</div>
</div>
I've been looking at grid documentation for an hour or so and can't seem to wrap my head around how to do this. Any tips?
Using grid-area: 1 / 3 / 2 / 4; for our .label div. Had to add a class to it. 1 / 3 / 2 / 4 means grid-row-start / grid-column-start / grid-row-end / grid-column-end. Basically we are placing .label in the third column of the first row with it. More about it here https://developer.mozilla.org/en-US/docs/Web/CSS/grid-area
We although can use ::before as a first element with full width using grid-area: 1 / 1 / 2 / 5;. grid treats ::before like a first element.
Using z-index to set one element over another. z-index works some specific way for grid children. More here https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout (Control of overlapping content)
Other children element works without specific grid-area setting, as you can see.
.grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(20px, auto);
grid-column-gap: 1px;
grid-row-gap: 1px;
}
.grid-container::before {
content: '';
grid-area: 1 / 1 / 2 / 5;
z-index: 1;
background: cyan;
}
.grid-container .label {
grid-area: 1 / 3 / 2 / 4;
z-index: 2;
}
<div class="grid-container">
<div class="label">label</div>
<div>col1</div>
<div>col2</div>
<div>col3</div>
<div>col4</div>
<div>col1</div>
<div>col2</div>
<div>col3</div>
<div>col4</div>
</div>

How should a CSS Grid layout be re-organized/re-distribuited at a media query breakpoints?

I have made up a grid layout that consists of 3 columns wide and 3 rows tall:
.home-works {
padding: 30px;
font-size: 1.2rem;
display: grid;
grid-template-columns: 2fr 2fr 2fr;
grid-template-rows: 2fr 4fr 4fr;
grid-gap: 10px;
}
This is giving me zero problems at desktop view, but what I need to follow up with, now, is when the view port breaks, at the moment I'm working with a max-width:768px rule. So, right now, once the view port breaks to that max-width, any CSS Grid command doesn't seem to have an effect or a change. I have tried using grid-row or grid-row-start grid-column or grid-row-start but no luck.
This is my HTML for the layout:
<div class="home-works">
<div class="head">
<h1>Let's stay connected!</h1>
</div>
<div class="col-menu">
<img class="image-home" src="img/profile-picture.png" width="50%">
<ul>
<li>home</li>
<li>about</li>
<li>contact</li>
<li>downloads</li>
</ul>
</div>
<div class="main-content">
<p>This is my website and I call it, the <em>"glassless window"</em>
Why? Because using the frame on your device (mobile, desktop or laptop)
we are allowed to establish a connection thus enabling me to show you my
up and coming projects. </p>
</div>
<div class="caption-object">
<p>I really wish you could <a class="drop-a-line-link" href="#">drop me a line</a> somewhere
in the future!</p>
</div>
</div>
And this is the CSS for the distribution:
.head {
grid-column: 1 / 4;
text-align: center;
}
.col-menu {
grid-column: 1;
grid-row: 2 / 3;
}
.main-content {
grid-column: 2 / 4;
grid-row: 2 / 3;
}
.caption-object {
grid-column: 3 / 4;
grid-row: 3;
}
This is my first time going about media queries and CSS Grid, meaning this is the first time i input a grid command inside a media query rule set. I checked to see if this would happen too if I wanted to change the background-color: plum; and it did worked. I know about repeat(minmax()) but honestly I wouldn't know how to properly achieve the same look or if it would have the same 'layout design' because then I'd have to delete the grid row's and column's placement? Like I said this is my first time ever using CSS Grid with media queries, I have attached some pics, thanks!
Initially I decided not to include it because nothing had seemed to be working so I didn't have a reason to include.
#media only screen and (max-width: 768px) {
.nav-items {
flex-direction: column;
align-items: center;
}
.navbar {
height: 200px;
padding-bottom: 20px;
}
.footer-link {
align-self: center;
left: 0;
top: 0;
}
.main-container {
flex-flow: column wrap;
margin: 0 10px;
}
.drop-a-line-link {
text-decoration: underline wavy;
}
}
Media Query
To answer my own question this is what I did and its available on MDN, have to check "Redefining the grid using media queries" topic.
To reorganize a CSS Grid layout one must set up the media query rule (which in this case I had it different than on MDN archives but somehow still worked) and in there I had to reassign my grid-template-areas, which was also another thing I lacked, I was NOT using grid-areas, I had stuff like grid-row or grid-columns. Apparently this seems to be a huge factor that comes to play when we are inside our Media Query code. One thing that they do note as important, when working with grid-areas is that one should assign them, outside of any Media Query commands, to cover just one "row" or one "column", I guess depends on your current grid-auto-flow command, which at default is set as row while defining the columns and rows
So, mine is looking like this:
display: grid;
grid-template-columns: 1fr;
grid-template-rows: minmax(350px, auto);
grid-template-areas:
"header"
"menu"
"main"
"caption";
Since I had not defined any areas on my previous grid I would never have gotten it to work the way I intended for it to behave. Well, and then once in the MQ, you assign the grid as best you can, but first, you need to use grid-template-areas to re-assign the areas, and as well as your columns, using grid-template-columns, this depends on your layout and item sizes or basically it depends on the idea that you had for the grid.
So my Media Query code ended up looking like this:
#media (min-width: 500px) {
.home-works {
grid-template-columns: 2fr 2fr 2fr;
grid-template-areas:
"header header menu"
". main main"
". . caption";
}
}
#media (min-width:700px) {
.home-works {
grid-template-areas:
"header header header"
"menu main main"
". . caption";
}
}
Important: the "." are "white-space", or "negative space" or "empty cells".

Understanding grid negative values

I'm trying to make a grid that has a full span row at the bottom.
For full span columns I can use grid-column: 1/-1.
For single span columns I can use grid-column: 1/1.
For single span rows I can use grid-row: 1/1.
But if I want to define the last column or row, I have to write grid-column: -2/-1.
Why is the syntax not the same as with 1/1 for the first column/row? Or am I making a mistake somewhere?
I also made a jsfiddle to demonstrate my problem: jsfiddle
.grid-container {
display: grid;
grid-template-columns: 5px 1fr 1fr;
grid-template-rows: minmax(50px, 2fr) 1fr 1fr 1fr 1fr 1fr 15px;
}
.grid-item {
width: 1fr;
}
.header {
display: flex;
grid-column: 2/-1;
grid-row: 1/1;
justify-content: center;
}
.border-left {
background: purple;
grid-column: 1/1;
grid-row: 1/-1;
}
.border-bottom {
background: #410266;
grid-column: 2/-1;
/* grid-row: -2 / -1; this will work, -1/-1 will not */
grid-row: -1 / -1;
}
<div class="grid-container">
<div class="header"> HEADER </div>
<div class="border-left"></div>
<div class="grid-item">1 </div>
<div class="grid-item">2 </div>
<div class="grid-item">3 </div>
<div class="grid-item">4 </div>
<div class="border-bottom"></div>
</div>
The grid-column and grid-row shorthand properties count grid lines.
You wrote:
For single span columns I can use grid-column: 1/1
This doesn't make any sense. It resolves to:
grid-column-start: 1
grid-column-end: 1
So you're defining a column that goes from the starting line to the starting line.
A column has a starting line and an ending line. So to span the first column you use:
grid-column: 1 / 2
The only reason your code works as you expect is because the Grid error handling algorithm removes the end line when the start and end lines are equal.
So 1 / 1 resolves to 1 / auto, where auto represents a default span of 1.
You wrote:
But if I want to define the last column or row, I have to write grid-column: -2/-1
Yes, that's one way to do it. (You can also use positive integers, since you know the number of columns.)
You wrote:
Why is the syntax not the same as with 1/1 for the first column/row? Or am I making a mistake somewhere?
1 / 1
As mentioned above, 1/1 was invalid. It is fixed by the Grid system, resolving to 1 / auto. As a result, you span the first column.
-1 / -1
This combination of values is also invalid. It means span from the last line of the grid to the last line of the grid. Grid error handling changes the end value to -1 / auto. This takes you out of the explicit grid (because an implicit column is created) and negative values no longer apply. The negative values end where the implicit grid begins (demo).
-2 / -1
Correct syntax. So it works. Span one column starting from the penultimate line of the grid.
when using the same value inside grid-column/grid-row you will fall into this rule:
If the placement for a grid item contains two lines, and the start line is further end-ward than the end line, swap the two lines. If the start line is equal to the end line, remove the end line.ref
So saying grid-column:-1/-1 means grid-column:-1 which is grid-column:-1/auto
auto
The property contributes nothing to the grid item’s placement, indicating auto-placement or a default span of one. (See § 8 Placing Grid Items, above.)
So basiclly you said to your element to start at the last line and span one column which will create an implicit new column:
A basic example to illustrate:
.box {
display:grid;
grid-template-columns:20px 20px 20px;
grid-auto-columns:100px;
grid-gap:5px;
}
span {
grid-column:-1/-1;
height:40px;
background:red;
}
<div class="box">
<span></span>
</div>
You can see that the span is having 100px which means it create a new column inside the implicit grid and is not inside the explicit one defined by 20px
When using -2/-1 it's clear that you will consider the before the last and the last line and the element will be placed in the last explicit column:
.box {
display:grid;
grid-template-columns:20px 20px 20px;
grid-auto-columns:100px;
grid-gap:5px;
}
span {
grid-column:-2/-1;
height:40px;
background:red;
}
<div class="box">
<span></span>
</div>
Same logic apply when using positive value but you won't notice a strange behavior since you will most likely span an explicit column thinking it's correct to specify, for example, grid-column:1/1

Issue with how the elements are placed in rows in the CSS Grid Layout

I'm trying to solve a grid problem with how the elements are automatically placed in the rows not in the way I intend them to. The code is the simplest possible variation written to demonstrate the issue. The number of paragraphs is variable-length, there can be any amount of them.
div {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
p:nth-child(4n + 1) {
grid-column: 1 / span 1;
}
p:nth-child(4n + 2) {
grid-column: 2 / span 1;
}
p:nth-child(4n + 3) {
grid-column: 2 / span 1;
}
p:nth-child(4n) {
grid-column: 1 / span 1;
}
<div>
<p>Test1</p>
<p>Test2</p>
<p>Test3</p>
<p>Test4</p>
<p>Test5</p>
<p>Test6</p>
<p>Test7</p>
<p>Test8</p>
<p>Test9</p>
<p>Test10</p>
</div>
Here is the current result, with two arrows showing what I want to achieve:
And here is exactly what I want to achieve, created for presentation purposes by just reordering HTML elements in a basic grid:
Thank you in advance!
This can be solved with the grid-auto-flow: dense CSS rule on the grid parent. This has the effect that previously blank cells will be filled, rather than searching for the next available space.

Can an element be forced to the last row of an implicit grid?

I have a dynamically generated grid that, for reasons, does not have elements in an unknown number of initial rows. All of the grid container's children but the last are given what row they belong to. Is there a way to ensure that the last element is placed in the last row? Is there a grid-row-start equivalent to grid-column-start: -1?
To expand on the question, by default, the last element will probably be alone at the beginning:
.container {
display: grid;
grid-auto-columns: 1fr;
grid-auto-rows: 60px;
}
.normal-child {
background-color: blue;
}
.normal-child:nth-child(2n) {
background-color: red;
}
.normal-child--3 {
grid-row: 3 / span 1;
}
.normal-child--4 {
grid-row: 4 / span 1;
}
.normal-child--5 {
grid-row: 5 / span 1;
}
.last-child {
background-color: green;
}
<div class="container">
<div class="normal-child normal-child--3"></div>
<div class="normal-child normal-child--3"></div>
<div class="normal-child normal-child--3"></div>
<div class="normal-child normal-child--4"></div>
<div class="normal-child normal-child--4"></div>
<div class="normal-child normal-child--4"></div>
<div class="normal-child normal-child--5"></div>
<div class="normal-child normal-child--5"></div>
<div class="normal-child normal-child--5"></div>
<div class="last-child"></div>
</div>
I can assign an arbitrarily large number to the element's row-start, but that seems inelegant and there is a chance, though small, that the edge case where it breaks will be encountered.
I also have tried to figure out how to name the last row, but I wasn't able to find a way to name rows in an implicit grid.
There is actually a grid-row: -1 or grid-row-start: -1 just like there is grid-column: -1
It works pretty well as long as your within the range of your explicit grid, but stops working as soon as you get to the implicit grid. The reason is that negative numeric indexes in the grid-placement properties count from the edges of the explicit grid
See also here https://css-tricks.com/difference-explicit-implicit-grids/
The potentially is a plan to at least let items span to last row/column that has been tagged for discussion in level 3, but that doesn't rally address your case either.
But right now, there is no way to achieve what you ask with implicit grid.
There might be some (ugly) solutions but that would at least require a known amount of empty initial rows