iOS Input field scrolls to top when focussed - ios

I have created a demo (not in Jsfiddle, couldn't get it to work in device):
http://i283951.iris.fhict.nl/test.html
When I open this on my iPad and scroll down all the way and then click on the input, it scrolls all the way up to the top and then shows the keyboard.
I'm pretty sure this also happens with a iPhone, on my android I don't have those problems. So I think it's iOs related.
body {
margin: 0;
padding: 0;
height: 2000px;
}
.top {
width: 100%;
height: 50px;
position: fixed;
background-color: #AA3939;
}
.input-group {
margin-top: 12px;
margin-left: 50px;
}
<html>
<head>
</head>
<body>
<div class="top">
<div class="input-group">
<input type="search" placeholder="Search...">
<button type="submit">Submit</button>
</div>
</div>
</body>
</html>

I think you could maybe prevent this by using the same like described here:
https://stackoverflow.com/a/7771215/1501847
For a web/html app running inside iOS Safari you want something like
document.ontouchmove = function(event){
event.preventDefault();
}

Related

Why my image doesn't go on height on mobile?

I would the image on desktop to stay the same, but on mobile to be bigger on height. What should i change in the code ? I'm using Bootstrap 5 aswell.
<div class="container">
<div class="row">
<div class="col-12">
<img src="/images/section1/home-image.jpg" class="img-fluid" id="img1" alt="man on boat">
<img src="/images/section1/home-logo.png" class="img-fluid" id="img2" alt="logo Seafarer">
</div>
</div>
</div>
#section1 {
position:relative;
}
#img2 {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
Here you go...
I think this is impossible to achieve with Bootstrap. I would use #media query if I were you.
Add this to your CSS:
#media only screen and (max-width: 575px) {
.col-12 {
height: 500px; // Adjust the height
}
#img1 {
object-fit: cover;
height: 100%;
}
}
It's important to add object-fit: cover; otherwise your image will be screwed. Try to remove this line to see what I'm talking about.
Let me know if this is helpful.

Fixed element flicker within an iframe on iOS

I know there seems to be a lot out there about this, but none of the solutions seem to fix my issue.
I am trying to apply a fixed button to the bottom of my screen within an iframe. With my current implementation, I am experiencing a terrible flicker with the button on iOS Safari whenever I scroll.
Here's essentially what I have:
HTML
<iframe>
<body>
<div class="app">
<div class="app-content">
<div class="card">
<h1>Header</h1>
<p>Content</p>
</div>
<button class="fixed-button">This is flickering</button>
</div>
</div>
</body>
</iframe>
CSS
iframe {
border: none;
position: absolute;
height: 100%;
width: 100%;
top: 0; left: 0;
}
app {
-webkit-overflow-scrolling: touch;
overflow:auto;
position:absolute;
width:100%;
height:100%;
}
fixed-button {
position: fixed;
bottom: 1rem;
}
I've got a WIP on my site here http://jaredrauh.com/iframe-fixed-elements-ios/. Any suggestions would be amazing.

Workaround for overflow restriction affecting fixed-positioned elements in iOS?

