swiatfrontendu.pl
  • arrow-right
  • Kodowaniearrow-right
  • Kalendarz w HTML, CSS, JS: stwórz interaktywną wersję krok po kroku

Kalendarz w HTML, CSS, JS: stwórz interaktywną wersję krok po kroku

Olaf Dudek

Olaf Dudek

|

13 września 2025

Kalendarz w HTML, CSS, JS: stwórz interaktywną wersję krok po kroku

W tym artykule dowiesz się, jak krok po kroku zbudować w pełni funkcjonalny i interaktywny kalendarz na swoją stronę internetową, wykorzystując HTML, CSS i JavaScript. Poznasz praktyczne rozwiązania i fragmenty kodu, które pozwolą Ci stworzyć własny, dynamiczny kalendarz.

Stwórz interaktywny kalendarz na swoją stronę kompletny przewodnik HTML, CSS i JavaScript

  • Struktura HTML: Wybierz między semantycznym `` a elastycznym `
    ` z CSS Grid, aby zbudować szkielet kalendarza.
  • Stylizacja CSS: Zapewnij czytelność i nowoczesny wygląd, wyróżniając aktualny dzień oraz weekendy, z myślą o responsywności.
  • Dynamiczne generowanie JavaScript: Użyj JavaScript do pobierania daty, obliczania dni miesiąca i dynamicznego wstawiania ich do struktury HTML.
  • Interaktywność: Dodaj funkcje nawigacji (zmiana miesięcy) oraz dynamiczne podświetlanie bieżącego dnia.
  • Lokalizacja: Dostosuj kalendarz do polskich standardów, ustawiając poniedziałek jako pierwszy dzień tygodnia i używając polskich nazw.
  • Rozwój: Poznaj pomysły na dalszą rozbudowę kalendarza, takie jak dodawanie wydarzeń czy integracja z API.
  • Zaczynamy od zera: fundamenty twojego kalendarza w HTML

    Kiedy zabieramy się za tworzenie kalendarza, jednym z pierwszych dylematów jest wybór odpowiedniej struktury HTML. Z mojego doświadczenia wynika, że znacznik `

    ` jest semantycznie poprawnym i często stosowanym wyborem do tworzenia siatki kalendarza. Dlaczego? Ponieważ dane, które prezentuje kalendarz dni tygodnia i dni miesiąca są z natury tabelaryczne. Użycie `
    ` naturalnie oddaje tę relację, co jest korzystne zarówno dla czytelności kodu, jak i dla dostępności.

    Jednak świat web developmentu nie stoi w miejscu. Coraz częściej, zwłaszcza w kontekście responsywności i bardziej złożonych układów, warto zastosować `

    ` w połączeniu z CSS Grid. Jest to nowoczesna i elastyczna alternatywa dla `
    `. CSS Grid pozwala nam na precyzyjne kontrolowanie układu siatki, co daje większą swobodę w projektowaniu i łatwiejsze dostosowywanie kalendarza do różnych rozmiarów ekranów. Jeśli zależy Ci na maksymalnej elastyczności i kontroli nad każdym elementem, `
    ` z Gridem będzie świetnym wyborem.

    Zanim zagłębimy się w kod, musimy przygotować podstawowe pliki. Zawsze zaczynam od utworzenia trzech kluczowych plików: `index.html` (dla struktury), `style.css` (dla stylizacji) i `script.js` (dla logiki). Pamiętaj, aby poprawnie je połączyć w pliku HTML. Plik CSS umieszczamy w sekcji `

    `, aby style załadowały się przed treścią, a plik JavaScript na końcu sekcji ``, tuż przed jego zamknięciem. Dzięki temu strona najpierw się wyrenderuje, a dopiero potem JavaScript zacznie modyfikować DOM, co zapobiega blokowaniu renderowania.
    
    
       Mój interaktywny kalendarz 
    
      
    
    
    

    struktura html kalendarza

    Krok 1: budowa szkieletu kalendarza za pomocą czystego HTML

    Zaczynamy od stworzenia głównego kontenera HTML, który będzie niczym rama dla naszego kalendarza. Zwykle używam do tego prostego `

    ` z unikalnym identyfikatorem, na przykład `
    `. Ten kontener będzie zawierał całą strukturę kalendarza zarówno nagłówek z miesiącem i przyciskami nawigacyjnymi, jak i samą siatkę dni. Jest to kluczowy element organizacji, który ułatwi nam późniejszą stylizację i manipulację za pomocą JavaScript.

    Następnie, wewnątrz tego kontenera, tworzymy podstawową strukturę tabeli kalendarza. Jak wspomniałem, znaczniki `

    `, `` i `` są idealne do tego celu. `
    ` definiuje całą tabelę, `` służy do grupowania nagłówków (w naszym przypadku dni tygodnia), a `` będzie zawierał dynamicznie generowane dni miesiąca. To semantyczne podejście sprawia, że nasz kod jest bardziej zrozumiały i dostępny.

    Pon Wt Śr Czw Pt Sob Nd

