HTML, CSS ve JavaScript ile Mobil Uyumlu Minimal Takvim Uygulaması

Web projelerinde sıklıkla ihtiyaç duyulan takvim bileşenini, sade tasarımı ve mobil uyumu ile sıfırdan oluşturuyoruz. HTML, CSS ve JavaScript kullanarak pratik ve kullanıcı dostu bir takvim nasıl yapılır birlikte inceleyelim.

HTML, CSS ve JavaScript ile Mobil Uyumlu Minimal Takvim Uygulaması

Web projelerinde kullanıcı deneyimini artırmak isteyen geliştiricilerin sıklıkla ihtiyaç duyduğu bileşenlerden biri de takvim bileşenidir. Bu yazıda, tamamen HTML, CSS ve JavaScript kullanarak nasıl şık, işlevsel ve mobil uyumlu bir takvim oluşturabileceğimizi adım adım anlatacağım.


Kullanılan Teknolojiler

  • HTML5: Yapının temel iskeleti
  • CSS3: Stil ve duyarlılık (responsive tasarım)
  • JavaScript (Vanilla): Dinamik içerik üretimi ve etkileşim
  • FontAwesome: Görsel zenginlik için ikonlar

Takvim Özellikleri

Bu takvim sadece görsel olarak değil, aynı zamanda kullanım açısından da kullanıcı dostu olacak şekilde tasarlanmıştır:

  • Bugünü belirgin biçimde öne çıkaran stil
  • Ay ve yıl seçim alanları
  • İleri-geri navigasyon
  • Mobil cihazlara uygun duyarlı yapı
  • FontAwesome ikon desteği

Teknik Detaylar

1. HTML Yapısı

HTML yapısı, takvimin temel iskeletini oluşturur. Üç ana bölüm içerir:

  • Navigasyon alanı (ay/yıl seçimi, ileri/geri butonlar)
  • Gün isimleri
  • Gün kutuları

2. CSS ile Stil ve Duyarlılık

Stil dosyamızda flex ve grid yapıları sayesinde kutucuk düzeni ve responsive (mobil uyumlu) görünüm sağlandı. @media ile mobil cihazlarda daha küçük yazı tipi ve daha kompakt yapı sunuluyor.

Bugün tarihini ön plana çıkaran stil:

.today {
  background: #ff5722;
  color: white;
  font-weight: bold;
  border: 2px solid #e64a19;
  transform: scale(1.05);
  pointer-events: none;
}
Code language: CSS (css)

3. JavaScript ile Dinamik Takvim

Takvimin ay ve yıl değişimlerine göre yeniden çizilmesi, boş hücrelerin hesaplanması ve günlerin oluşturulması tamamen JavaScript tarafından yapılmakta. Ayrıca kullanıcı select menülerle farklı tarihleri kolayca görüntüleyebilir.

function renderCalendar() {
  // Ay başı ve son günü hesaplanıyor
  ...
  for (let i = 1; i <= lastDay; i++) {
    const day = document.createElement('div');
    day.classList.add('day');
    if (i === today.getDate() && ... ) {
      day.classList.add('today');
    }
    daysContainer.appendChild(day);
  }
}
Code language: JavaScript (javascript)

Mobil Duyarlılık

Mobil kullanıcılar için max-width: 600px altında görünüm otomatik olarak sadeleştirilir. Select menüler tam genişlikte gösterilir ve padding oranları düşürülür.


Sonuç

Bu proje, tarihsel içerik gösterimi gereken her web projesi için esnek, sade ve kullanışlı bir çözüm sunuyor. Daha da ileriye gitmek istersen:

  • Etkinlik ekleme
  • Takvimden tarih seçme
  • Tatil entegrasyonu
  • Sunucu tarafı veri bağlama

gibi özelliklerle projeyi genişletebilirsin.

Demo

<!DOCTYPE html>
<html lang="tr">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Minimal Takvim</title>
  <!-- FontAwesome ikonları için stil dosyası -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <style>
    /* Genel kutu modeli ve yazı tipi */
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
      font-family: Arial, sans-serif;
    }

    /* Sayfa ortalama ve arka plan rengi */
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      padding: 5%;
      background-color: #f4f4f4;
    }

    /* Takvim ana kutusu */
    .calendar {
      background: #fff;
      border-radius: 16px;
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
      padding: 20px;
      width: 100%;
      max-width: 500px;
    }

    /* Başlık kısmı: ay/yıl seçimi ve ileri/geri butonlar */
    .calendar-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 10px;
      flex-wrap: wrap;
      gap: 10px;
    }

    /* Açılır menülerin görünümü */
    .calendar-header select {
      padding: 5px;
      border-radius: 6px;
      border: 1px solid #ccc;
      font-size: 1rem;
    }

    /* İleri/geri butonları */
    .calendar-header button {
      background: none;
      border: none;
      cursor: pointer;
      font-size: 1.2rem;
      color: #555;
    }

    /* Gün kutuları ızgara düzeni */
    .calendar-days {
      display: grid;
      grid-template-columns: repeat(7, 1fr);
      gap: 5px;
      margin-top: 10px;
    }

    /* Gün ismi ve sayı kutuları */
    .day-name, .day {
      text-align: center;
      padding: 10px;
    }

    /* Haftanın günleri başlığı */
    .day-name {
      font-weight: bold;
      color: #888;
    }

    /* Gün kutuları stil */
    .day {
      background: #f9f9f9;
      border-radius: 8px;
      cursor: pointer;
      transition: background 0.3s, transform 0.2s;
    }

    /* Bugünün dışındaki günlerde hover efekti */
    .day:hover:not(.today) {
      background: #e0e0e0;
    }

    /* Bugün için özel stil */
    .today {
      background: #ff5722;
      color: white;
      font-weight: bold;
      border: 2px solid #e64a19;
      transform: scale(1.05);
      pointer-events: none;
    }

    /* Mobil cihazlar için uyumlu görünüm */
    @media (max-width: 600px) {
      .calendar {
        padding: 15px;
      }
      .day, .day-name {
        padding: 8px;
        font-size: 0.85rem;
      }
      .calendar-header {
        flex-direction: column;
        align-items: stretch;
      }
      .calendar-header select {
        width: 100%;
      }
    }
  </style>
