Fix mobile panel visibility with floating button and iOS CSS fixes
Replace the unreliable peek-strip approach with a floating '☰ Controls' button on the map. The button is always clearly visible, hides when the panel is open, and reappears when the panel closes. Also fix two iOS Safari issues that were hiding the sidebar entirely: - overflow:hidden on body clips position:fixed elements in mobile Safari; reset to overflow:visible in the mobile media query - Add viewport-fit=cover and env(safe-area-inset-bottom) padding so the sidebar clears the home indicator / browser toolbar - Use 100dvh instead of 100vh to avoid iOS address-bar overflow Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
6927efca54
commit
ceea5706b3
3 changed files with 60 additions and 5 deletions
|
|
@ -36,17 +36,33 @@ function isMobile() { return window.innerWidth < 768; }
|
||||||
|
|
||||||
function openPanel() {
|
function openPanel() {
|
||||||
document.getElementById('sidebar').classList.add('panel-open');
|
document.getElementById('sidebar').classList.add('panel-open');
|
||||||
|
const fab = document.getElementById('panel-fab');
|
||||||
|
if (fab) fab.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
function closePanel() {
|
||||||
|
document.getElementById('sidebar').classList.remove('panel-open');
|
||||||
|
const fab = document.getElementById('panel-fab');
|
||||||
|
if (fab) fab.style.removeProperty('display');
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateHandleLabel(text) {
|
function updateHandleLabel(text) {
|
||||||
const el = document.getElementById('sidebar-handle-label');
|
const el = document.getElementById('sidebar-handle-label');
|
||||||
if (el) el.textContent = text;
|
if (el) el.textContent = text;
|
||||||
|
const fabLabel = document.getElementById('panel-fab-label');
|
||||||
|
if (fabLabel) fabLabel.textContent = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('sidebar-handle').addEventListener('click', () => {
|
document.getElementById('sidebar-handle').addEventListener('click', () => {
|
||||||
document.getElementById('sidebar').classList.toggle('panel-open');
|
if (document.getElementById('sidebar').classList.contains('panel-open')) {
|
||||||
|
closePanel();
|
||||||
|
} else {
|
||||||
|
openPanel();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
document.getElementById('panel-fab').addEventListener('click', openPanel);
|
||||||
|
|
||||||
// ── Helpers ────────────────────────────────────────────────────────────────
|
// ── Helpers ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,11 @@ html, body {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767.98px) {
|
@media (max-width: 767.98px) {
|
||||||
|
/* overflow:hidden on body clips position:fixed in mobile Safari — reset it */
|
||||||
|
html, body {
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
|
|
@ -51,15 +56,18 @@ html, body {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
flex: none !important;
|
flex: none !important;
|
||||||
height: 65vh;
|
height: 65vh;
|
||||||
max-height: calc(100vh - 56px);
|
max-height: calc(100dvh - 56px);
|
||||||
min-height: unset;
|
min-height: unset;
|
||||||
transform: translateY(calc(100% - 48px));
|
/* fully off-screen by default; FAB opens it */
|
||||||
|
transform: translateY(100%);
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
border-radius: 16px 16px 0 0;
|
border-radius: 16px 16px 0 0;
|
||||||
border-right: none !important;
|
border-right: none !important;
|
||||||
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.15);
|
box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.15);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
/* clear of home-indicator / browser chrome */
|
||||||
|
padding-bottom: env(safe-area-inset-bottom, 0px);
|
||||||
}
|
}
|
||||||
|
|
||||||
#sidebar.panel-open {
|
#sidebar.panel-open {
|
||||||
|
|
@ -70,6 +78,31 @@ html, body {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
flex: 0 0 100% !important;
|
flex: 0 0 100% !important;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Floating action button */
|
||||||
|
#panel-fab {
|
||||||
|
position: absolute;
|
||||||
|
bottom: calc(env(safe-area-inset-bottom, 0px) + 56px); /* above attribution */
|
||||||
|
right: 12px;
|
||||||
|
z-index: 999;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
background: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 10px 16px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 600;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#panel-fab:active {
|
||||||
|
background: #f8f9fa;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<title>{% if route_name %}{{ route_name }} – {% endif %}OSM Public Transport → GeoJSON</title>
|
<title>{% if route_name %}{{ route_name }} – {% endif %}OSM Public Transport → GeoJSON</title>
|
||||||
{% if route_name %}<meta property="og:title" content="{{ route_name }} – OSM Public Transport → GeoJSON">{% endif %}
|
{% if route_name %}<meta property="og:title" content="{{ route_name }} – OSM Public Transport → GeoJSON">{% endif %}
|
||||||
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
|
<link rel="icon" type="image/svg+xml" href="{{ url_for('static', filename='favicon.svg') }}">
|
||||||
|
|
@ -124,7 +124,13 @@
|
||||||
</div><!-- /sidebar -->
|
</div><!-- /sidebar -->
|
||||||
|
|
||||||
<!-- Map -->
|
<!-- Map -->
|
||||||
<div class="col-9" id="map"></div>
|
<div class="col-9" id="map">
|
||||||
|
<!-- Mobile floating button to open the panel (hidden on desktop) -->
|
||||||
|
<button id="panel-fab" class="d-md-none" type="button" aria-label="Open controls">
|
||||||
|
<span id="panel-fab-icon">☰</span>
|
||||||
|
<span id="panel-fab-label">Controls</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue