clientHeight is not working in IE - html

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>

Related

How to actually arrange images in CSS GRID?

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>

Understanding auto in css grids [duplicate]

This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 2 years ago.
I am pretty new to Web development and I am trying to learn CSS grids. While learning the CSS grid I tried to make one simple layout. It has one header section, one menu section, one sidebar section, and one footer section.
I used auto while defining grid template rows for the 2nd row, and gave conatiner height as 100%, so that 2nd row will stretch fully in the remaining space left by row 1 and 2.
But it didn't work that way, i am trying to figure out why 2nd row is not stretching vertically in the remaning space left.
Here is the conatiner css in which i defined the 2nd row as auto and conatiner height as 100%.
.container {
height: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
}
fiddle link:
https://jsfiddle.net/791vtd4z/
That is because you did not give body a fixed height, yet you have .container a relative height: therefore, when the child .container simply stretches to its content height and not any further, since there's nothing absolute to compare against by using 100% (ask yourself: "100% of what?").
A solution will be to set .container { min-height: 100vh; } to fix that, which tells the element to at least be as tall as the viewport, and allow it to grow should the content inside menu or sidebar grow beyond what the viewport can contain.
* {
margin: 0;
top: 0;
bottom: 0;
font-family: sans-serif;
font-size: 1.2em;
}
title {
display: none;
}
.container {
min-height: 100vh;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
}
.Header {
background-color: beige;
grid-column: 1/-1;
}
.Menu {
background-color: red;
}
.Sidebar {
background-color: burlywood;
grid-column: 2/-1;
}
.Footer {
background-color: aquamarine;
grid-column: 1/-1;
}
<div class="container">
<div class="Header">Header</div>
<div class="Menu">Menu</div>
<div class="Sidebar">Sidebar</div>
<div class="Footer">Footer</div>
</div>
To build on Terry's answer, you can achieve your desired result by giving body a height of 100vh, you could change the height of .container to 100vh, or you could give html and body a height of 100% (and keep the 100% height of .container).
This is because 100vh gives an element the full height of the viewport regardless of the height of its parents, while setting an element's full height using a percentage (i.e. 100%) means the element takes the full height of its parent, whatever that is. So an element with a height of 100% could still be zero, if its parent has no height.
To put this another way, when setting an element's height to 100% all of its parents need to be 100% as well for that element to take up the full viewport.
html, body{
height: 100%;
}
* {
margin: 0;
top: 0;
bottom: 0;
font-family: sans-serif;
font-size: 1.2em;
}
title {
display: none;
}
.container {
height: 100%;
display: grid;
grid-template-columns: repeat(12, 1fr);
grid-template-rows: 40px auto 40px;
}
.Header {
background-color: beige;
grid-column: 1/-1;
}
.Menu {
background-color: red;
}
.Sidebar {
background-color: burlywood;
grid-column: 2/-1;
}
.Footer {
background-color: aquamarine;
grid-column: 1/-1;
}
<div class="container">
<div class="Header">Header</div>
<div class="Menu">Menu</div>
<div class="Sidebar">Sidebar</div>
<div class="Footer">Footer</div>
</div>

CSS grid with scrollable row that expands

I have a css grid with a single column and two rows.
I want the first row to expand when there is space and to scroll when there is no space.
I want the second row to remain at the bottom of the div.
I have tried using display: flex; in the first row.
HTML:
<div class="parent">
<span class="top">my<br>long<br>long<br>long<br>content</span>
<span class="bottom">always visible</span>
</div>
CSS:
body {
overflow-y: hidden;
}
.parent {
display: grid;
grid-template-columns: auto;
grid-template-rows: 1fr 0fr;
}
.top {
overflow-y: scroll;
display: flex;
flex-direction: column;
}
span {
border: solid;
}
https://jsfiddle.net/9re86f2a/
I expect the first row to scroll when there is no space, but it actually remains the same size.
I expect the first row to expand when there is space, but it actually remains the same size.
I would use the flex model for this kind of behavior even if grid does it fine ;)
html * {
box-sizing:border-box;
padding:0.25em;
margin:0;
}
body {
height:100vh;
}
.parent {
display: flex;
flex-direction: column;
max-height: 100%;
overflow: hidden;
}
.top {
flex-grow: 1;
overflow: auto;
/* style aside */
background:lightblue;
margin:2px;/* or 0 */
border:solid;
}
.bottom {
flex-shrink: 0;
/* style aside */
background:tomato;
margin:2px;/* or 0 */
border:solid;
}
/* demo purpose */
.top .demo {
display: block;
max-height: 0;
overflow: hidden;
transition: 1.5s;
}
.top:hover .demo {
max-height: 300vh;
}
<div class="parent">
<span class="top"><b>Hover me to show my long content</b>
<span class="demo"><br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content</span>
</span>
<span class="bottom">always visible</span>
</div>
There's nothing in your code that triggers an overflow condition.
In order for content to overflow, it needs to exceed a width or height limitation (e.g. height: 300px), which then triggers the scrollbar.
From MDN:
In order for overflow to have an effect, the block-level container must have either a set height (height or max-height) or white-space set to nowrap.
In other words, without a fixed height, you won't get the vertical scrollbar... in Chrome! Ironically, however, in Firefox, a product of MDN, and Edge, the MDN rule above doesn't apply, and your layout works just fine.
.parent {
display: grid;
grid-template-columns: auto;
grid-template-rows: 1fr 0fr;
grid-gap: 2px;
background-color: black;
height: 100vh;
}
.top {
overflow-y: auto;
}
span {
background-color: white;
}
body {
margin: 0;
}
<div class="parent">
<span class="top">my<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content<br>long<br>long<br>long<br>content</span>
<span class="bottom">always visible</span>
</div>
jsFiddle demo
Note on browser rendering differences: I can only speculate as to why Firefox and Edge render a scrollbar on a block-level container that doesn't have a defined height or max-height, as specified by MDN (see above). They could be engaging in an intervention or may have a different interpretation of the specification than the MDN contributors.