</head>
<body>
  <div class="calendar">
    <div class="calendar-header">
      <!-- Geri butonu -->
      <button id="prevMonth"><i class="fas fa-chevron-left"></i></button>
      <!-- Ay ve yıl seçiciler -->
      <div>
        <select id="monthSelect"></select>
        <select id="yearSelect"></select>
      </div>
      <!-- İleri butonu -->
      <button id="nextMonth"><i class="fas fa-chevron-right"></i></button>
    </div>
    <!-- Gün isimleri kutuları -->
    <div class="calendar-days" id="dayNames"></div>
    <!-- Gün kutuları -->
    <div class="calendar-days" id="days"></div>
  </div>

  <script>
    // Haftanın günleri kısaltmaları
    const dayNames = ['Pzt', 'Sal', 'Çar', 'Per', 'Cum', 'Cmt', 'Paz'];

    // HTML elementlerini seçiyoruz
    const dayNamesContainer = document.getElementById('dayNames');
    const daysContainer = document.getElementById('days');
    const monthSelect = document.getElementById('monthSelect');
    const yearSelect = document.getElementById('yearSelect');
    let date = new Date(); // Mevcut tarih

    // Ay ve yıl seçeneklerini doldur
    function populateSelects() {
      const months = [...Array(12).keys()].map(i => new Date(0, i).toLocaleString('tr-TR', { month: 'long' }));
      months.forEach((month, index) => {
        const option = document.createElement('option');
        option.value = index;
        option.textContent = month;
        monthSelect.appendChild(option);
      });

      const currentYear = new Date().getFullYear();
      for (let y = currentYear - 5; y <= currentYear + 5; y++) {
        const option = document.createElement('option');
        option.value = y;
        option.textContent = y;
        yearSelect.appendChild(option);
      }
    }

    // Takvimi oluştur
    function renderCalendar() {
      date.setDate(1);
      const month = date.getMonth();
      const year = date.getFullYear();

      // Ayın hangi günde başladığını bul
      const firstDayIndex = date.getDay() === 0 ? 6 : date.getDay() - 1;
      const lastDay = new Date(year, month + 1, 0).getDate();

      // Seçicileri güncelle
      monthSelect.value = month;
      yearSelect.value = year;

      daysContainer.innerHTML = '';

      // Ay başına kadar boş kutular
      for (let i = 0; i < firstDayIndex; i++) {
        const emptyDiv = document.createElement('div');
        daysContainer.appendChild(emptyDiv);
      }

      // Günleri oluştur
      for (let i = 1; i <= lastDay; i++) {
        const day = document.createElement('div');
        day.classList.add('day');
        day.textContent = i;

        // Bugün ise özel stil ver
        const today = new Date();
        if (i === today.getDate() && month === today.getMonth() && year === today.getFullYear()) {
          day.classList.add('today');
        }

        daysContainer.appendChild(day);
      }
    }

    // Gün isimlerini ekle
    function renderDayNames() {
      dayNames.forEach(name => {
        const div = document.createElement('div');
        div.classList.add('day-name');
        div.textContent = name;
        dayNamesContainer.appendChild(div);
      });
    }

    // Ayı geri al
    document.getElementById('prevMonth').addEventListener('click', () => {
      date.setMonth(date.getMonth() - 1);
      renderCalendar();
    });

    // Ayı ileri al
    document.getElementById('nextMonth').addEventListener('click', () => {
      date.setMonth(date.getMonth() + 1);
      renderCalendar();
    });

    // Ay seçimi değiştiğinde takvimi güncelle
    monthSelect.addEventListener('change', () => {
      date.setMonth(parseInt(monthSelect.value));
      renderCalendar();
    });

    // Yıl seçimi değiştiğinde takvimi güncelle
    yearSelect.addEventListener('change', () => {
      date.setFullYear(parseInt(yearSelect.value));
      renderCalendar();
    });

    // İlk çalıştırma işlemleri
    populateSelects();
    renderDayNames();
    renderCalendar();
  </script>
</body>
</html>
Code language: HTML, XML (xml)

Yazar Metin METE

Yazmayı, üretmeyi, öğrenmeyi ve paylaşmayı seven; tasarım, kodlama ve yaratıcılıkla dijital dünyaya iz bırakmak isteyen bir hayalperest.

Henüz yorum yok

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir