Normally, setting overflow-x: hidden on the body should mean that the entire page never scrolls.
But in MacOS Safari, and iOS webkit (Safari, Chrome etc), if nested flexbox elements overflow the body, overflow-x: hidden is not respected.
Open the following in Chrome / Firefox and it works fine.
Open in Safari or iOS webkit, and it scrolls.
https://codepen.io/anon/pen/jdPbGN
body {
width: 100vw;
overflow-x: hidden;
margin: 0;
}
.flex {
display: flex;
}
.sidebar {
width: 100%;
height: 200px;
flex: 1 0 auto;
background-color: orange;
}
<body>
<main class="flex">
<aside class="sidebar">
</aside>
<section class="content">
<img src="https://via.placeholder.com/150" />
</section>
</main>
</body>
There is a simple fix, though not obvious if you assume overflow-x: hidden should always stop a parent scrolling when any of it's children / grandchildren overflow.
The fix is to put overflow-x: hidden on the same element as display: flex.
I feel this is a bug in Safari / iOS webkit. Curious if others agree.
Related
I've been searching all day to override this annoying iphone problem with scrollbars
so I've this very simple example
.scroller {
background: lightblue;
height: 1000px;
max-width: 400px;
margin: 90px auto;
padding: 40px;
}
.page {
max-height: 90vh;
overflow: scroll;
background: navajowhite;
}
<div class="container">
<div class="page">
<div class="scroller">
lorem ipsum
</div>
</div>
</div>
which just an html divs with overflow scroll this works very well on web and android chrome but for some reason on iPhone(chrome and safari) this scrollbar is not showing at all.
short story
I was missing with codepen for a while until my mind was blown when I saw the scrollbar is showing on the (html, css, js) snippets boxes on iPhone so I decided to investigate a little on this website and learn how they managed to get it to work on iPhone, I learned that it was a scrollbar actual element that simulate the movement of the actual scrollbar. I tried to make it work this way but I just gave up, that was a lot of work and it wasn't worth it.
I also tried -webkit-overflow-scrolling: touch;
also if you want to take a deep look into the original website you can find it in here
I am open to any ideas.. (simple I hope)
If supported, modifying the ::-webkit-scrollbar style rules, will display the scrollbar on most devices permanently and not hiding them, like mobile browser defaults do.
Except Firefox and Internet Explorer, every commonly used browser, supports it.
There are some properties you can modify.
::-webkit-scrollbar { /* 1 */ }
::-webkit-scrollbar-button { /* 2 */ }
::-webkit-scrollbar-track { /* 3 */ }
::-webkit-scrollbar-track-piece { /* 4 */ }
::-webkit-scrollbar-thumb { /* 5 */ }
::-webkit-scrollbar-corner { /* 6 */ }
::-webkit-resizer { /* 7 */ }
And a lot of pseudo-class selectors, which allow for more specific selection of the parts.
:horizontal
:vertical
:decrement
:increment
:start
:end
:double-button
:single-button
:no-button
:corner-present
:window-inactive
Firefox supports CSS Scrollbars Module Level 1, but not the ::-webkit-options by now.
This might be helpful too:
https://stackoverflow.com/a/6165489/10304804
https://stackoverflow.com/a/54101063/10304804
Your example with minimalistic -webkit-scrollbar-style-rules:
.scroller {
background: lightblue;
height: 1000px;
max-width: 400px;
margin: 90px auto;
padding: 40px;
}
.page {
max-height: 90vh;
overflow: scroll;
background: navajowhite;
}
/* minimal */
.page::-webkit-scrollbar {
width: .5em; /* counts only for the vertical scrollbar */
height: .5em; /* counts only for the horizontal scrollbar */
}
.page::-webkit-scrollbar-track {
background: #ccc;
}
.page::-webkit-scrollbar-thumb {
background: #888;
}
.page::-webkit-scrollbar-thumb:hover {
background: #555;
}
<div class="container">
<div class="page">
<div class="scroller">
lorem ipsum
</div>
</div>
</div>
Here's a simple scroll snap demo:
.scroll {
border: 2px solid black;
width: 150px;
height: 150px;
overflow-x: scroll;
scroll-snap-type: x mandatory;
display: flex;
}
.item {
scroll-snap-align: start;
flex: 0 0 auto;
width: 150px;
height: 150px;
box-sizing: border-box;
border: 2px solid red;
font-size: 50px;
display: flex;
align-items: center;
justify-content: center;
}
<div class="scroll">
<div class="item">A</div>
<div class="item">B</div>
<div class="item">C</div>
</div>
What I expect to happen
Scrolling the scrollbar with the mouse in desktop Safari should snap to an item.
What happens
Scroll snap has no effect in Safari but works in Firefox and Chrome. But it does work in Safari if I scroll with the trackpad.
This seems like such a simple issue and I feel silly for resorting to asking such a trivial question on Stackoverflow, but I've been googling for the past 30 mins and I can't seem to find anyone else with the same issue or some documentation that explains this behavior. Even WebKit's scroll snap demo page does not indicate that it should only work on iOS or with the trackpad; why don't they mention this? Am I missing something?
This is an already fixed bug: https://bugs.webkit.org/show_bug.cgi?id=146696
I've been working on a non-scrollable webapp for a while now and everything works fine on Chrome and Firefox. But unfortunately the app has to support ipad as well and I encountered a massive problem with flexboxes there.
.container {
display: flex;
flex-dircetion: column;
height: 100vh;
width: 100%;
background-color: #FF8;
}
.header {
height: 3rem;
width:100%;
background-color: #F88;
}
<div>
<div class="container">
<div class="header"/>
</div>
</div>
For some reason this is 100vh + 3rem high on the iPad and I don't have any idea why.
Does anyone know why it behaves this way?
And if so, is there a workaround?
I've created a website with a flexbox-based structure. My goal was to have the entire viewable page filled by divs, but to avoid letting any divs push below the lower limit of the browser window. One of my divs should scroll when the text overflows, but in Firefox it instead affects the entire page.
Here is my HTML:
<div class="header_bar">header</div>
<div class="page_grid">
<div class="pg_nav">nav</div>
<div class="pg_main">This is the div that should scroll</div>
<div class="pg_sidebar pg_sidebar2">sidebar</div>
</div>
And here is my CSS:
html, body
{
padding: 0;
margin: 0;
height: 100%;
display: flex;
flex-direction: column;
}
.header_bar
{
flex: 0 0 auto;
}
.page_grid
{
flex: 1;
display: flex;
}
.pg_nav
{
width: 25%;
}
.pg_main
{
width: 50%;
overflow-y: auto;
}
.pg_sidebar
{
width: 25%;
}
Everything works completely fine in Chrome and Safari, but there are problems when I load the website in Firefox. I created a pen of the site here. Does anyone have any advice on how to make this show up the same across all three browsers?
Thanks so much!
As stated above by magenetwd, this is a known firefox bug, when I added min-width:0;min-height:0; to .page_grid, the problem solved.
.page_grid
{
flex: 1;
display: flex;
color: #FFFFFF;
/* Firefox bug fix styles */
min-width:0;
min-height:0;
/* End of Firefox bug fix styles */
}
This question already has answers here:
Why don't flex items shrink past content size?
(5 answers)
Closed 6 years ago.
I want to contain a flex item within the parent so that it does not spill outside of the parent. Only the flex item should have a scrollbar (if necessary).
My styling works fine within Chrome and IE11, but not Firefox. I suspect there is a difference in interpretation of the flex-basis style set on #wrapper, but I cannot figure out why Firefox renders this differently.
Here's the desired rendering as seen in Chrome:
And here's what happens in Firefox:
I could apply a "duct tape" fix by adding #left { height: calc(100vh - 50px); }, but I'd prefer to identify the actual inconsistency if possible.
body, html, h1 {
padding: 0;
margin: 0;
}
header {
background-color: rgba(0, 255, 255, 0.2);
height: 50px;
}
#main {
height: 100vh;
background-color: rgba(0, 255, 255, 0.1);
display: flex;
flex-flow: column;
}
#wrapper {
display: flex;
flex-grow: 2;
flex-basis: 0%;
}
#left {
overflow-y: scroll;
background-color: rgba(0, 255, 255, 0.2);
width: 30%;
}
.box {
margin: 5px 0;
height: 50px;
width: 100%;
background-color: rgba(0, 0, 0, 0.2);
}
<div id="main">
<header>
<h1>Header</h1>
</header>
<div id="wrapper">
<div id="left">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
</div>
</div>
This has to do with the flexbox specification's implied minimum sizing algorithm.
This is a Firefox bug.
Adding min-width: 0; min-height: 0 to #wrapper seems to do the trick:
#wrapper {
display: flex;
flex-grow: 2;
flex-basis: 0%;
min-height: 0; /* NEW */
min-width: 0; /* NEW */
}
DEMO
Original Answer Below
Currently you have overflow-y: scroll applied to #left.
If you also apply overflow-y: scroll to #wrapper, the vertical scroll launches in Firefox.
As to why Firefox interprets the code differently than Chrome I can't say. The rendering engines have their differences. I recently addressed another flexbox interpretation issue between IE11 and Chrome:
More information:
Bug 1043520 - (minsizeauto-fallout) Tracking bug for web content breaking due to new "min-width:auto" / "min-height:auto" behavior on flex items
Bug 570036 - Flexible box does not allow overflow scrolling of children elements without extra markup
DEMO: http://jsfiddle.net/seqgz8qv/ (scroll works in FF)
Scroll not working with CSS3 flex box in Firefox
Flexbox and vertical scroll in a full-height app using NEWER flexbox api
Scrolling a flexbox with overflowing content