This fixes a few things on the iPhone.
-webkit-tap-highlight-color
removes the iPhone's element touch highlight.-webkit-overflow-scrolling
gives us momentum based scrollingviewport
gives us nicer scaling for mobiletouch-action: manipulation
prevents double tap to zoomposition: fixed
means we don't scroll the entire page but elements within it can befont-size: 16px
means we don't zoom in on the iPhone<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0">
<title>📱</title>
<style>
* {
touch-action: manipulation;
-webkit-tap-highlight-color: rgba(0,0,0,0);
box-sizing: border-box;
}
input {
font-size: 16px;
}
html, body {
padding: 10px;
margin: 0px;
overflow: hidden;
-webkit-overflow-scrolling: touch;
top: 0;
left: 0;
position: fixed;
height: 100%;
width: 100%;
background-color: yellowgreen;
}
body > .content {
display: flex;
flex-flow: column;
height: 100%;
}
.content > .items {
background-color: olivedrab;
padding: 4px;
overflow: auto;
border-radius: 6px;
}
.content > .items > div {
font-size: 60px;
color: white;
}
</style>
</head>
<body>
<div class="content">
i am a mobile friendly page
<input placeholder="with input">
<button>and a button</button>
<div class="items">
<div>one</div>
<div>one</div>
<div>one</div>
<div>one</div>
<div>one</div>
<div>one</div>
<div>one</div>
<div>one</div>
<div>two</div>
</div>
</div>
</body>
</html>
There's the web audio API... which of course safari refuses to support.
You can make an <input>
element have the type="file"
. And give it some relevant capture
and accept
attributes to look for audio.
<input type="file" name="audio" accept="audio/*" capture=""
onchange="...">
And you'll get this video from element's this.files[0]
in the onchange
event.
The input file element is ugly to look at. You can hide it in a div. And pass through a button click.
<div>
<button
onclick="this.nextElementSibling.click()">
🔴
</button>
<input type="file" name="audio" accept="audio/*" capture=""
style="display: none;"
onchange="alert('hooray something new', this.files[0])">
</div>
The above should open a normal dialogue on the desktop and the camera on an iPhone.
On the iPhone and others, if you long click on a button, or another element, the browser may offer a popup.
This popup does things like offer to copy text, search for the selected text. And often -webkit-user-select: none
and similar don't help--it selects other text nearby.
You can disable this by hooking onto the touchdown
event and running event.preventDefault()
to prevent the browser's default action.
element.addEventListener("touchstart", e => {
e.preventDefault()
})
A potential problem: if you run e.preventDefault()
in touchstart
then any click
listeners on the element will also not run.
You normally get the cursor x and y position with event.clientX
and event.clientY
in an mousedown
event. (and click
, mouseup
, etc)
But in a touchdown
event those properties don't exist to support multiple finger touch.
Instead the event.changedTouches
array exists. Then you get the clientX
from the first array item.
The following function is passed an Event, and it returns the clientX
and clientY
from either a normal mouse event or a touch event.
function get_client_x_y(e) {
var x, y = 0
if(e.type.startsWith("touch")) {
x = e.changedTouches[0].clientX
y = e.changedTouches[0].clientY
} else {
x = e.clientX
y = e.clientY
}
return {x, y}
}
As an aside, clientY
is the position from the top of the screen. pageY
is the position from the top of the, possibility scrolled, document.
You can make the width of your website better fit a mobile screen.
The viewport
meta tag does this. In its content
you set the width of the screen to be device-width
. And the initial-scale
to be 1.0.
<head>
...
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
...
</head>
...