W sekcji `` umieszczamy nagłówki dni tygodnia. Pamiętaj, aby uwzględnić polską kolejność, gdzie poniedziałek jest pierwszym dniem tygodnia. Używamy do tego znacznika `` (table header). W moim przykładzie zastosowałem skrócone nazwy, ale możesz użyć pełnych, jeśli wolisz. To właśnie ta sekcja będzie stała i niezmienna, niezależnie od wyświetlanego miesiąca.

  Pon Wt Śr Czw Pt Sob Nd 

Na koniec, sekcja `

` początkowo będzie pusta. To właśnie tutaj JavaScript dynamicznie wstawi wiersze (``) i komórki (``) z numerami dni miesiąca. Możesz, dla celów testowych, umieścić tam placeholderowe puste komórki, ale docelowo to skrypt będzie odpowiedzialny za ich wypełnienie. Ta separacja struktury od treści dynamicznej jest kluczowa dla utrzymania czystości kodu i efektywności działania aplikacji.
 

przykładowy styl kalendarza css

Krok 2: ożywiamy kalendarz, czyli podstawy stylizacji w CSS

Mając już szkielet HTML, czas nadać naszemu kalendarzowi wygląd. Dobra stylizacja jest kluczowa dla czytelności i użyteczności. Zaczynamy od podstawowych właściwości CSS, które określą ogólny wygląd kontenera, tabeli i komórek. Używam `width` do kontroli rozmiaru, `border` do obramowań, `padding` dla odstępów, `text-align` do wyrównania tekstu i `font-size` dla czytelności. Pamiętaj, aby style były spójne i estetyczne.

#calendar-container { width: 300px; margin: 20px auto; font-family: Arial, sans-serif; border: 1px solid #ccc; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1); background-color: #fff; padding: 15px;
} .calendar-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;
} .calendar-header h2 { margin: 0; font-size: 1.2em; color: #333;
} .calendar-header button { background-color: #007bff; color: white; border: none; padding: 8px 12px; border-radius: 5px; cursor: pointer; font-size: 1em; transition: background-color 0.3s ease;
} .calendar-header button:hover { background-color: #0056b3;
} #calendar { width: 100%; border-collapse: collapse; text-align: center;
} #calendar th, #calendar td { padding: 10px; border: 1px solid #eee; font-size: 0.9em;
} #calendar th { background-color: #f2f2f2; color: #555; font-weight: bold;
}

Aby kalendarz był bardziej intuicyjny, warto wyróżnić aktualny dzień oraz dni weekendowe. Używam do tego klas CSS, takich jak `.today`, `.weekend`, `.saturday` i `.sunday`. Zmieniając ich tło, kolor tekstu lub obramowanie, natychmiast zwracamy uwagę użytkownika na ważne daty. To prosta, ale bardzo efektywna technika poprawiająca UX.

