Is is possible to create a scrolling div within a html5 IOS app where the height needs to be dynamic?
To give a bit of background to my headache - our app has 3 main panels - the user can left or right swipe to reveal the first and third panel which contain notifications/settings (as in the Facebook app. All 3 outer panels are fixed position.
The main panel contains 6 pages - which are all absolutely positioned divs which hide and show via menu selection. Each revealed div (or page) needs to scroll, but all content is dynamic - so I cant set a height.
I have found several solutions for fixed heights - but none so far for dynamic heights..
Any suggestions?
Scrolling Divs
Another new feature in iOS 5+ is divs can finally scroll. To make a div scroll you’ll just need to add the following (this example has a fixed header but adjust the positioning to fit your app):
.scrollable {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
The trick here is adding the -webkit-overflow-scrolling to anywhere you’d normally set your overflow. The downside of Apple’s implementation is that the div doesn’t bounce as you’d hope when you are already at the absolute top or bottom. Instead of bouncing the div being scrolled, it bounces the whole page and reveals the browser chrome. This is where you’ll need a javascript fix.
Please try this example for Scrollability.
Please see this Link
iScroll is a party lib which help in good scrolling.
It has a scrolling without providing height.
We just have to call a method refresh when dom elements of scrolling are added.
Related
I have the following example. When I expand the panel, the remaining items below it goes down to make room for the content of the opened panel.
However, what I need is, when I expand the panel, it should scroll upwards so the header of the opened panel is on top. Reason being is that, I am planning to make the content height to occupy as much height as possibly available in the screen, making the opened panel almost occupy most of the screen.
For Angular Material Component's Expansion Panel,
you can use the following css for making the expanded expansion-panel to be present above all, ie the expanded expansion panel will move to the first position in the list.
--------- styles.css ---------.
.mat-expansion-panel,
.mat-accordion {
display: flex !important;
flex-direction: column;
}
.mat-expansion-panel.mat-expanded {
order: -1;
}
Approach :
Give .mat-accordion, display: flex and manipulate order property on the expanded expansion-panel to achieve the goal.
Stackblitz- Demo showing expaned panel moving to top in the list
I am using iscroll-probe.js to implement the pull-to-refresh and infinite load in a Phonegap application using the example given in this link.
I am loading the contents dynamically so iscroll is refreshed after the list items have been added.
Everything works perfectly for me except the situation when the total height of the list items is lesser than the screen height.
This is when the scroller is not required hence is disabled but it also disables the pull-to-refresh. This I think is how iscroll works as the scroller is disabled the moment I call the refresh method.
Does anyone know how to make pull-to-refresh work when the content height is smaller than the screen height.
For anyone still interested, I solved this problem by setting a min-height to the #scroller element.
I did this using jquery (I'm not sure if it can be done by using css only).
$('#scroller').css('min-height',($(window).height()+1)+'px');
That is: the #scroller element min-height is set to the window height + 1px.
This way the scroller is always enabled.
Please note that this instruction has to be executed before instantiating the iScroll element.
I am bulding a mobile project which has a number of modules having elements positioned as fixed. The issue which am facing is only on browsers running on iOS.
The exact issue is that whenever I tr to scroll over the body of the page having , say the bottom toolbar, as fixed, the whole fixed element moves respectively with the scroll, and once the scroll ends completely, then only it comes back to its assigned place.
I have given the body of the page a relative css rule.
Please help as this happens only on iOS.
.add-to-block {
background: #fff;
position: fixed;
bottom: 0px;
right: 0px;
display: block;
height: auto;
width: 100%;
*(inner content element) {
inner content element styling...
}
}
Please try this, source here
.add-to-block {
transform: translate3d(0,0,0);
.....
.....
}
There is not really an easy answer to this as it has been a known issue on ios for a while (supposedly fixed in ios8) but this gives you a few ways to fix it: https://remysharp.com/2012/05/24/issues-with-position-fixed-scrolling-on-ios it details all the issues with position fixed on ios devices and possible ways to fix it if you need to use it.
Add height: 100% and overflow: auto for fixed element.
Full example at https://codepen.io/astnt/pen/ExgOqeX
Safari allows you to scroll beyond the limits of the fixed div so that it can put in a nice bouncy effect. When you scroll past this point though, if there is a container that is scrollable, then subsequent touch events get handed off to this. Therefore scrolling does nothing for a bit until control gets handed back to the fixed div.
The fix is to give the container div the overflow-y: hidden style so that Safari does not hand off the touches, and we continue interacting with the fixed div.
None of the proposed solutions worked for me, although i had the fixed element inside the scrolling div (and moved it up), had no transform or other layer-creating properties on the parent elements (and created a layer on the fixed element) etc.
My solution was to just change the fixed element to be position: sticky;
The content on my screen is definitely able to fit into the given screen size, yet the app still shows scrollbars if the screen is shorter than a certain height.
This fiddle shows the issue, if you shrink the result pane to a certain height.
What I've tried:
Adding `overflow-y:hidden' to the body fixes this issue, but I want to be able to scroll in the y-direction if needed, just not when it's not needed.
How can I stop this scrolling when unnecessary?
The reason ended up being because of a rule in the jQueryMobile.css:
.ui-page, bla, bla{
min-height: 420px;
}
changing that to a smaller number that matches what I needed fixed the issue.
If you visit this page on your iPad device on the latest version of iOS you can follow along.
http://fiddle.jshell.net/will/8VJ58/10/show/light/
I have two elements with the new -webkit-overflow-scrolling: touch; property and value applied. The left hand grey area has plenty of content and will scroll in portrait or landscape. The right will only scroll in landscape.
If you start in landscape (refresh in landscape) you can scroll both areas with the inertia scrolling. Works great. Now flip your iPad into portrait and only the left hand area will scroll. This is as intended. But when you flip back to landscape the right hand area will no longer scroll at all, whereas the left hand area is fine still.
It's obvious how to stop this happening, but I don't always have the content to fill the area.
So any ideas?
Thanks in advance,Will :)
Coming late with a similar, but simpler solution.
var $el = $('.myElementClass');
function setOverflow(){
$el.css({webkitOverflowScrolling: 'touch', overflow: 'auto'});
}
function resizeHandler(){
$el.css({webkitOverflowScrolling: 'auto', overflow: 'hidden'});
setTimeout(setOverflow,10);
}
[EDIT]
Watch out, after experimenting (a lot), I found out that display:none declarations will surely break the webkit-overflow-scrolling: touch feature.
Never use it on elements (or parents of elements) that are supposed to support touch scrolling.
I am actually having the exact same issue. I have narrowed it down to the fact that it affects DIVs whose content's no longer require scrolling when the orientation is changed.
In your example. The DIV on the right scrolls in landscape, does not NEED to scroll in portrait, but then needs to scroll again. I have tested this when both DIVs (left and right) need to scroll regardless of orientation and its not a problem.
UPDATE:
I actually seem to have fixed this!
The issue appears to be a timing issue. During resize the inner content is not big enough to warrant scrolling on the outer DIV that has overflow. After wasting a day on this, I finally came up with this hack:
<div id="header" style="position:fixed; height:100px">Header</div>
<div id="content" style="overflow: auto; -webkit-overflow-scrolling: touch">
<div id="contentInner">
content that is not long enough to always scroll during different orientations
</div>
</div>
Here is my logic whenever the page resizes:
function handleResize()
{
var iHeight = $(window).height() - $("#header").height();
// Height needs to be set, to allow for scrolling -
//this is the fixed container that will scroll
$('#content').height(iHeight - 10);
// Temporarily blow out the inner content, to FORCE ipad to scroll during resizing
// This is a timing issue where the inner content is not big enough during resize post orientation to require the outer DIV to scroll
$('#contentInner').height(1000);
// Set the heights back to something normal
// We have to "pause" long enough for the re-orientation resize to finish
window.setTimeout(delayFix, 10);
}
function delayFix()
{
var iHeight = $(window).height() - $("#header").height();
// Inner divs force the outer div to always have at least something to scroll. This makes the inner DIV always "rubber-band" and prevents
// the page from scrolling all over the place for no reason.
// The height of the inner guy needs to be AT LEAST as big as the container and actually a nip bigger to cause the
// scrollable area to 'rubber band' properly
$('#contentInner').height(iHeight + 20);
}
I was able to use a known "fix" to force an iOS6 redraw to correct this issue without having to use setTimeout.
$(window).on('orientationchange', function()
{
var $elem=$('[selector]');
var orgDisplay=$elem.css('display');
$elem.css('display','none');
$elem.get(0).offsetHeight;
$elem.css('display',orgDisplay);
});
I experienced the same bug on iPhone, iPod and iPad. This is not restricted to the latter only.
I tried everything that was suggested to be a solution, but eventually the sweet combination ended up being detaching the element, appending it to its container and explicitly assigning it its own height while doing this, like so:
$(window).on('orientationchange', function(){
var el = $('.troublemaker').detach(),
elh = el.height();
setTimeout( el.css({'height':elh+'px'}).appendTo('.container'), 50 );
});