Neumorphic Calendar - MeggiTools
Run
Toggle Theme
Share Link
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Neumorphic Calendar</title> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"> <style> body { font-family: 'Arial', sans-serif; background: #e0e5ec; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .calendar { background: #e0e5ec; border-radius: 15px; box-shadow: 9px 9px 16px #a3b1c6, -9px -9px 16px #ffffff; overflow: hidden; width: 370px; padding: 20px; } .calendar-header { display: flex; justify-content: space-between; align-items: center; padding-bottom: 20px; font-size: 22px; } .calendar-header h2 { margin: 0; font-size: 1.7em; } .calendar-header select { background: #e0e5ec; border: none; box-shadow: inset 5px 5px 10px #a3b1c6, inset -5px -5px 10px #ffffff; border-radius: 10px; color: #333; font-size: 1.2em; margin: 0 5px; padding: 5px; } .calendar-header button { background: none; border: none; color: #333; cursor: pointer; font-size: 1.4em; } .calendar-header button:focus { outline: none; } .calendar-body { display: grid; grid-template-columns: repeat(7, 1fr); gap: 10px; padding: 10px 0; } .calendar-day { width: 40px; height: 40px; display: flex; justify-content: center; align-items: center; border-radius: 50%; background: #e0e5ec; box-shadow: 5px 5px 10px #a3b1c6, -5px -5px 10px #ffffff; transition: transform 0.3s, box-shadow 0.3s; cursor: pointer; } .calendar-day:hover { transform: translateY(-3px); box-shadow: 7px 7px 15px #a3b1c6, -7px -7px 15px #ffffff; } .calendar-day.active { background: #6a5acd; color: white; } .calendar-day span { font-size: 1.2em; } .calendar-footer { display: flex; justify-content: center; padding-top: 20px; } .calendar-footer button { background: #6a5acd; border: none; color: white; cursor: pointer; font-size: 1.1em; padding: 8px 16px; border-radius: 5px; transition: background 0.3s; } .calendar-footer button:hover { background: #584ac3; } </style> </head> <body> <div class="calendar"> <div class="calendar-header"> <button type="button" id="prevMonth" title="Previous"><i class="fas fa-chevron-left"></i></button> <select id="monthSelect" title="Month"></select> <select id="yearSelect" title="Year"></select> <button type="button" id="nextMonth" title="Next"><i class="fas fa-chevron-right"></i></button> </div> <div class="calendar-body" id="calendarBody"></div> <div class="calendar-footer"> <button type="button" id="todayBtn">Today</button> </div> </div> <script> const calendarBody = document.getElementById('calendarBody'); const monthSelect = document.getElementById('monthSelect'); const yearSelect = document.getElementById('yearSelect'); const prevMonth = document.getElementById('prevMonth'); const nextMonth = document.getElementById('nextMonth'); const todayBtn = document.getElementById('todayBtn'); let currentDate = new Date(); const months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; function populateMonthSelect() { months.forEach((month, index) => { const option = document.createElement('option'); option.value = index; option.textContent = month; monthSelect.appendChild(option); }); } function populateYearSelect() { const currentYear = new Date().getFullYear(); for (let i = currentYear - 50; i <= currentYear + 50; i++) { const option = document.createElement('option'); option.value = i; option.textContent = i; yearSelect.appendChild(option); } } function renderCalendar(date) { const year = date.getFullYear(); const month = date.getMonth(); const firstDayOfMonth = new Date(year, month, 1).getDay(); const lastDateOfMonth = new Date(year, month + 1, 0).getDate(); const lastDayOfLastMonth = new Date(year, month, 0).getDate(); monthSelect.value = month; yearSelect.value = year; calendarBody.innerHTML = ''; for (let i = firstDayOfMonth; i > 0; i--) { calendarBody.innerHTML += `<div class="calendar-day inactive">${lastDayOfLastMonth - i + 1}</div>`; } for (let i = 1; i <= lastDateOfMonth; i++) { calendarBody.innerHTML += `<div class="calendar-day ${i === date.getDate() ? 'active' : ''}"><span>${i}</span></div>`; } const totalDays = firstDayOfMonth + lastDateOfMonth; const nextDays = 7 - (totalDays % 7); for (let i = 1; i <= nextDays; i++) { calendarBody.innerHTML += `<div class="calendar-day inactive">${i}</div>`; } } prevMonth.addEventListener('click', () => { currentDate.setMonth(currentDate.getMonth() - 1); renderCalendar(currentDate); }); nextMonth.addEventListener('click', () => { currentDate.setMonth(currentDate.getMonth() + 1); renderCalendar(currentDate); }); monthSelect.addEventListener('change', (e) => { currentDate.setMonth(e.target.value); renderCalendar(currentDate); }); yearSelect.addEventListener('change', (e) => { currentDate.setFullYear(e.target.value); renderCalendar(currentDate); }); todayBtn.addEventListener('click', () => { currentDate = new Date(); renderCalendar(currentDate); }); populateMonthSelect(); populateYearSelect(); renderCalendar(currentDate); </script> </body> </html>