Podróż zaplanowana w trzech krokach
FormularzePodgląd
Ładowanie podglądu…
Formularz planowania podróży w trzech krokach z podsumowaniem wybranych opcji.
Kod źródłowy
Licencja MIT — także do użytku komercyjnego. Zachowaj informacje o autorze i licencji.
HTML
<main class="journey"><aside><p class="note">Plan podróży</p><h1>Zaplanuj<br>podróż.</h1><ol id="steps"><li aria-current="step">Kierunek</li><li>Uczestnicy</li><li>Podsumowanie</li></ol><svg viewBox="0 0 180 110" aria-hidden="true"><path d="M0 105 60 22 96 78 128 42 180 105Z" fill="#c2de8e"/><path d="m60 22 19 30-18-8-15 8Z" fill="white"/></svg></aside><form id="trip"><section data-step="0"><h2>Wybierz kierunek</h2><label for="destination">Kierunek</label><select id="destination"><option>Portugalia</option><option>Norwegia</option><option>Japonia</option></select><p class="muted">Przykładowy plan podróży.</p></section><section data-step="1" hidden><h2>Kto jedzie?</h2><div class="field"><label for="traveller">Twoje imię</label><input id="traveller" required maxlength="40" placeholder="Np. Anna"></div><label for="people">Liczba osób</label><input id="people" type="number" min="1" max="12" value="2" required></section><section data-step="2" hidden><h2>Podsumowanie</h2><p id="summary"></p><p class="muted">Sprawdź kierunek i liczbę osób.</p></section><div class="row controls"><button id="back" type="button" class="secondary" hidden>Wstecz</button><button id="next" type="button" data-demo-submit>Dalej</button></div><p id="status" class="status" role="status"></p></form></main>
CSS
*{box-sizing:border-box}body{margin:0;min-height:100vh;padding:24px;font:16px/1.45 system-ui,sans-serif;display:grid;align-content:center;color:#17212e;background:#f5f7fb}main{width:min(100%,850px);margin:auto}h1,h2,p{margin:0 0 16px}h1{font-size:clamp(26px,4vw,42px);line-height:1.1}h2{font-size:21px}label{display:block;font-weight:600;margin-bottom:6px}input,select,textarea,button{font:inherit;max-width:100%}input:not([type=radio]):not([type=checkbox]):not([type=range]):not([type=color]),select,textarea{width:100%;padding:10px 12px;background:#fff;color:#17212e;border:1px solid #748091;min-height:44px;border-radius:0}textarea{resize:vertical}button{min-height:44px;padding:10px 18px;border:1px solid currentColor;background:#17212e;color:white;cursor:pointer;border-radius:0}button:hover{filter:brightness(1.15)}button:disabled{cursor:default;opacity:.55}button.secondary{background:transparent;color:inherit}input[type=radio],input[type=checkbox]{width:20px;height:20px;vertical-align:middle;accent-color:var(--accent,#3155c7)}input[type=range]{width:100%;accent-color:var(--accent,#3155c7);min-height:32px}input[type=color]{width:100%;min-height:52px;cursor:pointer;background:transparent;border:1px solid currentColor}fieldset{border:0;padding:0;margin:0}legend{font-weight:600;margin-bottom:12px}output{display:block}small,.note{font-size:13px}p.note{margin:10px 0 0}button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible{outline:3px solid var(--accent,#3155c7);outline-offset:3px}[hidden]{display:none!important}.field{margin-bottom:16px}.row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.status{min-height:24px;margin-top:14px;font-weight:600;overflow-wrap:anywhere}.muted{color:#4b5868}.two{display:grid;grid-template-columns:1fr 1fr;gap:20px}@media(max-width:560px){body{padding:18px}.two{grid-template-columns:1fr}h1{font-size:29px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}.journey{display:grid;grid-template-columns:290px 1fr;background:#fff;border:1px solid #d3dbea}.journey aside{background:#2546a6;color:white;padding:30px}.journey form{padding:36px}.journey ol{padding-left:22px;line-height:2}.journey li[aria-current]{font-weight:800;color:#d9f0af}.journey svg{width:100%;margin-top:25px}.controls{margin-top:30px}#summary{font-size:22px}body{--accent:#2546a6}@media(max-width:560px){.journey{grid-template-columns:1fr}.journey aside{padding:20px}.journey aside h1{font-size:26px}.journey svg{display:none}.journey ol{display:flex;gap:24px;flex-wrap:wrap;margin-bottom:0}.journey form{padding:22px}}
JavaScript
(()=>{const q=s=>document.querySelector(s);const all=s=>[...document.querySelectorAll(s)];let step=0;const show=()=>{all('[data-step]').forEach(e=>e.hidden=Number(e.dataset.step)!==step);all('#steps li').forEach((e,i)=>{if(i===step)e.setAttribute('aria-current','step');else e.removeAttribute('aria-current')});q('#back').hidden=step===0;q('#next').textContent=step===2?'Zapisz plan':'Dalej';};q('#trip').addEventListener('submit',e=>{e.preventDefault();if(step===1&&!q('#traveller').reportValidity())return;if(step===1&&!q('#people').reportValidity())return;if(step<2){step++;if(step===2)q('#summary').textContent=`${q('#traveller').value.trim()||'Podróżnik'}: ${q('#destination').value}, liczba osób: ${q('#people').value}.`;show();(q(`[data-step="${step}"] input`)||q('#next')).focus();}else q('#status').textContent='Plan zapisany w tym podglądzie.';});q('#back').onclick=()=>{step=Math.max(0,step-1);q('#status').textContent='';show()};all('form').forEach(form=>{const submit=form.querySelector('[data-demo-submit]');if(!submit)return;submit.addEventListener('click',()=>form.dispatchEvent(new Event('submit',{cancelable:true})));form.addEventListener('keydown',event=>{if(event.key==='Enter'&&!event.defaultPrevented&&event.target.matches('input:not([type=radio]):not([type=checkbox])')){event.preventDefault();submit.click();}})});})();
Edytuj swój pen
Podaj adres e-mail użyty przy zapisie. Wyślemy link do edycji.