Hilfe-Button mit Overlay hinzugefügt - Barrierefreier Tooltip und Modal-Dialog implementiert
This commit is contained in:
@@ -51,6 +51,145 @@ body {
|
||||
box-shadow: var(--shadow);
|
||||
padding: 2.5em 2em 2em 2em;
|
||||
border: 1px solid var(--border);
|
||||
position: relative;
|
||||
}
|
||||
.help-button-container {
|
||||
position: absolute;
|
||||
top: 2.5em;
|
||||
right: 2em;
|
||||
z-index: 10;
|
||||
}
|
||||
.help-button {
|
||||
width: 2.2em;
|
||||
height: 2.2em;
|
||||
border-radius: 50%;
|
||||
background: rgba(37, 99, 235, 0.1);
|
||||
color: var(--primary);
|
||||
border: 1px solid var(--border);
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 1em;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
}
|
||||
.help-button:hover {
|
||||
background: rgba(37, 99, 235, 0.2);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
.help-button:focus {
|
||||
outline: 3px solid #facc15;
|
||||
outline-offset: 2px;
|
||||
box-shadow: 0 0 0 4px #1e293b;
|
||||
}
|
||||
.help-tooltip {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: var(--text);
|
||||
color: white;
|
||||
padding: 0.5em 0.8em;
|
||||
border-radius: 6px;
|
||||
font-size: 0.85em;
|
||||
white-space: nowrap;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
transition: opacity 0.2s, visibility 0.2s;
|
||||
margin-top: 0.5em;
|
||||
z-index: 20;
|
||||
}
|
||||
.help-tooltip::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
border: 5px solid transparent;
|
||||
border-bottom-color: var(--text);
|
||||
}
|
||||
.help-button:hover + .help-tooltip,
|
||||
.help-button:focus + .help-tooltip {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
.modal-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 1000;
|
||||
}
|
||||
.modal-overlay.active {
|
||||
display: flex;
|
||||
}
|
||||
.modal-content {
|
||||
background: var(--surface);
|
||||
border-radius: 12px;
|
||||
padding: 2em;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||
margin: 0 auto;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
.modal-close {
|
||||
position: absolute;
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
background: none;
|
||||
border: none;
|
||||
font-size: 1.5em;
|
||||
cursor: pointer;
|
||||
color: var(--text);
|
||||
padding: 0.5em;
|
||||
border-radius: 50%;
|
||||
transition: background 0.2s;
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
}
|
||||
.modal-close:hover {
|
||||
background: var(--border);
|
||||
}
|
||||
.modal-close:focus {
|
||||
outline: 3px solid #facc15;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
.modal-content h1 {
|
||||
margin-top: 0;
|
||||
color: var(--primary-dark);
|
||||
}
|
||||
.modal-content h2 {
|
||||
color: var(--primary-dark);
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.modal-content p {
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
.modal-content ul {
|
||||
margin-bottom: 1em;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
.modal-content li {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
@@ -275,6 +414,25 @@ button:focus, .accordion-header:focus {
|
||||
h1 {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.help-button-container {
|
||||
top: 1.5em;
|
||||
right: 1.2em;
|
||||
}
|
||||
.help-button {
|
||||
width: 2em;
|
||||
height: 2em;
|
||||
font-size: 0.9em;
|
||||
min-width: 48px;
|
||||
min-height: 48px;
|
||||
}
|
||||
.help-tooltip {
|
||||
font-size: 0.8em;
|
||||
padding: 0.4em 0.6em;
|
||||
}
|
||||
.modal-content {
|
||||
padding: 1.5em;
|
||||
margin: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Touch-Target Optimierungen für Footer-Links */
|
||||
@@ -335,6 +493,22 @@ footer br + a {
|
||||
el.classList.toggle('active', i === idx);
|
||||
});
|
||||
}
|
||||
function showHelp() {
|
||||
const modal = document.getElementById('helpModal');
|
||||
modal.classList.add('active');
|
||||
document.body.style.overflow = 'hidden';
|
||||
// Fokus auf den Schließen-Button setzen
|
||||
setTimeout(() => {
|
||||
document.querySelector('.modal-close').focus();
|
||||
}, 100);
|
||||
}
|
||||
function hideHelp() {
|
||||
const modal = document.getElementById('helpModal');
|
||||
modal.classList.remove('active');
|
||||
document.body.style.overflow = '';
|
||||
// Fokus zurück auf den Hilfe-Button setzen
|
||||
document.querySelector('.help-button').focus();
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Sofortige Aktivierung der ersten Accordion-Sektion um Layout-Shifts zu vermeiden
|
||||
const activeIdx = parseInt("{{ active_idx|default(0) }}");
|
||||
@@ -368,6 +542,20 @@ footer br + a {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ESC-Taste zum Schließen des Modals
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
hideHelp();
|
||||
}
|
||||
});
|
||||
|
||||
// Klick außerhalb des Modals zum Schließen
|
||||
document.getElementById('helpModal').addEventListener('click', function(e) {
|
||||
if (e.target === this) {
|
||||
hideHelp();
|
||||
}
|
||||
});
|
||||
});
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
@@ -378,6 +566,10 @@ footer br + a {
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="help-button-container">
|
||||
<button type="button" class="help-button" onclick="showHelp()" aria-label="Hilfe anzeigen" title="Hilfe anzeigen" aria-describedby="help-tooltip">?</button>
|
||||
<div id="help-tooltip" class="help-tooltip" role="tooltip">Öffnet ein Hilfefenster mit Informationen über den Datumsrechner</div>
|
||||
</div>
|
||||
<div style="text-align:center; margin-bottom:1.2em;">
|
||||
<div style="font-size:1.1em; font-style:italic; color:#64748b;">Elpatrons</div>
|
||||
<h1 style="margin:0;">Datumsrechner</h1>
|
||||
@@ -540,6 +732,57 @@ footer br + a {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Help Modal Overlay -->
|
||||
<div id="helpModal" class="modal-overlay" role="dialog" aria-labelledby="help-title" aria-describedby="help-content">
|
||||
<div class="modal-content">
|
||||
<button type="button" class="modal-close" onclick="hideHelp()" aria-label="Hilfe schließen">×</button>
|
||||
<h1 id="help-title">Was ist Elpatrons Datumsrechner?</h1>
|
||||
|
||||
<p>Der Datumsrechner kann verschiedene Datumsberechnungen durchführen:</p>
|
||||
|
||||
<ul>
|
||||
<li>Anzahl der Tage zwischen zwei Daten</li>
|
||||
<li>Anzahl der Werktage zwischen zwei Daten</li>
|
||||
<li>Anzeige des Wochentags eines Datums</li>
|
||||
<li>Datum plus/minus X Tage</li>
|
||||
<li>Datum plus/minus X Werktage</li>
|
||||
<li>Datum plus/minus X Wochen/Monate</li>
|
||||
<li>Kalenderwoche zu Datum</li>
|
||||
<li>Start-/Enddatum einer Kalenderwoche eines Jahres</li>
|
||||
</ul>
|
||||
|
||||
<h2>Online Datumsrechner gibt es bereits in einer Vielzahl, warum also noch einer?</h2>
|
||||
|
||||
<p>Aus zwei Gründen:</p>
|
||||
|
||||
<ul>
|
||||
<li>Finde mal einen Datumsrechner, der nicht vollkommen verseucht mit Werbung, Tracking und Cookies ist!</li>
|
||||
<li>Das hat mich so geärgert, dass ich meinen eigenen programmiert habe.
|
||||
<ul>
|
||||
<li>Genau genommen nicht ich selbst. Diese App wurde zum überwiegenden Teil von KI nach meinen Anweisungen entwickelt (Vibe Coding).</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Was du noch wissen solltest</h2>
|
||||
|
||||
<ul>
|
||||
<li>Ich habe versucht, die App möglichst barrierefrei zu gestalten, um Menschen mit Einschränkungen die Benutzung zu erleichtern.</li>
|
||||
<li>Diese App schnüffelt dir nicht hinterher, sammelt keine persönlichen Daten und geht dir auch sonst (hoffentlich!) in keiner Weise auf die Nerven.</li>
|
||||
<li>Den Quellcode dieser App habe ich auf <a href="https://codeberg.org/elpatron/datecalc" target="_blank">Codeberg</a> veröffentlicht, du kannst ihn einsehen, verändern oder damit deinen eigenen kleinen Datumsrechner betreiben.</li>
|
||||
<li>Die App läuft auf meinem kleinen Home-Server und ist derzeit nicht für große Besucherzahlen ausgelegt.</li>
|
||||
<li>Ich übernehme keine Gewähr für die Funktionalität und die Rechenergebnisse. Die KI, die das programmiert hat, übrigens auch nicht.</li>
|
||||
<li>Falls du einen Fehler findest oder eine weitere Funktion wünschst, kannst du mir eine Mail schreiben (siehe Mailto Link in der Fußzeile)</li>
|
||||
</ul>
|
||||
|
||||
<p><strong>Hab Spaß mit Elpatrons Datumsrechner! Dein M. Busche</strong></p>
|
||||
</div>
|
||||
<div id="help-content" class="sr-only">
|
||||
Hilfe-Informationen für den Datumsrechner mit Erklärungen zu allen Funktionen
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer style="text-align:center; margin-top:2em; color:#64748b; font-size:0.98em; padding-bottom:1.5em;">
|
||||
Dies ist ein werbe- und trackingfreier <a href="https://codeberg.org/elpatron/datecalc/src/branch/main/README.md" target="_blank" style="color:#2563eb; text-decoration:underline;">Open Source Datumsrechner</a><br>
|
||||
<a href="/api-docs" target="_blank" style="color:#2563eb; text-decoration:underline;">REST API Dokumentation (Swagger)</a><br>
|
||||
|
Reference in New Issue
Block a user