How to use overflow hidden on 1fr grid element

So I have this basic setup - a canvas area and an animator in a parent grid.
The parent grid is also inside another grid with one 1fr row.
I can resize the animator by dragging a resizer up and down.
canvas {
background-color: blue;
}
#grid1 {
grid-template-rows: 1fr;
}
#grid2 {
background-color: black;
display: grid;
grid-template-rows: 1fr auto;
overflow: hidden;
}
#canvas-area {
grid-row: 1;
background-color: red;
}
#animator {
grid-row: 2;
height: 200px;
}
<div id="grid1">
<div id="grid2">
<div id="canvas-area">
<canvas/>
</div>
<div id="animator"></div>
</div>
</div>
I want the canvas to be bigger than its parent and hide its overflow, but that seems to also expand the parent element.
I've already tried overflow: hidden, but that doesn't work
As a side question: I also noticed that there is a space of 4px under the canvas, why is that?
I want the canvas to be bigger than its parent and hide its overflow, but that seems to also expand the parent element.
Normally you'd add a height to the grid container so that the the 1fr in the grid-template-rows: 1fr auto is meaningful; otherwise the grid item auto-adjusts to the dimensions of its contents.
Add overflow: hidden to the grid item #canvas-area along with a fixed height to the container (say 400px as your previous jsFiddle had) - see demo below:
document.querySelector('button').onclick = () => {
document.querySelector('canvas').height = 300;
}
canvas {
background-color: blue;
}
#grid {
background-color: black;
display: grid;
grid-template-rows: 1fr auto;
width: 400px;
height: 400px; /* added a fixed height */
}
#canvas-area {
grid-row: 1;
background-color: red;
overflow: hidden; /* added */
}
#animator {
grid-row: 2;
height: 200px;
}
<div id="grid">
<div id="canvas-area">
<canvas/>
</div>
<div id="animator"></div>
</div>
<button>Change Canvas Height</button>
Note that adding min-height: 0 also does not grow the container:
document.querySelector('button').onclick = () => {
document.querySelector('canvas').height = 300;
}
canvas {
background-color: blue;
}
#grid {
background-color: black;
display: grid;
grid-template-rows: 1fr auto;
width: 400px;
height: 400px;
}
#canvas-area {
grid-row: 1;
background-color: red;
min-height: 0; /* added */
}
#animator {
grid-row: 2;
height: 200px;
}
<div id="grid">
<div id="canvas-area">
<canvas/>
</div>
<div id="animator"></div>
</div>
<button>Change Canvas Height</button>
Why so?
By default grid items have min-width: auto and min-height: auto (just like flex items). You can see some examples of of this behaviour below:
css-grid creates an imaginary column
How to make images stay within the rows of a css grid container?
and from the specs:
To provide a more reasonable default minimum size for grid items, this
specification defines that the auto value of min-width/min-height also
applies an automatic minimum size in the specified axis to grid items
whose overflow is visible and which span at least one track whose min
track sizing function is auto.
W3C
Space below canvas element?
I also noticed that there is a space of 4px under the canvas, why is that?
That is the whitespace, a characteristic of inline elements - you can remove that by making it a block element (add display: block) or adjusting vertical-align property (add vertical-align: top):
document.querySelector('button').onclick = () => {
document.querySelector('canvas').height = 300;
}
canvas {
background-color: blue;
display: block; /* added */
}
#grid {
background-color: black;
display: grid;
grid-template-rows: 1fr auto;
width: 400px;
height: 400px;
}
#canvas-area {
grid-row: 1;
background-color: red;
min-height: 0; /* added */
overflow: auto; /* added */
}
#animator {
grid-row: 2;
height: 200px;
}
<div id="grid">
<div id="canvas-area">
<canvas/>
</div>
<div id="animator"></div>
</div>
<button>Change Canvas Height</button>

Prevent grid area from expanding causing whole page to scroll

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/