I have an svg image (with the class content__img) has a default width of 760.7 and height of 687.08,
in the grid container there are 2 columns and 2 rows of `` `1fr```, this image is found
in the first cell, and since the image size is bigger than the first row,
the image enlarges the height of the row:
taking this into account
1.- If I specify that the image has a height
from 100% the image does not fit the height of the first row
Why is this happening? Shouldn't it be the size of the row at that moment?
Because with block type elements (and the other elements in general)
if they take the size of the current row, as far as I know, by default they take the width and height of the cell
(it also doesn't work assigning display: block to the image)
HTML:
<body>
<div class="content">
<img class="content__img" src="../../assets/images/test.svg" alt="Test">
</div>
</body>
CSS:
.content {
width: 80%;
height: 80%;
background-color: beige;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.content__img {
height: 100%;
}
2.- If I wrap the image in a container div
(with class content__img-box), this also doesn't work, despite
that the div takes the width and height of 100% of the cell, therefore, if I set the height of the image to 100%, why does the image
doesn't take the 100% from the div (content__img-box)?
HTML:
<body>
<div class="content">
<div class="content__img-box">
<img class="content__img" src="../../assets/images/test.svg" alt="Test">
</div>
</div>
</body>
CSS:
.content {
width: 80%;
height: 80%;
background-color: beige;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
}
.content__img {
height: 100%;
}
This is the result I want (obviously you can give a fixed or non-dynamic size to the row and that works, but the purpose is that the image is attacked if the grid container grows):
As promised, the explaination:
The grid-template-rows: 1fr 1fr; will not work as you intend to. Unfortunatly 1fr as template-row is counter-intuitive. It will not care for the parents height at all. 1fr 1fr will take the heighest row height of both rows and add the same height for the other row aswell. As such the containers height will be overwritten and as such broken. for 50% 50% to work, you need to to give the grid-contaienr a specific height!
I wrapped the images inside a <div>. The whole reason to do this, is to add a the object-fit property. This will allow me to resize the image to fit inside the containing <div> without breaking its aspect-ratio and without being clipped. I added a max-height-width: 100%; to the image itself. This will down-size the image to fit inside the container (not overflow the container). But also allows the image to be smaller then the container. If I wouldnt add this but use a fixed 100%, the image aspect-ratio would be changed as the image then would fill the entire height and width no matter of the aspect ratio.
Also I added display:flex, justify-content: center; align-items: center;. This will move the image into the center of the grid-card if the image does not fill out the entire grid-card.
.content {
height: 100vh;
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 50% 50%;
}
.content > div {
display: flex;
justify-content: center;
align-items: center;
object-fit: contain;
}
.content > div > img {
max-height: 100%;
max-width: 100%;
}
/*for demonstration purpose only */
body {
margin: 0;
}
.content > div {
border: 2px solid red;
}
<div class="content">
<div>
<img src="https://via.placeholder.com/1024x720.svg">
</div>
<div>
<img src="https://via.placeholder.com/800.svg">
</div>
<div>
<img src="https://via.placeholder.com/1920x1080.svg">
</div>
<div>
<img src="https://via.placeholder.com/150x300.svg">
</div>
</div>
Related
Goal is to build a page the expands the height of the main content to remaining height of page but not to exceed the visible area. Instead it should max out and start vertically scrolling instead.
Is this possible in css grid without using max-height: 80vh for example? I don't always know what the max-height should be. (.app-main is large content that should expand but be capped at remaining height and then start scrolling vertically.)
body {
display: grid;
grid-template-rows: auto 1fr auto;
grid-row-gap: 1em;
height: 100vh;
}
.app-main {
height: 1800px;
background-color: yellow;
overflow-y: auto;
}
<header>
<h1>Header</h1>
</header>
<section class="app-main">
<p>
my large content
</p>
</section>
<footer>
<h2>Footer</h2>
</footer>
Setting the height on the children of section will achieve what you want. For example:
body {
display: grid;
grid-template-rows: auto 1fr auto;
grid-row-gap: 1em;
height: 100vh;
}
.app-main {
height: 100%;
background-color: yellow;
overflow-y: auto;
}
.app-main p {
height: 1200px;
}
I'm using the following grid layout:
grid-template-columns: 10em 1fr 10em;
grid-template-rows: 2em 1fr 2em;
To create a centered area that fills most of the screen while leaving some padding around it. Inside this 1fr x 1fr grid area is a pane div which contains an editor div which contains a content div.
The content div can be any height, and the editor div has overflow: scroll set. My problem is that instead of pane staying the same size and editor handling the overflow, pane grows and causes the whole page to scroll.
I can keep pane from growing by setting its overflow: scroll, but this causes the editor itself to scroll, rather than its content. This is unacceptable because the editor has buttons which must always be on screen.
Is there a way, within grid layout, to allow this functionality? I originally had it working with a flex layout, where the pane div was a single item within a 100% x 100% flexbox. I switched to grid to allow me to easily resize side-menus, so implementing this without grid is not preferable.
Also, multi-browser support would be amazing, but my target browser is Chrome.
Here's a jsfiddle with my reproducing my problem.
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#site {
width: 100%;
height: 100%;
background-color: #000;
display: grid;
grid-template-rows: 10em 1fr 10em;
grid-template-columns: 2em 1fr 2em;
grid-template-areas:
'top top top'
'lpn mid rpn'
'bot bot bot';
}
#pane {
grid-area: mid;
height: 100%;
width: 100%;
background-color: #f0f;
}
#editor {
display: relative;
overflow: scroll;
}
#content {
height: 2000px;
}
<div id='site'>
<div id='pane'>
<div id='editor'>
<div id='content'>
</div>
</div>
</div>
</div>
min-width: auto / min-height: auto
Generally speaking, a grid item cannot be smaller than its content. The default minimum size of grid items is min-width: auto and min-height: auto.
This often causes grid items to overflow their grid areas or grid containers. It also prevents scrollbars from rendering on the items, since an overflow condition can't be triggered (the grid item just keeps expanding).
To override this default (and allow grid items to shrink past their content size) you can use min-width: 0, min-height: 0 or overflow with any value other than visible.
This behavior, with references to official documentation, is explained in this post:
Prevent content from expanding grid items
1fr
Another thing to note is that 1fr means minmax(auto, 1fr). This means, again, that the track to which it is applied cannot shrink below the content size (i.e., the min value in the minmax() function is auto, meaning content-based).
Therefore, to override this setting, use minmax(0, 1fr) instead of 1fr.
More details here: https://github.com/w3c/csswg-drafts/issues/1777
revised demo (tested in Chrome, Firefox and Edge)
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#site {
width: 100%;
height: 100%;
background-color: #000;
display: grid;
/* grid-template-rows: 10em 1fr 10em; */
grid-template-rows: 10em minmax(0, 1fr) 10em; /* new */
grid-template-columns: 2em 1fr 2em;
grid-template-areas:
'top top top'
'lpn mid rpn'
'bot bot bot';
}
#pane {
grid-area: mid;
height: 100%;
width: 100%;
background-color: #f0f;
overflow: auto; /* new */
}
#editor {
/* display: relative; */
/* overflow: scroll; */
}
#content {
height: 2000px;
}
<div id='site'>
<div id='pane'>
<div id='editor'>
<div id='content'></div>
</div>
</div>
</div>
jsFiddle demo
Not 100% sure if this is what you're asking. I added a wrapper to content to make it scrollable, and set a vh height on it, which you could adjust.
#content-scroll {
height: 40vh;
overflow: scroll;
}
#content {
height: 2000px;
}
<div id='site'>
<div id='pane'>
<div id='editor'>
<div id='content-scroll'>
<div id='content'>
</div>
</div>
</div>
</div>
</div>
https://jsfiddle.net/16owL8x0/
I have a parent and child element and sets the parent element height as 100%.
When i check the child element height it show some value in chrome browser.
But in IE browser it shown as 0. what i made wrong and how can i get the height value.
<div id='parent'>
<div id="child"></div>
</div>
/* Styles go here */
#parent{
height: 100%;
min-height:100%;
min-width:100%;
background-color:red;
display:grid;
display: -ms-grid;
align-items:stretch;
position:relative;
}
i have used clientHeight to find the element height.
document.getElementById(''child").clientHeight
Sample Link https://jsfiddle.net/zc39px72/
You need to specify how the grid will act and repeat, cause you are using grid to make the child element to get the full width and height of its container.Also you need to get the element heigh by using offsetHeight (or width using offsetWidth).
Check the following snippet:
var child = document.getElementById('child');
child.innerHTML = 'My height is: ' + child.offsetHeight;
html, body {
height: 100%;
margin: 0;
}
#parent{
height: 100%;
min-height:100%;
min-width:100%;
background-color: red;
display: grid;
display: -ms-grid;
align-items: stretch;
position: relative;
-ms-grid-columns: 1fr;
grid-template-columns: repeat( 1, 1fr );
-ms-grid-rows: 100%;
grid-template-rows: repeat( 1, 100% );
}
<div id="parent">
<div id="child"></div>
</div>
I'm trying to make .container (the div with yellow border) take the full width of its parent (body), that is screen width, I don't know what makes it narrow and centered like that
.container {
background: url("https://image.ibb.co/e7L09w/rsz_pexels_photo_540518.png") no-repeat fixed center bottom;
background-size: cover;
display: grid;
grid-template-columns: 1fr;
grid-template-rows: 120px 1fr 150px;
border: 2px solid yellow;
width: 100%;
height: 100%;
See pen below :
https://codepen.io/mrassili/pen/wPxpgL
As #Temani Afif said, you are using Bootstrap, and therefore the class .container will give the div a max-width.
Use the class container-fluid instead, it has no max-width, thus the width will be screen-sized.
I have a CSS grid layout with a bunch of areas and a photo container.
I don't know how to:
control the size of the photo, so that it is contained within the area of the grid
keep the width of the photo at 100% (thus equal to its container) and scale the height of the container to fit the photo. Basically, when the window becomes smaller, the width of the photo becomes smaller, and so does the height - pulling the tag, album, and rotate elements up.
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 40vh 30vh 30vh;
grid-gap: 10px;
grid-template-areas:
"info photo photo photo photo"
"comment photo photo photo photo"
"comment tag tag album rotate"
}
.photo {
grid-area: photo;
background: yellow;
}
.photo>img {
object-fit: cover;
width: 100%
}
.info {
grid-area: info;
background: pink;
}
.tag {
grid-area: tag;
background: teal;
}
.comment {
grid-area: comment;
background: green;
}
.album {
grid-area: album;
background: red;
}
.rotate {
grid-area: rotate;
background: blue;
}
<div class="container">
<div class="photo">
<img src="http://wallpaper-gallery.net/images/image/image-13.jpg" />
</div>
<div class="info">info</div>
<div class="tag">tag</div>
<div class="comment">comment</div>
<div class="album">album</div>
<div class="rotate">rotate</div>
</div>
You have two different problems here.
I'll address the first one, which is to contain the image in its container. You almost had it.
Your code:
.photo > img {
object-fit: cover;
width: 100%;
}
You just needed to specify a maximum height on the image so it could not overflow the container:
.photo > img {
object-fit: cover;
width: 100%;
max-height: 100%;
}
JSFiddle demo
The second problem, which is to scale the size of the image container, and drag up the grid items below when the image gets smaller, is significantly more complex.
This isn't an issue relating to the image. In fact, you can remove the image altogether when trying to solve this problem.
This is an issue of dynamically sizing a grid item (the image container). Why would this grid item change size in relation to the image size, when its size is being controlled by grid-template-columns and grid-template-rows?
In addition, why would the bottom row of grid items (tag, album, rotate) follow the image container either up or down? They would have to exit their row.
Scaling the entire grid container wouldn't be a problem. But it seems like you only want to scale one grid item (the image container). It's tricky. You're probably looking at additional containers, auto values for lengths, and possibly scripting.
Here's what happens if you give the image rows an auto value: JSFiddle demo
What if you use a background-image inside one of the grid cells rather than an IMG tag (haven't used display: grid yet b/c it's so new - cool!)
Then using background-size and background-position, you can size it properly within that cell.
.container {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-template-rows: 40vh 30vh 30vh;
grid-gap: 10px;
grid-template-areas: "info photo photo photo photo" "comment photo photo photo photo" "comment tag tag album rotate"
}
.photo {
grid-area: photo;
background: yellow;
height: 100%;
background-size: cover; /* <-- background size */
background-position: center; /* <-- background position */
}
.info {
grid-area: info;
background: pink;
}
.tag {
grid-area: tag;
background: teal;
}
.comment {
grid-area: comment;
background: green;
}
.album {
grid-area: album;
background: red;
}
.rotate {
grid-area: rotate;
background: blue;
}
<div class="container">
<div class="photo" style="background-image: url('https://thumbs.web.sapo.io/?epic=YmIzAEUIMb3pue+Zz8qV8QS/WuKmq0vrL/lWiluSn7SstKeeh7/UTTBAuDlhHFD6YC9+vaCHBQuNOXeVaHkjzTSE8tF3hMBev6512ha92Yc4kRw=&W=1200&H=627&crop=center&delay_optim=1')">
</div>
<div class="info">info</div>
<div class="tag">tag</div>
<div class="comment">comment</div>
<div class="album">album</div>
<div class="rotate">rotate</div>
</div>
I have a slight correction which works for any combination of aspect ratio of both css-grid cell and src img. (As the accepted solution only works if the aspect ratio of the cell is greater than the aspect ratio of the image). It's very simple:
.photo > img {
object-fit: cover;
width: 100%;
height: 100%;
}
You probably need to add explicit width: 100% to the image