Performance-Optimierungen: CSS inline eingebettet, Touch-Targets vergrößert, Layout-Shifts minimiert

This commit is contained in:
2025-07-25 14:02:36 +02:00
parent ffa1af560c
commit 97aa208bf2
2 changed files with 307 additions and 243 deletions

View File

@@ -1,238 +0,0 @@
:root {
--primary: #2563eb;
--primary-dark: #1e40af;
--background: #f8fafc;
--surface: #fff;
--border: #e5e7eb;
--text: #1e293b;
--shadow: 0 2px 8px rgba(30,41,59,0.07);
}
body {
background: var(--background);
color: var(--text);
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
max-width: 480px;
margin: 3em auto;
background: var(--surface);
border-radius: 16px;
box-shadow: var(--shadow);
padding: 2.5em 2em 2em 2em;
border: 1px solid var(--border);
}
h1 {
text-align: center;
margin-bottom: 2em;
font-size: 2.1em;
letter-spacing: 0.01em;
}
form {
margin-bottom: 2.2em;
padding-bottom: 1.2em;
border-bottom: 1px solid var(--border);
}
form:last-of-type {
border-bottom: none;
margin-bottom: 0;
}
h2 {
font-size: 1.15em;
margin-bottom: 0.7em;
color: var(--primary-dark);
}
label {
display: block;
margin-bottom: 0.7em;
font-weight: 500;
}
.date-row {
display: flex;
align-items: center;
gap: 0.5em;
margin-top: 0.2em;
}
.date-calc-row {
display: flex;
align-items: center;
gap: 0.5em;
margin-top: 0.2em;
}
input[type="date"] {
padding: 0.45em 0.7em;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 1em;
background: #f1f5f9;
color: var(--text);
}
.today-btn {
padding: 0.35em 0.9em;
background: var(--primary-dark);
color: #fff;
border: none;
border-radius: 6px;
font-size: 0.95em;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
.today-btn:hover {
background: var(--primary);
}
button, .accordion-header {
background: var(--primary);
color: #fff;
border: none;
border-radius: 6px;
font-size: 1em;
font-weight: 600;
cursor: pointer;
box-shadow: 0 1px 3px rgba(30,41,59,0.05);
transition: background 0.2s;
}
/* Berechnungs-Buttons vergrößern */
button[type="submit"] {
font-size: 1.1em;
padding: 0.8em 1.5em;
min-width: 140px;
margin-top: 1.2em;
}
button:hover, .accordion-header:hover {
background: var(--primary-dark);
}
button:focus, .accordion-header:focus {
outline: 3px solid #facc15;
outline-offset: 2px;
box-shadow: 0 0 0 4px #1e293b;
z-index: 2;
}
.result {
margin-top: 1em;
font-weight: bold;
background: #e0e7ff;
color: #1e293b;
border-radius: 6px;
padding: 0.7em 1em;
box-shadow: 0 1px 2px rgba(30,41,59,0.04);
border: 2px solid #2563eb;
}
.accordion {
border-radius: 12px;
overflow: hidden;
box-shadow: var(--shadow);
background: var(--surface);
margin-bottom: 2em;
}
.accordion-item + .accordion-item {
border-top: 1px solid var(--border);
}
.accordion-header {
background: var(--primary-dark);
color: #fff;
cursor: pointer;
padding: 1em 1.2em;
font-size: 1.1em;
font-weight: 600;
border: none;
outline: none;
width: 100%;
text-align: left;
transition: background 0.2s;
}
.accordion-header.active, .accordion-header:hover {
background: var(--primary);
}
.accordion-content {
display: none;
padding: 1.2em 1.2em 1em 1.2em;
background: var(--surface);
}
.accordion-content.active {
display: block;
}
.header-tage {
background: #2563eb;
color: #fff;
}
.header-tage.active, .header-tage:hover {
background: #1e40af;
color: #fff;
}
.header-werktage {
background: #059669;
color: #fff;
}
.header-werktage.active, .header-werktage:hover {
background: #047857;
color: #fff;
}
.header-wochentag {
background: #f59e42;
color: #1e293b;
}
.header-wochentag.active, .header-wochentag:hover {
background: #d97706;
color: #fff;
}
.header-plusminus-tage {
background: #a21caf;
color: #fff;
}
.header-plusminus-tage.active, .header-plusminus-tage:hover {
background: #701a75;
color: #fff;
}
.header-plusminus-werktage {
background: #0ea5e9;
color: #fff;
}
.header-plusminus-werktage.active, .header-plusminus-werktage:hover {
background: #0369a1;
color: #fff;
}
.header-plusminus-wochenmonate {
background: #f43f5e;
color: #fff;
}
.header-plusminus-wochenmonate.active, .header-plusminus-wochenmonate:hover {
background: #be123c;
color: #fff;
}
.header-kw {
background: #a78bfa;
color: #1e293b;
}
.header-kw.active, .header-kw:hover {
background: #7c3aed;
color: #fff;
}
.header-kw-datum {
background: #facc15;
color: #1e293b;
}
.header-kw-datum.active, .header-kw-datum:hover {
background: #ca8a04;
color: #fff;
}
.header-plusminus {
background: #be123c;
color: #fff;
}
.header-plusminus.active, .header-plusminus:hover {
background: #7f1d1d;
color: #fff;
}
@media (max-width: 600px) {
.container {
margin: 1em;
padding: 1.2em 0.7em 1em 0.7em;
}
h1 {
font-size: 1.3em;
}
}

View File

@@ -26,7 +26,297 @@
<meta name="application-name" content="Elpatrons Datumsrechner"> <meta name="application-name" content="Elpatrons Datumsrechner">
<meta name="msapplication-TileColor" content="#2563eb"> <meta name="msapplication-TileColor" content="#2563eb">
<link rel="icon" type="image/x-icon" href="/static/favicon.ico"> <link rel="icon" type="image/x-icon" href="/static/favicon.ico">
<link rel="stylesheet" href="/static/style.css"> <style>
:root {
--primary: #2563eb;
--primary-dark: #1e40af;
--background: #f8fafc;
--surface: #fff;
--border: #e5e7eb;
--text: #1e293b;
--shadow: 0 2px 8px rgba(30,41,59,0.07);
}
body {
background: var(--background);
color: var(--text);
font-family: 'Segoe UI', Arial, sans-serif;
margin: 0;
padding: 0;
}
.container {
max-width: 480px;
margin: 3em auto;
background: var(--surface);
border-radius: 16px;
box-shadow: var(--shadow);
padding: 2.5em 2em 2em 2em;
border: 1px solid var(--border);
}
h1 {
text-align: center;
margin-bottom: 2em;
font-size: 2.1em;
letter-spacing: 0.01em;
}
form {
margin-bottom: 2.2em;
padding-bottom: 1.2em;
border-bottom: 1px solid var(--border);
}
form:last-of-type {
border-bottom: none;
margin-bottom: 0;
}
h2 {
font-size: 1.15em;
margin-bottom: 0.7em;
color: var(--primary-dark);
}
label {
display: block;
margin-bottom: 0.7em;
font-weight: 500;
}
.date-row {
display: flex;
align-items: center;
gap: 0.5em;
margin-top: 0.2em;
}
.date-calc-row {
display: flex;
align-items: center;
gap: 0.5em;
margin-top: 0.2em;
}
input[type="date"] {
padding: 0.45em 0.7em;
border: 1px solid var(--border);
border-radius: 6px;
font-size: 1em;
background: #f1f5f9;
color: var(--text);
}
.today-btn {
padding: 0.35em 0.9em;
background: var(--primary-dark);
color: #fff;
border: none;
border-radius: 6px;
font-size: 0.95em;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
.today-btn:hover {
background: var(--primary);
}
button, .accordion-header {
background: var(--primary);
color: #fff;
border: none;
border-radius: 6px;
font-size: 1em;
font-weight: 600;
cursor: pointer;
box-shadow: 0 1px 3px rgba(30,41,59,0.05);
transition: background 0.2s;
}
/* Berechnungs-Buttons vergrößern */
button[type="submit"] {
font-size: 1.1em;
padding: 0.8em 1.5em;
min-width: 140px;
margin-top: 1.2em;
}
button:hover, .accordion-header:hover {
background: var(--primary-dark);
}
button:focus, .accordion-header:focus {
outline: 3px solid #facc15;
outline-offset: 2px;
box-shadow: 0 0 0 4px #1e293b;
z-index: 2;
}
.result {
margin-top: 1em;
font-weight: bold;
background: #e0e7ff;
color: #1e293b;
border-radius: 6px;
padding: 0.7em 1em;
box-shadow: 0 1px 2px rgba(30,41,59,0.04);
border: 2px solid #2563eb;
}
.accordion {
border-radius: 12px;
overflow: hidden;
box-shadow: var(--shadow);
background: var(--surface);
margin-bottom: 2em;
/* Layout-Shift-Prävention */
min-height: 200px;
contain: layout style paint;
}
.accordion-item + .accordion-item {
border-top: 1px solid var(--border);
margin-top: 0.5em;
}
.accordion-header {
background: var(--primary-dark);
color: #fff;
cursor: pointer;
padding: 1em 1.2em;
font-size: 1.1em;
font-weight: 600;
border: none;
outline: none;
width: 100%;
text-align: left;
transition: background 0.2s;
}
.accordion-header.active, .accordion-header:hover {
background: var(--primary);
}
.accordion-content {
display: none;
padding: 1.2em 1.2em 1em 1.2em;
background: var(--surface);
max-height: 0;
overflow: hidden;
transition: max-height 0.3s ease-out, padding 0.3s ease-out;
opacity: 0;
}
.accordion-content.active {
display: block;
max-height: 500px;
opacity: 1;
transition: max-height 0.3s ease-in, padding 0.3s ease-in, opacity 0.3s ease-in;
}
.header-tage {
background: #2563eb;
color: #fff;
}
.header-tage.active, .header-tage:hover {
background: #1e40af;
color: #fff;
}
.header-werktage {
background: #059669;
color: #fff;
}
.header-werktage.active, .header-werktage:hover {
background: #047857;
color: #fff;
}
.header-wochentag {
background: #f59e42;
color: #1e293b;
}
.header-wochentag.active, .header-wochentag:hover {
background: #d97706;
color: #fff;
}
.header-plusminus-tage {
background: #a21caf;
color: #fff;
}
.header-plusminus-tage.active, .header-plusminus-tage:hover {
background: #701a75;
color: #fff;
}
.header-plusminus-werktage {
background: #0ea5e9;
color: #fff;
}
.header-plusminus-werktage.active, .header-plusminus-werktage:hover {
background: #0369a1;
color: #fff;
}
.header-plusminus-wochenmonate {
background: #f43f5e;
color: #fff;
}
.header-plusminus-wochenmonate.active, .header-plusminus-wochenmonate:hover {
background: #be123c;
color: #fff;
}
.header-kw {
background: #a78bfa;
color: #1e293b;
}
.header-kw.active, .header-kw:hover {
background: #7c3aed;
color: #fff;
}
.header-kw-datum {
background: #facc15;
color: #1e293b;
}
.header-kw-datum.active, .header-kw-datum:hover {
background: #ca8a04;
color: #fff;
}
.header-plusminus {
background: #be123c;
color: #fff;
}
.header-plusminus.active, .header-plusminus:hover {
background: #7f1d1d;
color: #fff;
}
@media (max-width: 600px) {
.container {
margin: 1em;
padding: 1.2em 0.7em 1em 0.7em;
}
h1 {
font-size: 1.3em;
}
}
/* Touch-Target Optimierungen für Footer-Links */
footer a {
display: inline-block;
padding: 0.5em 0.8em;
margin: 0.3em 0.2em;
min-height: 44px;
min-width: 44px;
line-height: 1.4;
text-decoration: none;
border-radius: 6px;
transition: background-color 0.2s, color 0.2s;
position: relative;
}
footer a:hover {
background-color: rgba(37, 99, 235, 0.1);
text-decoration: underline;
}
footer a:focus {
outline: 3px solid #facc15;
outline-offset: 2px;
background-color: rgba(37, 99, 235, 0.1);
}
/* Zusätzlicher Abstand zwischen Footer-Links */
footer br + a {
margin-top: 0.5em;
}
/* Responsive Anpassungen für Footer */
@media (max-width: 600px) {
footer a {
padding: 0.6em 1em;
margin: 0.4em 0.3em;
min-height: 48px;
min-width: 48px;
}
}
</style>
<link rel="manifest" href="/static/manifest.json"> <link rel="manifest" href="/static/manifest.json">
<meta name="theme-color" content="#2563eb"> <meta name="theme-color" content="#2563eb">
<script> <script>
@@ -46,9 +336,21 @@
}); });
} }
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
openAccordion(parseInt("{{ active_idx|default(0) }}")); // Sofortige Aktivierung der ersten Accordion-Sektion um Layout-Shifts zu vermeiden
// Tastatursteuerung für Accordion const activeIdx = parseInt("{{ active_idx|default(0) }}");
const headers = document.querySelectorAll('.accordion-header'); const headers = document.querySelectorAll('.accordion-header');
const panels = document.querySelectorAll('.accordion-content');
// Sofort den aktiven Zustand setzen
headers.forEach((btn, i) => {
btn.classList.toggle('active', i === activeIdx);
btn.setAttribute('aria-expanded', i === activeIdx ? 'true' : 'false');
});
panels.forEach((el, i) => {
el.classList.toggle('active', i === activeIdx);
});
// Tastatursteuerung für Accordion
headers.forEach((header, idx) => { headers.forEach((header, idx) => {
header.addEventListener('keydown', function(e) { header.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') { if (e.key === 'Enter' || e.key === ' ') {
@@ -85,14 +387,14 @@
</div> </div>
<div class="accordion"> <div class="accordion">
<div class="accordion-item"> <div class="accordion-item">
<button type="button" class="accordion-header header-tage" id="accordion-header-0" aria-expanded="true" aria-controls="accordion-panel-0" role="button" tabindex="0" onclick="openAccordion(0)"> <button type="button" class="accordion-header header-tage active" id="accordion-header-0" aria-expanded="true" aria-controls="accordion-panel-0" role="button" tabindex="0" onclick="openAccordion(0)">
<span style="vertical-align:middle;display:inline-block;width:1.5em;"> <span style="vertical-align:middle;display:inline-block;width:1.5em;">
<!-- Kalender mit Doppelpfeil --> <!-- Kalender mit Doppelpfeil -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><path d="M8 15h8M8 15l2-2M8 15l2 2M16 15l-2-2M16 15l-2 2" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round"/></svg> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="3" y="5" width="18" height="16" rx="4" fill="#fff" stroke="#2563eb" stroke-width="2"/><rect x="3" y="5" width="18" height="4" rx="2" fill="#2563eb"/><rect x="6" y="2" width="2" height="4" rx="1" fill="#2563eb"/><rect x="16" y="2" width="2" height="4" rx="1" fill="#2563eb"/><path d="M8 15h8M8 15l2-2M8 15l2 2M16 15l-2-2M16 15l-2 2" stroke="#2563eb" stroke-width="1.5" stroke-linecap="round"/></svg>
</span> </span>
Anzahl der Tage/Werktage zwischen zwei Daten Anzahl der Tage/Werktage zwischen zwei Daten
</button> </button>
<div class="accordion-content" id="accordion-panel-0" role="region" aria-labelledby="accordion-header-0"> <div class="accordion-content active" id="accordion-panel-0" role="region" aria-labelledby="accordion-header-0">
<form method="post"> <form method="post">
<label for="start1">Startdatum:<br> <label for="start1">Startdatum:<br>
<span class="date-row"> <span class="date-row">