#calendar td.today { background-color: #007bff; color: white; border-radius: 50%; font-weight: bold;
} #calendar td.weekend { color: #dc3545; /* Czerwony kolor dla weekendów */
} #calendar td.saturday { background-color: #f8d7da; /* Jasnoczerwone tło dla soboty */
} #calendar td.sunday { background-color: #f8d7da; /* Jasnoczerwone tło dla niedzieli */
} #calendar td.empty { background-color: #f9f9f9; color: #ccc;
}

W dzisiejszych czasach responsywność jest absolutną koniecznością. Kalendarz musi dobrze wyglądać i działać na każdym urządzeniu. Wprowadzam podstawy responsywnego projektowania (RWD) za pomocą `media queries`. Pozwalają mi one dostosować style kalendarza na przykład rozmiary czcionek, marginesy czy szerokość w zależności od szerokości ekranu. Dzięki temu kalendarz będzie czytelny zarówno na dużym monitorze, jak i na smartfonie.

@media (max-width: 600px) { #calendar-container { width: 95%; padding: 10px; } #calendar th, #calendar td { padding: 8px; font-size: 0.8em; } .calendar-header h2 { font-size: 1em; } .calendar-header button { padding: 6px 10px; font-size: 0.9em; }
}

Krok 3: mózg operacji dynamiczne generowanie kalendarza w JavaScript

Staticzny kalendarz HTML to tylko siatka. Prawdziwa magia dzieje się w JavaScript. Na początek, używamy obiektu `new Date()` w JavaScript do pobrania bieżącego roku, miesiąca i dnia. Te informacje są punktem wyjścia dla naszego kalendarza. Będą one wykorzystywane do inicjalizacji kalendarza, czyli do wyświetlenia aktualnego miesiąca i roku po załadowaniu strony.

let currentMonth = new Date().getMonth();
let currentYear = new Date().getFullYear();
const today = new Date();

Następnie tworzymy główną funkcję JavaScript, którą nazwałem `renderCalendar(year, month)`. To ona będzie odpowiedzialna za generowanie całego widoku kalendarza dla podanego miesiąca i roku. Wewnątrz tej funkcji musimy obliczyć liczbę dni w danym miesiącu (np. za pomocą `new Date(year, month + 1, 0).getDate()`) oraz pierwszy dzień tygodnia dla tego miesiąca (`new Date(year, month, 1).getDay()`). Te dwie wartości są fundamentem do prawidłowego ułożenia dni w siatce kalendarza.

const monthYearLabel = document.getElementById('monthYear');
const calendarBody = document.getElementById('calendar-body');
const months = ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień']; function renderCalendar(year, month) { calendarBody.innerHTML = ''; // Czyścimy poprzednie dni monthYearLabel.textContent = `${months[month]} ${year}`; const firstDayOfMonth = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); let date = 1; for (let i = 0; i < 6; i++) { // Maksymalnie 6 wierszy dla dni const row = document.createElement('tr'); // Tworzymy komórki for (let j = 0; j < 7; j++) { const cell = document.createElement('td'); // Logika dodawania pustych komórek i dni miesiąca // ... (będzie w kolejnych krokach) row.appendChild(cell); } calendarBody.appendChild(row); }
}

Jednym z kluczowych momentów jest prawidłowe obliczenie i dodanie pustych komórek na początku miesiąca, jeśli pierwszy dzień nie przypada na poniedziałek. Tutaj pojawia się ważna kwestia: konieczność korekty wartości zwracanej przez `getDay()` dla polskiej lokalizacji. Domyślnie `getDay()` zwraca 0 dla niedzieli, 1 dla poniedziałku itd. W Polsce tydzień zaczyna się od poniedziałku, więc musimy przeliczyć tę wartość. Moja sprawdzona metoda to `(firstDayOfMonth + 6) % 7`. Dzięki temu poniedziałek zawsze będzie miał indeks 0, wtorek 1 itd., a niedziela 6.

