I am building a page with grid.
And I am in a stuck with grid-template-areas.
I want that .cinema takes all space (2 column) and .why only first column.
But when I wrote .cinema twice, Chrome showed the grid-template-areas - "invalid property value"
Why does it happen?
.grid {
display: grid;
grid-gap: 0px;
grid-template-areas: "cinema" "why"
}
#media (min-width: 640px) {
.grid {
grid-template-columns: 1fr 1fr;
grid-template-areas: "cinema cinema" "why"
}
}
.cinema {
grid-area: cinema;
background: url(comigo/other/homepage-featured-new-1920x745.jpg) no repeat;
background-position: 100%;
background-size: cover;
text-align: center;
}
.why {
grid-area: why;
background: white;
text-align: center;
}
<div class="grid">
<div class="cinema">
<h3>Comigo OTT/STB solutions - redefine TV experience</h3>
<p>
<form>
<button>OUR SOLUTIONS</button>
</form>
</div>
<div class="why">
<h2> WHY COMIGO?</h2>
<h4>Comigo redefines the TV experience
<p>
<form>
<button>CONTACT US</button>
</form>
</div>
</div>
There appear to be numerous problems in your code.
First, you have form elements contained inside p elements. This is invalid HTML.
A paragraph element can contain only phrasing content. See this post and the spec.
Second, the string values of the grid-template-areas property must have the same number of columns. In your media query, the first row has two columns, and the second row has one column.
grid-template-areas: "cinema cinema" "why"
This is invalid CSS. The rule is ignored.
Try this instead:
grid-template-areas: "cinema cinema" "why ."
A period (.), or a sequence of contiguous periods (...), can be used to represent an empty grid area and maintain equal columns among strings.
See here for more details:
Grid areas not laying out properly in CSS Grid
grid-template-areas with ASCII art is not working
Related
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".
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
I'm experimenting with component driven front end frameworks, such as Angular, and finally learning CSS Grid.
My question is: is it bad practice to nest CSS Grids?
What I've done here is in my main/root component, I've used css grid to make two things: the navbar and the main content area, since navbar will be present in the entire app and also the main content.
As you can see below, the grid on the root level then another grid in the <nav-bar> component. And in the main content area, there will be many more, probably a grid in each/any Angular component I use.
********************** ******************************
* Navbar * => * img | nav | logout *
********************** ******************************
**********************
* *
* Content *
* *
**********************
Example code below:
app.component.html
<div class="container">
<div class="item-navbar"></div>
<div class="item-nav">
<nav-bar></nav-bar>
</div>
<div class="item-content">
<router-outlet></router-outlet>
</div>
</div>
<!-- With this CSS: -->
<style>
.container {
display: grid;
grid: ". nav ."
". content ."
/ 3vh auto 3vh;
row-gap: 1vh;
}
.item-navbar {
grid-area: 1 / 1 / 2 / 4;
position: relative;
z-index: -1;
background: #579C87;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
.item-nav {
grid-area: nav;
}
.item-content {
grid-area: content;
background: #D1C7B8;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
}
</style>
then
nav-bar.component.html
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" routerLink="/">
<div class="img">
<img src="logo.jpg">
</div>
</a>
</div>
<div class="navbar-menu">
<a routerLink="/dashboard" class="navbar-item">Dashboard</a>
</div>
<div class="navbar-logout">
<a routerLink="/logout" class="navbar-item">Logout</a>
</div>
</nav>
<!-- with this CSS: -->
<style>
.navbar {
display: grid;
grid-template-columns: 64px auto auto;
grid-template-rows: auto;
grid-template-areas: "image navs logout";
gap: 1vh;
}
.navbar-brand {
grid-area: image;
place-self: center / start;
}
.navbar-menu {
grid-area: navs;
place-self: center start;
}
.navbar-logout {
grid-area: logout;
place-self: center end;
}
</style>
There is nothing wrong or invalid with nesting grid containers.
The grid specification doesn't prohibit, or even admonish, against the practice. It says this:
Grid containers can be nested or mixed with flex containers as necessary to create more complex layouts.
In fact, nesting grid containers is what you must do to apply grid properties to the descendants of a top-level container, since grid layout works only between parent and child elements.
More details here:
Grid properties not working on elements inside grid container
Positioning content of grid items in primary container (subgrid feature)
It is not bad practice, it is recommended for proper display.
I have one caveat to mention, separate each nested level into its own file for debugging purposes. When nesting multiple levels deep, a single missing or misplaced </div> can significantly alter the output and will be very hard to debug. My suggestion is any further nesting also should be split out into separate components, so each level can be tested independently.
To answer your question, it is an acceptable practice to nest grid or flex components: csswg
Here is an example that demonstrates a nested grid: gridbyexample
Nesting grid containers is an acceptable practice.
I am new to CSS in general and trying out a simple grid layout. This is what I have.
CSS
.layoutGrid {
display: grid;
grid-gap: 10px;
grid-auto-rows: minMax(100px, auto);
}
.articleCard {
display: grid;
grid-template-rows: 100px 300px 100px;
grid-template-areas: "article-title"
"article-body"
"article-footer";
grid-auto-flow: row dense;
}
.articleHeader {
grid-area: article-title;
}
.articleBody {
grid-area: article-body;
}
.articleFooter {
display: grid;
grid-template-columns: 0.5fr 0.5fr;
grid-template-areas: "articleDomain articleKeypoints";
grid-area: article-footer;
grid-auto-flow: row dense;
}
.articleKeypoints {
grid-area: article-keypoints;
}
.articleDomain {
grid-area: article-domain;
}
#media only screen and (min-width: 600px) {
.layoutGrid {
grid-template-columns: repeat(3, 1fr);
}
}
#media only screen and (max-width: 600px) {
.layoutGrid {
grid-template-columns: repeat(1, 1fr);
}
}
HTML
<div id="mainContent" className="container layoutGrid">
<Card className={"articleCard"} style={{height:"500px", flex: "1 1 auto", padding: "1.25rem", boxSizing: "border-box"}}>
<CardHeader className="articleHeader">
<CardTitle>{props.articleDetails.Title}</CardTitle>
</CardHeader>
<CardBody className="articleBody">
<CardText>{props.articleDetails.Summary}</CardText>
</CardBody>
<div className="row articleFooter">
<div className="col-auto mr-auto">
<Button outline color="info">Read Keypoints</Button>
</div>
<div className="col-auto">
<CardSubtitle style={{verticalAlign: 'text-bottom'}}>
<small>{props.articleDetails.Domain}</small>
</CardSubtitle>
</div>
</div>
</Card>
</div>
There is nothing here which adds a ::before element, but in the result the first element of the grid is always a ::before element. Even the inner grid which says "Read Keypoints" has the same issue. The outer layout is in a loop but I dont think that would affect anything.
Can anyone tell how do I get around this, and also any pointers on how to improve the overall structure of the layout would be really appreciated!
Writing my comment as an answer as it seems to do the trick.
That's bootstrap.css its .container selector that adds the before and
after. If you're using grid you should either not user the class
container here (some other name) or not use bootstrap.
There is nothing wrong with ::before or ::after. Those are CSS pseudo elements/selectors that inserts something before/after the content of each selected element(s).
Here they are shown because of viewing the code dynamically in Developers tool of the browser.
Just compare it with the real source of the page - right click on the page and select View page source (the message vary in web browsers). A blank tab will appear with exact code as it was send from the server to the web browser.
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>