I am using the new css grid like this:
#site {
display: grid;
grid-template-columns: 10% 1fr 1fr 1fr 10%;
grid-template-rows: 100px auto;
grid-template-areas:
". header header header ."
". content content sidebar ."
}
So I have tow rows and 5 columns but only 3 columns with content. I'm using the dot in the template areas to define a white space.
This results in having a 3 column layout with white space on the left and right side.
If I place an element in a grid area that has a background color the white space left and right stays white (logically).
What I want is a full width background (color) but I'm not really sure how to realise this. One option I have in mind is to have a second grid in the background that has the same columns and rows but not the white spaces and then I can fill it up with color but I think this is not best practice.
Best I have found is put the grid inside a container for a certain width to center the content. And have items you need to extend the background give a huge left/right padding, and same margin negative.
Just be sure to give body an overflow-x: hidden;
<div class="container">
<div id="site">
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
</div>
And the CSS:
.container{
width:1000px;
margin: 0 auto; //
}
#site {
display: grid;
grid-template-columns: 10% 1fr 1fr 1fr 10%;
grid-template-rows: 100px auto;
grid-template-areas:
". header header header ."
". content content sidebar ."
}
.header{
background: red;
padding: 0 3000px;
margin: 0 -3000px;
}
body{
overflow-x: hidden;
}
I see 3 options here
You can set one or multiple backgrounds using CSS background color. Also this way you can set gradients and solid color can be imitated using gradients.
Create grid item with background and manually set grid-row and grid-column with values that you need. This items should have negative z-index to be overlapped by other grid items (z-index is working even for statically positioned for grid items, the same is true about flex items).
Absolutely positioned elements of grid container.
It sounds like what you're looking to do may be best addressed by the upcoming Subgrid feature, arriving in Level 2 of CSS Grid: this will allow outer elements and their children to both be laid out using the same grid.
As of today (Aug 8th, 2019) Subgrid has shipped in Firefox nightly, so will hopefully land in a real release soon (tracked here). Unfortunately, there hasn't been much movement yet from the Chrome team (please star the issue in the Chrome bug tracker to show your support)
In lieu of Subgrid arriving, what I've done is either define the same grid lines inside the container element, or, for the specific case of a full-width background, define a padding on the wrapper element that is equal in size to the width of the "empty" gutters on either side of the page. This is easiest/most reliable if you use vw units, and is fairly straightforward with the use of a variable in SASS or LESS
Related
I have a grid markup like that
HTML
<div class="parent">
<aside>{...}</aside>
<main>{...}</main>
</div>
Styles:
.parent {
display: grid;
grid-template-columns: auto 1fr;
}
The problem is the content inside <main> flows over.
I tried to assign width and max-width: they work in pixels. But when assigned as percentages don't work and flow over the page.
See this screenshot:
the container is bordered in lime color.
The element that has a problem is bordered in yellow.
I hope I explained it clearly
I have a css grid. I would like the elements in the grid to have a minimum grid gap of 35 px. I would like the elements to have a maximum width of 286 pixels. If the space between elements is greater than 35 pixels, I would like the space between elements to be the maximum. I created a picture below to illustrate what I want.
The green shows the grid.
The blue shows the minimum gap between boxes, After the gap get's below this grid, the boxes should go on a new line or start shrinking.
Currently I am getting the result on top, but I would like the result on the bottom. I want the elements to be pushed to the sides of the grid. Currently there is extra space between the right most element and the grid.
This is the code I'm using which currently produces these results
.container: {
display: grid;
grid-gap: 35;
grid-template-columns: repeat(auto-fit, minmax(286px, 1fr));
},
To maximize space between content use justify-content:
.container {
justify-content: space-between;
}
I have a parent section div with a max-width of 1760px.
I can put a carousel directly inside a section container and it will take the width of the viewport up to 1760px i have set, works as expected. *carousel will try to fill 100% of space given.
However, the issue is that i want to put the content inside a 2 col grid, inside container, but the first part of the grid has the carousel that takes the max-width of parent section, rather than stopping at width of page. So, rather than take 2fr of the viewport (map takes 1fr), it fills whole of 1760px so the screen overflows.
Style wise, The best example i can find online to show what i mean is Airbnb listing, it has 2 cols, 1 with listing and 1 with map. This is pretty much what i am trying to replicate.
Here is the carousel directly in section (pretty simple and works as explained above). If i put the carousel inside this it doesn't overflow page.
<section>
<div>Carousel</div>
</section>
section{
max-width: 1760px;
padding: 50px 40px;
margin: 0 auto;
}
Once i add it inside a grid it ignores the viewport size and simply fills max-width of section (1760px) and overflows viewport width.
<section>
<div class="grid">
<div>Carousel</div>
<div>Map</div>
</div>
</section>
.grid{
display: grid;
grid-template-columns: 2fr 1fr;
grid-gap: 20px;
}
It actually works using grid-template-columns: 60% 40%; instead of 2fr 1fr, and removing margin: 0 auto. But this means i cannot use gap (which is fine).
To summerize, how can i use fr sizing and make sure it takes notice of viewport size, and not just take up the max-width value by default.
I went through your pen and made some changes and it gave the result as you wanted it to be, no overflowing of the image.
If you do following changes, it will work for you too:
These are not mandatory, if you wish you can do the changes or else you can keep as it is.
Remove the max-width: 1760px from section style.
Add max-width: 1760px to the grid element, since you are providing the max-width to the grid, the parent section will also have this max-width, since grid is the child element.
Now make sure you are applying the width: 100% to the images (This is mandatory). Like this:
.listing > img {
width: 100%;
}
OR, if you have nested elements inside .listing element and img tag is not the immediate child of the .listing element, then you can go with this way:
.listing img {
width: 100%;
}
So every img tag which is direct or indirect descendent of .listing element will have width 100%
Here's the working piece of example:
https://codepen.io/prathameshkoshti/pen/KKMYoWY?editors=0100
I am trying to use an implicit CSS grid to generate a layout for the following basic HTML structure:
<div class='row'>
<textarea></textarea>
<div></div>
</div>
where the .row div is a CSS grid with an auto-flow set to column for automatically placing elements as columns:
.row {
display: grid;
grid-auto-flow: column;
}
I would expect, as with most elements, that the CSS grid would provide equal space to both the textarea and the div elements along the row. But instead, the layout looks like this:
The textarea takes up more space along the row than expected. When you try to resize the textarea, I see the following:
What seems to be happening here is the grid is adding additional space to the right of the textarea equal to the width of the div on the right. What I can't figure out is why this is happening, and why the elements don't initially have an equal width. What am I missing here?
I've created a simple JSFiddle for testing this behavior here.
To make them the same size you need to ask the grid to do that
grid-auto-columns:1fr;
You can stop the user resizing the textarea with resize:none
If you want to get this to work whilst letting the user resize, I couldn't find a css solution
I had an idea but I couldn't get it to work.
The gist was
have a set of [invisible] divs as a first row
have a function that can be called on an element of a grid to see if its offsetWidth is lesser to one of the hidden divs of the same column
if it is, manipulate the css from auto to setting the width explicitly to the textarea's for that column, then with some mix of repeat(x, 1fr) (pre-textarea columns) & repeat(auto-fill, 1fr) (post-textarea columns)
then attach this function to the resize (or mouseup) of the textarea
Alternatively, consider flex.
It will have the opposite problem; it wont force an element to be 1fr (and apply that unwanted padding), but I dont think you can ask it to be 1/<number in row> in size [in css only] either.
why the elements don't initially have an equal width. What am I missing here?
textarea has a width initially defined by cols which has a default value equal to 20
cols
The visible width of the text control, in average character widths. If it is specified, it must be a positive integer. If it is not specified, the default value is 20.
This width play a role in defining the initial width of the textarea. You can set a small value to make sure it behave almost the same as div.
.row {
display: grid;
grid-auto-flow: column;
}
.row > div {
border: 1px dotted;
}
<div class='row'>
<textarea cols=1></textarea>
<div></div>
</div>
You can still notice a small difference since the textarea is not having an initial width exactly equal to 0 and it also has some padding so its column will logically be a little bigger.
To avoid this and to also fix the resize issue better explicitely define the grid like below where you set the initial width of the textarea to be half the width of grid.
I don't know your real use case but I will consider the fact that your grid is full page width (I will also consider the default body margin)
.row {
display: grid;
grid-template-columns:auto 1fr;
}
.row > div {
border: 1px dotted;
}
textarea {
width:calc(50vw - 16px);
box-sizing:border-box;
}
<div class='row'>
<textarea ></textarea>
<div></div>
</div>
Using CSS Grid, this is what I am trying to achieve:
I've tried with:
nav {
display: grid;
grid-template-columns: auto 10%;
}
But that 10% might still be smaller, depending on the content that's on that column. How can I make it as small as possible whilst being a width-variable field?
You can do that with Grid by using max-content or min-content.
nav {
display: grid;
grid-template-columns: auto max-content;
}
max-content
Is a keyword representing the largest maximal content
contribution of the grid items occupying the grid track.
min-content
Is a keyword representing the largest minimal content contribution of
the grid items occupying the grid track.
See grid-template-columns.