function renderCalendar(year, month) { // ... (poprzedni kod) const firstDayOfMonth = new Date(year, month, 1).getDay(); const daysInMonth = new Date(year, month + 1, 0).getDate(); // Korekta dla polskiej lokalizacji: poniedziałek to 0, niedziela to 6 const startDayIndex = (firstDayOfMonth === 0) ? 6 : firstDayOfMonth - 1; let date = 1; for (let i = 0; i < 6; i++) { const row = document.createElement('tr'); for (let j = 0; j < 7; j++) { const cell = document.createElement('td'); if (i === 0 && j < startDayIndex) { // Puste komórki na początku miesiąca cell.classList.add('empty'); cell.textContent = ''; } else if (date > daysInMonth) { // Puste komórki na końcu miesiąca cell.classList.add('empty'); cell.textContent = ''; } else { // Dni miesiąca cell.textContent = date; // ... (dodawanie klas .today, .weekend) date++; } row.appendChild(cell); } calendarBody.appendChild(row); if (date > daysInMonth) break; // Przerwij pętlę, jeśli wszystkie dni zostały dodane }
}

Wreszcie, za pomocą pętli (zazwyczaj `for`) dynamicznie tworzymy elementy `

` (lub `
`, jeśli używasz CSS Grid) dla każdego dnia miesiąca. Każda komórka otrzymuje numer dnia, a następnie jest wstawiana do odpowiedniego kontenera HTML, czyli do naszego `` (o identyfikatorze `calendar-body`). To jest serce dynamicznego generowania, które sprawia, że kalendarz "ożywa" i wyświetla prawidłowe dni dla każdego miesiąca.
function renderCalendar(year, month) { // ... (poprzedni kod) let date = 1; for (let i = 0; i < 6; i++) { const row = document.createElement('tr'); for (let j = 0; j < 7; j++) { const cell = document.createElement('td'); if (i === 0 && j < startDayIndex) { cell.classList.add('empty'); cell.textContent = ''; } else if (date > daysInMonth) { cell.classList.add('empty'); cell.textContent = ''; } else { cell.textContent = date; // Dodajemy klasę 'weekend' dla soboty (indeks 5) i niedzieli (indeks 6) if (j === 5 || j === 6) { cell.classList.add('weekend'); } // Sprawdzamy, czy to dzisiejszy dzień if (date === today.getDate() && month === today.getMonth() && year === today.getFullYear()) { cell.classList.add('today'); } date++; } row.appendChild(cell); } calendarBody.appendChild(row); if (date > daysInMonth) break; }
} // Inicjalizacja kalendarza po załadowaniu strony
document.addEventListener('DOMContentLoaded', () => { renderCalendar(currentYear, currentMonth);
});

Krok 4: interaktywność, której oczekują użytkownicy

Statyczny kalendarz to za mało. Użytkownicy oczekują możliwości nawigacji. Dodajemy więc przyciski nawigacyjne `

const prevBtn = document.getElementById('prevBtn');
const nextBtn = document.getElementById('nextBtn'); prevBtn.addEventListener('click', () => { currentMonth--; if (currentMonth < 0) { currentMonth = 11; currentYear--; } renderCalendar(currentYear, currentMonth);
}); nextBtn.addEventListener('click', () => { currentMonth++; if (currentMonth > 11) { currentMonth = 0; currentYear++; } renderCalendar(currentYear, currentMonth);
});

Aby użytkownik zawsze wiedział, który miesiąc i rok są wyświetlane, musimy dynamicznie aktualizować nagłówek kalendarza (np. `

Miesiąc Rok

