PhoneGap/Cordova: Prevent horizontal scrolling - html

I have an app built on Cordova and on some of my pages I am able to scroll horizontally out of my content into white space.
This is weird as I have nothing there that extends beyond my #wrapper, which is set to width: 100%.
So I was wondering if there was a way I could disable horizontal scrolling in the app altogether?
UPDATE:
Code on page as requested:
body {
background-color: #fff;
font-family:Arial, Helvetica, sans-serif;
color: #b7b8b9;
height: 100%;
width: 100%;
}
iframe{
border: none;
width: 100%;
/*margin-top: 50px;*/
}
#header{
height: 50px;
width: 100%;
}
<body>
<div id="wrapper">
<div id="header">
<div class="headerback">Home</div>
<div class="headerrefresh"><script>var pathname = window.location.pathname;</script><script>document.write('Refresh')</script></div>
<div class="headertitle"><h2>Get the Look</h2></div>
</div><!--HEADER-->
<iframe src="http://www.mbff.com.au/getthelook"></iframe>
</div>
</body>

Try to debug your page in Chrome (webkit) with the exact dimensions of your device. This solves most rendering issues for me.
I do not know the specific issue here, but it looks like one of your elements is flowing outside of the wrapper. You could for example try this in your css:
div.wrapper { overflow: hidden; width: inherit; }
Although it might be a better idea to find out why your page is expanding horizontally?

I was looking for the solution to this problem for a long time.
Finally I solved it in the following way.
I set style for bodyand html tags:
position: fixed;
width: 100%;
height: 100%;
overflow: hidden;
After that I've added div to body and set the style for it:
overflow-y: auto;
height: 100%;
So, I have got fixed body, which contains div with vertical scroll bar.

// Phone Gap disable only horizontal scrolling in Android.
// Add this code in your Phone Gap Main Activity.Initially Declare the variable
private float m_downX;
//Then add this code after loadUrl
this.appView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
// save the x
m_downX = event.getX();
}
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
// set x so that it doesn't move
event.setLocation(m_downX, event.getY());
}
break;
}
return false;
}
});

Try adding the following code to your .html file:
document.body.addEventListener('touchmove', function(event) {
event.preventDefault();
}, false);

For the sake of completeness, I thought the answer which makes use of the official method of doing such a thing via the preference tag should be added:
<preference name="DisallowOverscroll" value="true"/>
Supported by Android and iOS according the documentation.
Default: false
Set to true if you don't want the interface to display any feedback when users scroll past the beginning or end of content. On iOS, overscroll gestures cause content to bounce back to its original position. on Android, they produce a more subtle glowing effect along the top or bottom edge of the content.

In my case it was broken styling like below
<body>
<div style="margin-left:5%; width:100%">Content</div>
</body>
which cause div to became horizontally bigger than body. I could see scroll when app run in browser. Set width to 90% (as it was initially intended) fixed the problem.
Generally, as it already pointed out here, enough to find element with wrong style which makes your page expanding horizontally and fix it.
BTW DisallowOverscroll was not helpful in above case.

Related

why 'overflow' is not working correctly on mobile?

I have problem scrolling with touch scrolling, it's working just fine with mouse and keyboard arrows but not by touching.
This is the html code:
<div class="drive-dashboard">
<div id="dashboardContainer" class="dashboard-container"/>
</div>
And this is the CSS part
.drive-dashboard {
height: 100%;
width: 100%;
position: absolute;
overflow: auto;
}
Any suggestions where the problem is?
I've run into this before and in React i've been able to solve it with something like:
`document.addEventListener("touchstart", function() {}, true);`
But, I have to admit sometimes i've needed to use it and sometimes not, so I am not sure which html elements respond and which don't.
Here is some reference

scroll behaviour smooth not working at all

