Safari: VH units applied to parent element doesn't allow 100% height in child?
This is a known bug with vh
and vw
in Safari. You can fix it by setting height: inherit
on the inner element:
.inner {
height: inherit;
}
http://jsfiddle.net/24hZQ/47/
safari: height:100% not executing
In the #signup-login-forms form, changing height:100%
to height:inherit
solved the problem. This allows me to keep the height of #signup-login-forms
measured in vh.
Child inside parent with min-height: 100% not inheriting height
This is a reported webkit (chrome/safari) bug, children of parents with min-height can't inherit the height property: https://bugs.webkit.org/show_bug.cgi?id=26559
Apparently Firefox is affected too (can't test in IE at the moment)
Possible workaround:
- add position:relative to #containment
- add position:absolute to #containment-shadow-left
The bug doesn't show when the inner element has absolute positioning.
See http://jsfiddle.net/xrebB/
Edit on April 10, 2014
Since I'm currently working on a project for which I really need parent containers with min-height
, and child elements inheriting the height of the container, I did some more research.
First: I'm not so sure anymore whether the current browser behaviour really is a bug. CSS2.1 specs say:
The percentage is calculated with respect to the height of the
generated box's containing block. If the height of the containing
block is not specified explicitly (i.e., it depends on content
height), and this element is not absolutely positioned, the value
computes to 'auto'.
If I put a min-height on my container, I'm not explicitly specifying its height - so my element should get an auto
height. And that's exactly what Webkit - and all other browsers - do.
Second, the workaround I found:
If I set my container element to display:table
with height:inherit
it acts exactly the same way as if I'd give it a min-height
of 100%. And - more importantly - if I set the child element to display:table-cell
it will perfectly inherit the height of the container element - whether it's 100% or more.
Full CSS:
html, body {
height: 100%;
margin: 0;
}
#container {
background: green;
display: table;
height: inherit;
width: 100%;
}
#content {
background: red;
display: table-cell;
}
The markup:
<div id="container">
<div id="content">
<p>content</p>
</div>
</div>
See http://jsfiddle.net/xrebB/54/.
Prevent child element from stretching parent: portable solution for both Chrome & Safari?
Here is a simplified example (I removed a couple elements from your code just to make it easier to read). The scroll element needs two things: a parent with overflow:hidden, and an ancestor with a height property (can't be auto). Then to center the non-overflowing content, just use flexbox on the parent, and margin:auto on the content element.
*** UPDATE
A better explanation of what is going on with your code:
- You want to center a content block while making the parent hide its overflow if any.
- For overflow to work it needs a parent with a
height
otherwise it will not know where to cut off the content. - To vertically center the content box within the available space, set the parent to
display:flex
. - The important part: the content block has to be centered using
margin:auto
otherwise when there is overflow, it will remain centered with its top and bottom parts being cut-off by the parent'soverflow:hidden
.
body,
html {
margin: 0;
padding: 0;
height: 100%;
}
.page {
/* Set height for overflow element ancestor */
height: 100%;
max-height: 100vh;
display: flex;
background: blue;
justify-content: center;
}
.central-column {
flex-basis: 100%;
max-width: 90%;
display: flex;
flex-direction: column;
height: 100%;
}
.topbar {
height: 20%;
flex-shrink: 0;
background: red;
}
.cardbar {
flex-grow: 1;
display: flex;
/* Parent of the scroll element hide overflow */
overflow: hidden;
}
.cardtable {
padding: 20px;
background: white;
display: flex;
flex-basis: 100%;
}
.card {
background: cyan;
padding: 30px;
/* Margin auto to center the content */
margin: auto;
text-align: center;
}
.bottombar {
height: 20%;
flex-shrink: 0;
background: red;
}
<div class="page">
<div class="central-column">
<div class="topbar">
</div>
<div class="cardbar">
<div class="cardtable">
<div class="card">
<div class="content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.Lorem ipsum dolor sit amet, consectetur adipiscing elit.
</div>
</div>
</div>
</div>
<div class="bottombar"></div>
</div>
</div>
CSS3 100vh not constant in mobile browser
Unfortunately this is intentional…
This is a well know issue (at least in safari mobile), which is intentional, as it prevents other problems. Benjamin Poulain replied to a webkit bug:
This is completely intentional. It took quite a bit of work on our part to achieve this effect. :)
The base problem is this: the visible area changes dynamically as you scroll. If we update the CSS viewport height accordingly, we need to update the layout during the scroll. Not only that looks like shit, but doing that at 60 FPS is practically impossible in most pages (60 FPS is the baseline framerate on iOS).
It is hard to show you the “looks like shit” part, but imagine as you scroll, the contents moves and what you want on screen is continuously shifting.
Dynamically updating the height was not working, we had a few choices: drop viewport units on iOS, match the document size like before iOS 8, use the small view size, use the large view size.
From the data we had, using the larger view size was the best compromise. Most website using viewport units were looking great most of the time.
Nicolas Hoizey has researched this quite a bit: https://nicolas-hoizey.com/2015/02/viewport-height-is-taller-than-the-visible-part-of-the-document-in-some-mobile-browsers.html
No fix planned
At this point, there is not much you can do except refrain from using viewport height on mobile devices. Chrome changed to this as well in 2016:
- https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/BK0oHURgmJ4
- https://developers.google.com/web/updates/2016/12/url-bar-resizing
Safari height 100% element inside a max-height element
This issue happens due to a reported bug in Webkit:
Bug 26559 - When a block's height is determined by min-height/max-height, children with percentage heights are sized incorrectly
This seems to be fixed for Chrome by now, but not for Safari.
The only non-JavaScript workaround that worked for me, is using an absolute positioning on the parent element:
div {
position: absolute;
}
Demo
Try before buy
height:100% works in Chrome but not in Safari
Your flex container (.flex-box
) has a defined height
of 500px.
Your splitter (.handle-inner
) has a defined height
of 100%.
However, .handle
, which exists between them, does not have a defined height. Safari sees this as a missing link, which it considers a violation of the spec, which essentially says:
The parent of an element with a percentage height must have a defined height and it must be with the height
property. Otherwise, the element with a percentage height must default to height: auto
(content height).
Therefore, you need to add height: 100%
to .handle
.
Also, in your body
element, you not only have your .flex-box
element, but you also have a nav
element with height: 250px
. Depending on how a browser handles the overflow (250px + 100%), this may cause your splitter element to disappear off-screen, which is happening in Safari.
To avoid that problem, make these adjustments to your code:
* { box-sizing: border-box; } /* include borders and padding in width
and height calculations */
.flex-box { height: calc(100% - 250px); } /* compensate for nav height */
revised demo
Also, being that body
is a column-direction flex container, you can also use flex properties (such as flex: 1
on .flex-box
) to consume remaining space. You may not even need percentage heights. See my answer here for details.
revised demo
Each section must have at least 100% height
You can also make section
100% height with js
$(window).on("resize", function () { var fullHeight = $(window).height(); $('section').height(fullHeight);}).resize();
.s-one { background: blue;}
.s-two { background: green;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><section class="s-one"></section><section class="s-two"></section>
Related Topics
Preventing Browser Text Input Suggestions
How to Center Text Inside an Svg Path
Firefox Support for Alignment-Baseline Property
What Is the Meaning of the "@Include" in .CSS Files
Line Height Default Value If Font Size Is 100%
In the CSS Visual Formatting Model, What Does "The Flow of an Element" Mean
How to Make Diagonal Circle Border Gradient
What Does 14Px/26Px Font Size in CSS Do
Why Is My Bootstrap Code Not Working
How to Put Custom Content Like a Linebreak Inside P:Column Header
CSS Performance Between Class and Attribute Selectors
Can You Add New CSS Properties in Chrome Inspector
CSS Selector for First Element of Visual (Block Reflow) Row
How to Import CSS File for into Component .Jsx File
Css-Selector for When a HTML-Document Is Inside an Iframe
Css: Move a "Float:Right" Element to Top (To Align with the First Element of the List)