`). W JavaScript wykorzystuję do tego tablicę z polskimi nazwami miesięcy. Po każdej zmianie miesiąca, pobieram odpowiednią nazwę z tablicy i wstawiam ją do elementu HTML. To prosty, ale efektywny sposób na utrzymanie użytkownika w kontekście.
const months = ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'];
const monthYearLabel = document.getElementById('monthYear'); function renderCalendar(year, month) { // ... monthYearLabel.textContent = `${months[month]} ${year}`; // ...
}

Ważne jest, aby klasa `.today` (podświetlająca aktualny dzień) była dodawana tylko wtedy, gdy wyświetlany miesiąc i rok są zgodne z bieżącymi. Unikamy w ten sposób podświetlania "dzisiejszej daty" w przeszłych lub przyszłych miesiącach, co mogłoby wprowadzać w błąd. Logika jest prosta: sprawdzamy, czy numer dnia, miesiąc i rok komórki odpowiadają aktualnej dacie systemowej. Jeśli tak, dodajemy klasę. To dbałość o szczegóły, która poprawia użyteczność.

function renderCalendar(year, month) { // ... let date = 1; for (let i = 0; i < 6; i++) { const row = document.createElement('tr'); for (let j = 0; j < 7; j++) { const cell = document.createElement('td'); // ... (logika pustych komórek) else { cell.textContent = date; if (j === 5 || j === 6) { // Sobota i Niedziela cell.classList.add('weekend'); } // Sprawdzamy, czy to dzisiejszy dzień TYLKO w bieżącym miesiącu i roku if (date === today.getDate() && month === today.getMonth() && year === today.getFullYear()) { cell.classList.add('today'); } date++; } row.appendChild(cell); } calendarBody.appendChild(row); if (date > daysInMonth) break; }
}

Zaawansowane techniki i dobre praktyki

Tworząc kalendarz dla polskiego użytkownika, kluczowe jest dostosowanie logiki JavaScript do polskiej lokalizacji. W Polsce tydzień zaczyna się od poniedziałku, podczas gdy domyślna metoda JavaScript `getDay()` zwraca 0 dla niedzieli. Musimy to skorygować. Moja ulubiona metoda to `(dayOfWeek + 6) % 7`. Jeśli `getDay()` zwróci 0 (niedziela), to `(0 + 6) % 7` da 6 (czyli niedzielę jako ostatni dzień). Jeśli zwróci 1 (poniedziałek), to `(1 + 6) % 7` da 0 (czyli poniedziałek jako pierwszy dzień). To zapewnia, że nasza siatka dni będzie zawsze poprawnie ułożona.

// firstDayOfMonth z new Date(year, month, 1).getDay()
const firstDayOfMonth = new Date(year, month, 1).getDay(); // Korekta: 0 (niedziela) staje się 6, 1 (poniedziałek) staje się 0 itd.
const startDayIndex = (firstDayOfMonth === 0) ? 6 : firstDayOfMonth - 1;

Podczas pracy nad dynamicznymi elementami, łatwo o błędy, zwłaszcza na początku. Chciałbym zwrócić uwagę na kilka typowych pułapek:

  • Nadmierna manipulacja DOM w pętlach: Wielokrotne dodawanie elementów do DOM w pętli może być nieefektywne i spowalniać aplikację. Zamiast tego, zalecam użycie `DocumentFragment`. Pozwala on zbudować całą strukturę poza DOM, a następnie wstawić ją jednokrotnie, co jest znacznie szybsze.
  • Brak walidacji danych: Zawsze zakładaj, że dane wejściowe mogą być niepoprawne. Upewnij się, że Twoje funkcje radzą sobie z nieoczekiwanymi wartościami, np. dla roku czy miesiąca.
  • Nieczytelny kod: Staraj się pisać czysty, dobrze skomentowany kod. Używaj sensownych nazw zmiennych i funkcji. Pamiętaj, że kod jest czytany znacznie częściej niż pisany.
  • Brak obsługi błędów: Zastanów się, co się stanie, jeśli coś pójdzie nie tak (np. element HTML nie zostanie znaleziony). Proste mechanizmy obsługi błędów mogą zapobiec awarii aplikacji.

Stworzenie podstawowego kalendarza to dopiero początek! Oto kilka pomysłów na dalszą rozbudowę, które mogą Cię zainspirować:

  • Dodawanie i wyświetlanie wydarzeń: Po kliknięciu w dany dzień, możesz otworzyć modalne okno, które pozwoli użytkownikowi dodać wydarzenie. Następnie możesz wyświetlać małe kropki lub ikony pod dniami, które mają przypisane wydarzenia.
  • Integracja z zewnętrznymi API: Wyobraź sobie kalendarz, który automatycznie pobiera święta państwowe z API, albo integruje się z Google Calendar, wyświetlając wydarzenia z konta użytkownika. To otwiera ogromne możliwości.
  • Stworzenie "date pickera" do formularzy: Kalendarz jest idealnym komponentem do wyboru daty w formularzach. Możesz go przekształcić w rozwijany "date picker", który pojawia się po kliknięciu w pole formularza i pozwala użytkownikowi intuicyjnie wybrać datę.
  • Personalizacja i motywy: Pozwól użytkownikom zmieniać kolory, czcionki lub układ kalendarza, oferując różne motywy.
  • Widok tygodniowy/miesięczny: Dodaj możliwość przełączania między widokiem miesięcznym a tygodniowym.

Źródło:

[1]

https://brylka.net/refaktoryzacja-i-rozbudowa-kalendarza-w-html-css-i-jquery

[2]

https://creativecoding.pl/jak-zrobic-kalendarz-na-stronie-html/

FAQ - Najczęstsze pytania

`