Edit: The main issue is this: overflow: hidden and overflow: auto affect fixed positioned elements in iOS.
So if I have a fixed positioned modal dialog in a component within a scrolling feature of the page, that element is not displayed wherever it exceeds the bounds of its parent. This is really messed up, as it's not how fixed positioning works on any other system. So what's the official response to this?
Original post:
I have a modal dialog that works fine on desktop and Android, but on any browser on my iPad, the modal dialog, including the modal overlay, gets hidden wherever it exceeds the boundaries of its parent container (even though it is fixed positioned). I know that this isn't how overflow: auto is supposed to work, because it works just fine on all other devices. Anyone else experienced this? I'm sure it has something to do with how iOS handles fixed positions.
Anyway, here's some code:
HTML:
<confirm-dialog ng-if="$ctrl.confirmDlgShowing" on-close="$ctrl.closeDlgs()" on-confirm="$ctrl.deleteInstance()" class="ng-scope ng-isolate-scope">
<div class="modal general modal"><div class="modal-window"><div class="modal-inner" ng-transclude="">
<div style="position:relative" class="ng-scope">
<label class="modal-close" ng-click="$ctrl.onClose()"></label>
<div class="page-heading">
<h2>Are you sure?</h2>
</div>
<input class="btn" type="button" value="Yes" ng-click="$ctrl.confirm()">
<input class="btn" type="button" value="No" ng-click="$ctrl.onClose()">
</div>
</div></div></div>
</confirm-dialog>
SASS:
.container {
overflow: auto;
.modal-window {
// overlay
#include transition(opacity 0.25s ease);
#include position(fixed, 0px 0px 0px 0px);
background: rgba(0,0,0, 0.6);
padding-top: 0.6em;
text-align: left;
z-index: 999999999;
margin: 0 !important;
.modal-bg {
#include position(absolute, 0px 0px 0px 0px);
cursor: pointer;
}
}
.modal-inner {
#include transition(opacity 0.25s ease);
background: $modal-background;
border-radius: $base-border-radius;
display: table;
margin: 70px auto;
max-height: 80%;
overflow: auto;
padding: $modal-padding / 2;
z-index: 1000000000;
min-width: 400px;
#media(max-width: $medium-screen) {
max-height: 70%;
padding: $modal-padding;
}
}
}
Here's the workaround we finally came up with--a new directive to replace ng-if on our modals that places the object on the body. Plays nicely with other Angular bindings too.
angular.module('app').directive('rootIf', function()
{
return {
restrict: 'A',
link: function (scope, $elm, attrs)
{
scope.$watch(attrs.rootIf, onChangeRootIf);
function onChangeRootIf()
{
if (scope.$eval(attrs.rootIf))
$("body").children().first().before($elm);
else
$elm.detach();
}
}
}
});

Display div over canvas in Dojo mobile app