I am wondering why my scroll smooth isn't working at all. I am not too sure why? I thought adding overflow-y: scroll; scroll-behavior: smooth; will help but its not working. Here is my code:
#container{
overflow-y: scroll;
scroll-behavior: smooth;
}
.topTab{
bottom: 0;
position: fixed;
font-size: 25px;
color: white;
}
.pg{
font-size: 100px;
height: 100vh;
background-color: blue;
text-align: center;
}
a{
color: white;
}
<div class = "topTab">
<li>1</li>
<li>2</li>
<li>3</li>
</div>
<div id = "container">
<div id = "1" class= "pg">1</div>
<div id = "2" class = "pg">2</div>
<div id = "3" class = "pg">3</div>
</div>
I was facing the same issue in modern Chrome (e.g. in version 88.0.4324.182) but I then enable the smooth scrolling flag using the below-mentioned URL :
chrome://flags/#smooth-scrolling
you have to override the current auto scroll settings by putting !important into your css code.
*, html {
scroll-behavior: smooth !important;
}
```
Try this one...
html {
scroll-behavior: smooth;
}
#container{
overflow-y: scroll;
}
.topTab{
bottom: 0;
position: fixed;
font-size: 25px;
color: white;
}
.pg{
font-size: 100px;
height: 100vh;
background-color: blue;
text-align: center;
}
a{
color: white;
}
<div class = "topTab">
<li>1</li>
<li>2</li>
<li>3</li>
</div>
<div id = "container">
<div id = "1" class= "pg">1</div>
<div id = "2" class = "pg">2</div>
<div id = "3" class = "pg">3</div>
</div>
If adding scroll-behavior:smooth to html is not working, what worked for me is adding it to the body as well.
html, body {
scroll-behavior: smooth
}
In my case, it wasn't working because of my windows setting for best performance where I had disabled all animations. Turning it off did the required work
[Type Adjust the appearance and performance of Windows in the start menu to get this dialog box and enable all]
First ensure if your browser is compatible with the scroll-behavior or not.
Check browser compatibility with scroll-behavior
If your browser is compatible with this property but still smooth scroll is not working
then this is not fault or error in code but you have to change a small setting of your browser.
If you are on chrome browser go to URL "chrome://flags/" depending upon your browser and press ctrl+f to open find dialogue-box and search for smooth scrolling and simply enable it and re-launch browser to make changes.
in case anyone has problems with this with Vue:
Adding
<style>
html {
scroll-behavior: smooth;
}
</style>
to App.vue
worked for me!
I solved my problem with chrome by using this:
html:focus-within {
scroll-behavior: smooth;
}
More on the subject is posted on Css-tricks "Fixing Smooth Scrolling with Find-on-Page"
Unfortunatelly this will also stop working if your device "prefers-reduced-motion"...
I always thought overwriting stuff that's not "auto" by nature, is bad practice, but this seems to be a thing now.
While reading some of the answers got an idea to check if windows performance settings could be somehow related, and after switching to "adjust for best appearance" in System Properties > Performance Options scrolling became smooth.
I made a custom solution with the easeOutSine function:
function scrollTop (initial?: number) {
if (document.documentElement && document.documentElement.scrollTop && document.documentElement.scrollTop > 10) {
if (typeof initial === 'undefined') initial = document.documentElement.scrollTop;
const progress = (initial - document.documentElement.scrollTop + 1)/initial;
document.documentElement.scrollTo({top: initial*(1-easeOutSine(progress))});
setTimeout(() => {
scrollTop(initial);
}, 10);
}
}
function easeOutSine(x: number): number {
return Math.sin((x * Math.PI) / 2);
}
since smooth isn't stable on my tests and I can't depend on the user enabling a flag.
You can tune the speed by changing the setTimeout's second argument.
Paste the below link in your browser which you are going to use as the live server:
chrome://flags/#smooth-scrolling
Then, a new tab will open up and then you can enable the smooth scrolling option and relaunch the tab. For putting the smooth scrolling action into your website, you have to put the below code in your code editor:
<html lang="en" style="scroll-behavior: smooth;" >
Just a little thing to check... I had the same issue but eventually realised / realized that I was spelling 'behaviour' the English way and not the American-English way. scroll-behavior: smooth; should work on the html selector if correctly spelled. Though I appreciate that this was not the case for #James_Lee.
I tried all the solutions but got nowhere.
Biggest steps I took to fix it in my system were:
Restarting my frontend client.
Putting overflow-y: "auto"
Placing scroll-behavior : smooth in html outside container was not generating the desired result so I put it back inside the container and now it works
Note: I did these CSS changes for the parent container while doing same in the actual container also didn't help me.
#container{
overflow-y: auto;
scroll-behavior: smooth;
}
My problem was really simple, but maybe someone else is making the same mistake, hence this answer.
For me I had changed my anchor links from
<a href="#Home">
to
<a href="index.html#Home">
The anchor links behavior was indeed smooth scrolling within my IDE's server's preview browser as well as locally in my browsers.
However, once I published to Cloudflare Pages the smooth scrolling changed to jumping.
I changed the anchor link back to
<a href="#Home">,
which brought smooth scrolling back to my staging site on Cloudflare Pages.

Iframe does not show scrollbar

Can't seem to make the iframe appear with a scroll-bar.
Go to https://billiving-qa.azurewebsites.net/accountant
email: qa#billiving.com
pass: 111111
Reload the list with F5, then click new invoice on the right side. The content is lengthy but doesn't show the scroll-bar.
My css uses the following:
.frm {
position: fixed; width: 100%; height:100vh; overflow-y:scroll !important; overflow-x:hidden !important;
}
html is as follows:
<iframe frameborder="5" class="frm" ng-src="{{trustSrc(url)}}" scrolling="yes"></iframe>
You have hidden scrollbars in ionic.app.css:
::-webkit-scrollbar {
display: none;
}
I don't know if it is possible to override this style so probably you have to remove it. Similar question.

Issues with touch scroll on iOS when focusing inputs

I am having some issues with a scrollable div on iOS. When trying to scroll by touching outside an input, it scrolls ok without any problem but when I try to scroll and I touch an input to start scrolling (there are a lot of chances that it happens because it is a div with a lot of inputs) it scrolls the whole window instead scrolling the div. I don't have that problem either in desktop or Android. I found a similar question (iOS HTML Input Tag Stops Scrolling in Scrollable Element) but it doesn't have any answer either. While I don't find any good solution, I decided to prevent the event touchmove when the user touches an input, but it is not exactly what I want.
Maybe someone already faced this problem and can help. I would really appreciate it, thanks in advance.
To get native momentum scrolling on iOS 5+, you'll need:
div {
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
Source: Overflow
Maybe you also need:
div > * {
-webkit-transform: translateZ(0px);
}
Source: Similar question in Stack Overflow
Source 2: Another similar question
This stuff made me crazy too, after testing everything, I found the following answer from Thomas Bachem here working and made it simpler in jquery.
Just add a class scrollFix to the inputs and you are ready to go. (or directly apply that js to any inputs/textarea using$('input, textarea')
Now when you touch and scroll on an input on iOS 8+, the input get all its "pointer-events" disabled (including the problematic behavior). Those "pointer-events" are enabled when we detect a simple touch.
$('.scrollFix').css("pointer-events","none");
$('body').on('touchstart', function(e) {
$('.scrollFix').css("pointer-events","auto");
});
$('body').on('touchmove', function(e) {
$('.scrollFix').css("pointer-events","none");
});
$('body').on('touchend', function(e) {
setTimeout(function() {
$('.scrollFix').css("pointer-events", "none");
},0);
});
Hacky workaround, but by doing this I was able to make scrolling work even on form inputs. The JS forces a reflow in the rendering engine, which is where the bug in iOS8 Safari lies. Changing the height to auto also improved scrolling when focused on a form element, since scrolling is forcibly handled by the browser when focused.
Markup:
<div class="modal-backdrop-container">
<div class="modal-backdrop">
<div class="modal> <!-- Content --> </div>
</div>
</div>
CSS:
.modal-backdrop-container {
z-index: 10;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
height: 100%;
}
.modal-backdrop {
z-index: 10;
height: 100%;
background-color: rgba(255,255,255,0.5);
overflow: auto;
overflow-x: hidden;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.modal {
position: relative;
width: 400px;
max-width: 100%;
margin: auto;
background-color: white;
}
JS:
// reflow when changing input focus
$modalInputs = $('.modal').find(':input');
modalInputs.on('focus', function() {
var offsetHeight = modal.$backdrop[0].offsetHeight;
modal.$backdropContainer.css({
'height': 'auto'
});
});
modalInputs.on('blur', function() {
var offsetHeight = modal.$backdrop[0].offsetHeight;
modal.$backdropContainer.css({
'height': ''
});
});
Not sure of the var offsetHeight = modal.$backdrop[0].offsetHeight; line is needed, since both this and changing the height value should force a reflow.

Google maps with jquery.mobile: how to correctly resize map canvas?

I am writing a jquery mobile app which needs a map.
For the map I am planning to use Google maps service.
To account for orientation changes, I tried to use something like:
<script>
$('#page-map').live('pagecreate', function(event) {
var map = $('#map_canvas').gmap({
...
});
...
$(window).resize(function() {
$('#map_canvas').width($(window).width());
$('#map_canvas').height($(window).height());
});
)};
</script>
The problem: this code correctly resizes the map canvas when the device is rotated, but it looks like jquery mobile resize() is skipped (the url bar is visible, for example...).
Not even adding to the "resize(function() {" code something like this:
google.maps.event.trigger(map, 'resize');
is of any help.
UPDATE:
The issue only happens on the only mobile device I'm testing my pages - a Samsung Galaxy Mini (GT-S5570), Android 2.3.4 (Gingerbread). It does not happen when resizing window on a desktop PC (i.e: on a desktop browser map_canvas is correctly filled when browser's window is enlarged, even without the resize() binding, only due to width/height at 100% on map_canvas...)
I assign a size through css to my map in jquery mobile
I add the map_canvas inside div with dimencion deuin want in this case 100%
CSS
#map_content {
padding: 0px;
width: 100%;
height: 100%;
overflow: hidden;}
#map_canvas {
width: 100%;
height: 100%;
padding: 0;
text-shadow: none;}
HTML
<div data-role="content" id="map_content" data-theme="a">
<div id="map_content">
<div id="map_canvas"></div>
</div>
</div>
I've tried the above answer (plus many others) and nothing worked for me. Actually, the above code was working for me, but just until I started using jQuery Mobile. Somehow, when I load jQuery Mobile (funnily enough, I noticed that it's the JS, no the CSS) the map_canvas has no height (a trick to check the height of the element is adding a border to it like border: 1px solid red;).
Eventually, I managed to solve the auto-resize when the orientation changes by using the following code/css:
<div data-role="page" id="pageID">
<div role="main" class="ui-content">
<div id="map_canvas">
</div>
</div>
</div>
And in the css:
html,
body,
#pageID {
height: 100%;
margin: 0;
padding: 0;
}
.ui-content {
padding: 0;
}
.ui-content,
.ui-content #map_canvas {
height: inherit; /* the trick */
}
So, basically the: height: inherit; solved the problem for me.
Credits: https://jqmtricks.wordpress.com/2014/12/01/content-div-height-css-solution/comment-page-1/#comment-250
I hope it helps!