W Polsce tydzień zaczyna się od poniedziałku. Metoda `getDay()` w JS zwraca 0 dla niedzieli. Aby to skorygować, użyj formuły `(firstDayOfMonth + 6) % 7`. Zapewni to, że poniedziałek będzie miał indeks 0, a niedziela 6, co odzwierciedli polski standard.

Tak, to popularne rozszerzenie. Możesz dodać funkcjonalność, która po kliknięciu w dzień otwiera modalne okno do dodawania wydarzeń. Następnie wyświetlaj je jako małe znaczniki pod dniami. Możliwa jest też integracja z zewnętrznymi API, np. Google Calendar.

Użyj `media queries` w CSS. Pozwalają one dostosować style (np. szerokość kontenera, rozmiar czcionek, padding) w zależności od szerokości ekranu. Dzięki temu kalendarz będzie czytelny i użyteczny zarówno na desktopie, jak i smartfonie.

Tagi:

jak zrobić kalendarz w html
jak stworzyć kalendarz w html css js
dynamiczny kalendarz na stronę www
interaktywny kalendarz javascript tutorial
generowanie kalendarza html css javascript
kod kalendarza html js

Udostępnij artykuł

Autor Olaf Dudek
Olaf Dudek
Nazywam się Olaf Dudek i od ponad dziesięciu lat zajmuję się analizą oraz pisaniem o technologiach. Moje doświadczenie obejmuje szeroki zakres tematów, od nowoczesnych rozwiązań programistycznych po innowacje w dziedzinie sztucznej inteligencji. Jako doświadczony twórca treści, moim celem jest uproszczenie złożonych danych i dostarczanie obiektywnej analizy, która pozwala czytelnikom lepiej zrozumieć dynamiczny świat technologii. Specjalizuję się w badaniu trendów rynkowych oraz ocenie wpływu nowych technologii na różne branże. Z pasją śledzę najnowsze osiągnięcia i zmiany w tym obszarze, co pozwala mi dostarczać aktualne i rzetelne informacje. Moja misja to zapewnienie czytelnikom źródła wiedzy, które jest nie tylko dokładne, ale także inspirujące i pomocne w podejmowaniu świadomych decyzji w świecie technologii.

Napisz komentarz