I know this question have been asked many times but I still can't manage to get it to work.
I am developing apps on iPad and generate a globe 3D in WebGL, some of the elements are created with Dojo (like the splitpane).
I basically have a top pane with a canvas and a bottom pane with different stuffs.
<div id="splitArea" data-dojo-type="dojox.mobile.FixedSplitter" data-dojo-props="orientation:'V'">
<div id="topDiv" data-dojo-type="dojox.mobile.ContentPane">
<div id="globePane">
<button class="globeItem" id="metButton" data-dojo-type="dojox.mobile.Button" onclick="displayOptions('MET')">MET</button>
<canvas id="globeCanvas"></canvas>
<script type="text/javascript" src="js/Globe.js"></script>
<div id="globeOptions"></div>
</div>
</div>
<div id="infosPane" data-dojo-type="dojox.mobile.ContentPane">
</div>
</div>
Here is the top pane elements CSS :
#topDiv {
top: 0px;
width: 100%; height: 50%;
}
#globePane {
width: 100%; height: 100%;
position:relative;
}
#globeCanvas {
position: absolute;
z-index: 0;
width: 100%;
height: 100%;
}
#globeOptions {
width: 150px; height: 150px;
position: absolute;
top: 40px; right: 200px;
z-index: 4;
}
.globeItem {
position: absolute;
z-index: 3;
}
And the Javascript that injects globe in the canvas :
var container= document.getElementById('globeCanvas');
if ( Detector.webgl )
renderer = new THREE.WebGLRenderer( { canvas: globeCanvas , antialias:true} );
else
renderer = new THREE.CanvasRenderer( { canvas: globeCanvas } );
renderer.setSize(container.offsetWidth,container.offsetHeight);
renderer.setClearColor(0x000000, 1);
...
}
Now question is : I want a Div (id="globeOptions") to appear on screen when I click a button named "MET", I got at first to create it (what is done in the code), but once created, the div isn't displayed.
The button was created with Dojo and is displayed well on canvas (I didn't do anything special so it must be Dojo auto config that lets it being displayed on canvas), but the div stays under canvas whatever I try.
I tried lots of solutions I found but nothing works (even the relative/absolute positions).
Why does it work on Fiddle but doesn't in device, am I doing something wrong?

Making DIV in an IFRAME scrollable

Page A has an iframe (that loads Page B). That Page B has a div#OutputDiv. My goal is to make that div in that iframe scrollable.
SOLUTION (CREDIT TO STEVE!):
Include overflow: auto for that div. However you must specify height too. Simply give any fixed value. eg height: 0.
Use a javascript function to make the div's height always same as the window's, even after window resize. height is now not fixed.
Code:
#outputDiv {
font-size: 12px;
font-family: Arial;
margin-right: 1em;
overflow: auto;
overflow-x: hidden; (optional)
-webkit-overflow-scrolling: touch; (enable smooth scrolling on mobile)
height: 0; (omit-able)
}
$(window).resize(function(){
$("#outputDiv").css("height",0).css("height",$(this).height());
});
$(window).trigger("resize");
TL;DR Full story
Page A.html - has an iframe to load Page B. When on Page A, that div#OutputDiv in that iframe must be scrollable. Works fine on PC but not scrollable on iPad/Android. Page structure:
Page B.php - Left half div#OutputDiv, right half div#map-canvas containing Google Maps.
(Sidenote: I think the #map-canvas CSS is pretty unchangeable, for example changing something may cause the Maps to extend height beyond browser height, which is not what I want.)
Page A.html
<style type="text/css">
#title-banner {
position: fixed;
top: 0;
left: 0;
width: 100%;
}
#real-time-alert {
margin-top: 155px;
margin-left: 10px;
}
.tab-content {
border-left: 1px solid #ddd;
padding: 10px;
height: 100%;
}
#map {
height: 100%;
}
.nav-tabs {
margin-bottom: 0;
}
#panel {
position: fixed;
top: 120px;
right: 10px;
bottom: 10px;
left: 350px;
}
iframe {
width: 100%;
height: 100%;
}
</style>
<body>
<div id="title-banner" class="well"><h1>Real-time incident updates</h1></div>
<div id="real-time-alert">
DEMO:<br>
<a id="demolink" style="cursor: pointer; font-weight: bold;">22/11/2013, 0.32.18AM: 3.128268, 101.650656<br></a>
</div>
<div id="panel">
<ul class="nav nav-tabs" id="myTab">
<li class="active"><a data-toggle="tab" href="#map">Map</a></li>
<li><a data-toggle="tab" href="#message">Messages</a></li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="map"><iframe seamless name="map-report"></iframe></div>
<div class="tab-pane" id="message"></div>
</div>
</div>
</body>
Page B.php
*for div#map-canvas, I had to do the code below, or else when I hover on the page, div#OutputDiv will disappear. This may be not important.
$("*").hover(function(){
$("#map-canvas").css("position","fixed"); });
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map-canvas {
height: 100%;
width: 50%;
}
#content-pane {
float:left;
width:48%;
padding-left: 2%;
}
#outputDiv {
font-size: 12px;
font-family: Arial;
margin-right: 1em;
}
</style>
<body>
<div id="content-pane">
<div class='well well-small' id="inputs" style="margin: 1em 1em 0 0">
<b>TESTING ONLY</b> <br>
<label for="originLat">Incident Site: </label><input type="text" id="originLat" style="width:6em;" />
<input type="text" id="originLng" style="width:6em;" />
<button type="button">Calculate distances</button>
</br>eg. 3.126547,101.657825
</div>
<div id="outputDiv"></div>
</div>
<div id="map-canvas" style="position: fixed; right: 1px;"></div>
</body>
I can't see any overflow controls specified in the CSS (apologies if I missed them).
Have you tried:
div#OutputDiv { overflow: auto; height: 200px; }
The height is just for testing purposes - but you could use Javascript to get the actual height and apply it using either raw javascript or jQuery.
A good example (including how to detect orientation changes if device goes portrait to landscape or similar) can be found on:
How do I get the new dimensions of an element *after* it resizes due to a screen orientation change?

Resources