Create Airline Reservation System Using HTML, CSS, and JavaScript

Faraz

By Faraz -

Learn how to create an airline reservation system using HTML, CSS (TailwindCSS), and JavaScript. Follow our step-by-step guide for building a functional flight booking system.


create-airline-reservation-system-using-html-css-and-javascript.webp

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Conclusion
  6. Preview

In this blog, we'll guide you through building a simple airline reservation system using HTML, CSS (TailwindCSS), and JavaScript. This system will allow users to select their flights, input personal details, and view available seats, offering an interactive and user-friendly experience.

To create this system, you'll need a basic understanding of HTML, CSS, and JavaScript. TailwindCSS will be used to style the system, making it visually appealing and responsive. Airline reservation systems like this are widely used in the travel industry, making them valuable for real-world applications. Let's dive in!

Source Code

Step 1 (HTML Code):

The first step is to create the structure of the reservation system using HTML. This includes the basic elements that the user will interact with. We'll create a form where passengers can input their personal information, select their desired flight, and choose the number of seats.

Step 2 (CSS Code):

Now that we have the basic structure, we need to style the system to make it look appealing and user-friendly. CSS will be used to style the form, buttons, and input fields. It will also make the system responsive, ensuring it works well on both desktop and mobile devices.

body {
    font-family: 'Inter', sans-serif;
    background-color: #f0f2f5;
    /* Light gray background */
}

.nav-link-custom {
    padding-left: 0.75rem;
    /* px-3 */
    padding-right: 0.75rem;
    /* px-3 */
    padding-top: 0.5rem;
    /* py-2 */
    padding-bottom: 0.5rem;
    /* py-2 */
    border-radius: 0.375rem;
    /* rounded-md */
    font-size: 0.875rem;
    /* text-sm */
    line-height: 1.25rem;
    font-weight: 500;
    /* font-medium */
    color: #d1d5db;
    /* text-gray-300 */
    transition-property: background-color, color;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-duration: 150ms;
}

.nav-link-custom:hover {
    background-color: #0284c7;
    /* hover:bg-sky-600 */
    color: #ffffff;
    /* hover:text-white */
}

.nav-link-active-custom {
    background-color: #0369a1;
    /* bg-sky-700 */
    color: #ffffff;
    /* text-white */
}

.btn-custom {
    padding-left: 1.5rem;
    /* px-6 */
    padding-right: 1.5rem;
    /* px-6 */
    padding-top: 0.75rem;
    /* py-3 */
    padding-bottom: 0.75rem;
    /* py-3 */
    border-radius: 0.5rem;
    /* rounded-lg */
    font-weight: 600;
    /* font-semibold */
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
    /* shadow-md */
    transition-property: all;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-duration: 300ms;
}

.btn-primary-custom {
    background-color: #0ea5e9;
    /* bg-sky-600 */
    color: #ffffff;
    /* text-white */
}

.btn-primary-custom:hover {
    background-color: #0284c7;
    /* hover:bg-sky-700 */
}

.btn-primary-custom:focus {
    outline: 2px solid transparent;
    outline-offset: 2px;
    --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
    --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);
    box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
    --tw-ring-color: #7dd3fc;
    /* focus:ring-sky-300 */
}


.btn-secondary-custom {
    background-color: #e5e7eb;
    /* bg-gray-200 */
    color: #374151;
    /* text-gray-700 */
}

.btn-secondary-custom:hover {
    background-color: #d1d5db;
    /* hover:bg-gray-300 */
}

.btn-secondary-custom:focus {
    outline: 2px solid transparent;
    outline-offset: 2px;
    --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
    --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);
    box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
    --tw-ring-color: #d1d5db;
    /* focus:ring-gray-300 */
}

.card-custom {
    background-color: #ffffff;
    /* bg-white */
    border-radius: 0.75rem;
    /* rounded-xl */
    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
    /* shadow-lg */
    overflow: hidden;
}

.input-field-custom {
    width: 100%;
    padding-left: 1rem;
    /* px-4 */
    padding-right: 1rem;
    /* px-4 */
    padding-top: 0.75rem;
    /* py-3 */
    padding-bottom: 0.75rem;
    /* py-3 */
    border-radius: 0.5rem;
    /* rounded-lg */
    border-width: 1px;
    border-color: #d1d5db;
    /* border-gray-300 */
    transition-property: box-shadow;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-duration: 150ms;
}

.input-field-custom:focus {
    outline: 2px solid transparent;
    outline-offset: 2px;
    --tw-ring-color: #0ea5e9;
    /* focus:ring-sky-500 */
    border-color: transparent;
    /* focus:border-transparent */
    --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
    --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
    box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
}

.form-label-custom {
    display: block;
    margin-bottom: 0.5rem;
    /* mb-2 */
    font-size: 0.875rem;
    /* text-sm */
    line-height: 1.25rem;
    font-weight: 500;
    /* font-medium */
    color: #374151;
    /* text-gray-700 */
}

.skeleton-custom {
    background-color: #d1d5db;
    /* bg-gray-300 */
    border-radius: 0.25rem;
    /* rounded */
    animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

@keyframes pulse {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: .5;
    }
}

.toast-custom {
    position: fixed;
    bottom: 1.25rem;
    /* bottom-5 */
    right: 1.25rem;
    /* right-5 */
    background-color: #22c55e;
    /* bg-green-500 default */
    color: #ffffff;
    /* text-white */
    padding-left: 1.5rem;
    /* px-6 */
    padding-right: 1.5rem;
    /* px-6 */
    padding-top: 0.75rem;
    /* py-3 */
    padding-bottom: 0.75rem;
    /* py-3 */
    border-radius: 0.5rem;
    /* rounded-lg */
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
    /* shadow-xl */
    transition-property: all;
    transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
    transition-duration: 500ms;
    transform: translateY(100%);
    opacity: 0;
}

.toast-custom.show {
    transform: translateY(0);
    opacity: 1;
}

.modal-backdrop-custom {
    position: fixed;
    inset: 0;
    background-color: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 50;
    transition-property: opacity;
    transition-duration: 300ms;
    opacity: 0;
    pointer-events: none;
}

.modal-backdrop-custom.show {
    opacity: 1;
    pointer-events: auto;
}

.modal-content-custom {
    background-color: #ffffff;
    /* bg-white */
    padding: 2rem;
    /* p-8 */
    border-radius: 0.75rem;
    /* rounded-xl */
    box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
    /* shadow-2xl */
    width: 100%;
    max-width: 28rem;
    /* max-w-md */
    transform: scale(0.95);
    transition-property: transform;
    transition-duration: 300ms;
}

.modal-backdrop-custom.show .modal-content-custom {
    transform: scale(1);
}

.seat-base {
    /* Base styles for seats */
    border-width: 2px;
    border-color: #d1d5db;
    /* border-gray-300 */
    border-radius: 0.375rem;
    /* rounded-md */
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition-property: all;
    transition-duration: 200ms;
}

/* Sizes applied directly with Tailwind classes w-8 h-8 md:w-10 md:h-10 */

.seat-available {
    background-color: #d1fae5;
    /* bg-green-100 */
    border-color: #6ee7b7;
    /* border-green-400 */
}

.seat-available:hover {
    background-color: #a7f3d0;
    /* hover:bg-green-300 */
}

.seat-selected {
    background-color: #0ea5e9;
    /* bg-sky-500 */
    color: #ffffff;
    /* text-white */
    border-color: #0369a1;
    /* border-sky-700 */
}

.seat-occupied {
    background-color: #9ca3af;
    /* bg-gray-400 */
    cursor: not-allowed;
    border-color: #6b7280;
    /* border-gray-500 */
}

/* Custom Scrollbar */
::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: #f0f2f5;
}

::-webkit-scrollbar-thumb {
    background: #cbd5e1;
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    background: #94a3b8;
}

/* Lucide icon sizes */
.lucide {
    width: 24px;
    height: 24px;
    stroke-width: 2;
}

.lucide-sm {
    width: 18px;
    height: 18px;
}

.lucide-lg {
    width: 32px;
    height: 32px;
} 

Step 3 (JavaScript Code):

The final step is to add interactivity to the system using JavaScript. We will write a script to validate user inputs, dynamically display available flights based on user selection, and calculate the total cost of the reservation.

document.addEventListener('DOMContentLoaded', () => {
    // Initialize Lucide icons
    lucide.createIcons();

    // Page navigation logic
    const allNavLinks = document.querySelectorAll('.nav-link-custom, .btn-custom[data-page], .footer-nav-link[data-page]');
    const pageSections = document.querySelectorAll('.page-section');
    const mainContent = document.getElementById('mainContent');
    const skeletonLoaderResults = document.getElementById('skeletonLoaderResults');
    const actualFlightResults = document.getElementById('actualFlightResults');

    function setActivePage(pageId, skipScroll = false) {
        pageSections.forEach(section => {
            if (section) section.classList.add('hidden');
        });
        const activePage = document.getElementById(pageId);
        if (activePage) {
            activePage.classList.remove('hidden');
            if (!skipScroll && mainContent) {
                // Scroll to top of main content, not the entire window
                mainContent.scrollIntoView({ behavior: 'smooth', block: 'start' });
            }

            if (pageId === 'searchResults') {
                if (skeletonLoaderResults) skeletonLoaderResults.style.display = 'block';
                if (actualFlightResults) actualFlightResults.classList.add('hidden');
                setTimeout(() => {
                    if (skeletonLoaderResults) skeletonLoaderResults.style.display = 'none';
                    if (actualFlightResults) actualFlightResults.classList.remove('hidden');
                    lucide.createIcons();
                }, 1500);
            }
        } else {
            console.warn(`Page section with ID "${pageId}" not found.`);
        }

        // Update active link styling for main nav and mobile nav
        document.querySelectorAll('.nav-link-custom').forEach(link => {
            if (link) {
                link.classList.remove('nav-link-active-custom');
                if (link.dataset.page === pageId) {
                    link.classList.add('nav-link-active-custom');
                }
            }
        });

        const mobileMenuElement = document.getElementById('mobile-menu');
        if (mobileMenuElement && mobileMenuElement.classList.contains('block')) {
            toggleMobileMenu(); // Close mobile menu after navigation
        }
        lucide.createIcons(); // Re-render icons after page change
    }

    allNavLinks.forEach(link => {
        if (link) {
            link.addEventListener('click', (e) => {
                e.preventDefault();
                const pageId = link.dataset.page;
                if (pageId) {
                    setActivePage(pageId);
                }
            });
        }
    });

    setActivePage('home', true); // Initial page load (Home), skip scroll

    // Mobile Menu Toggle
    const mobileMenuButton = document.getElementById('mobileMenuButton');
    const mobileMenu = document.getElementById('mobile-menu');

    function toggleMobileMenu() {
        if (mobileMenu && mobileMenuButton) {
            mobileMenu.classList.toggle('hidden');
            mobileMenu.classList.toggle('block');
            // Toggle icons by finding them within the button
            const icons = mobileMenuButton.querySelectorAll('.current-icon');
            icons.forEach(icon => icon.classList.toggle('hidden'));
        }
    }
    if (mobileMenuButton) {
        mobileMenuButton.addEventListener('click', toggleMobileMenu);
    }


    // Login Modal Logic
    const loginModal = document.getElementById('loginModal');
    const loginModalButton = document.getElementById('loginModalButton');
    const loginModalButtonMobile = document.getElementById('loginModalButtonMobile');
    const closeLoginModalButton = document.getElementById('closeLoginModal');
    const loginForm = document.getElementById('loginForm'); // Changed from loginSubmitButton to the form
    const userProfileDropdownContainer = document.getElementById('userProfileDropdownContainer');
    const userProfileDropdownContainerMobile = document.getElementById('userProfileDropdownContainerMobile');

    function openLoginModal() { if (loginModal) loginModal.classList.add('show'); }
    function closeLoginModal() { if (loginModal) loginModal.classList.remove('show'); }

    if (loginModalButton) loginModalButton.addEventListener('click', openLoginModal);
    if (loginModalButtonMobile) loginModalButtonMobile.addEventListener('click', openLoginModal);
    if (closeLoginModalButton) closeLoginModalButton.addEventListener('click', closeLoginModal);

    if (loginModal) {
        loginModal.addEventListener('click', (e) => {
            if (e.target === loginModal) closeLoginModal();
        });
    }
    if (loginForm) {
        loginForm.addEventListener('submit', (e) => { // Changed to listen to form submit
            e.preventDefault();
            closeLoginModal();
            showToast('Login successful! Welcome back.', 'success');
            if (loginModalButton) loginModalButton.classList.add('hidden');
            if (loginModalButtonMobile) loginModalButtonMobile.classList.add('hidden');
            if (userProfileDropdownContainer) userProfileDropdownContainer.classList.remove('hidden');
            if (userProfileDropdownContainerMobile) userProfileDropdownContainerMobile.classList.remove('hidden');
            lucide.createIcons(); // Refresh icons if profile pic appears
        });
    }

    // User Profile Dropdown Toggle
    const userMenuButton = document.getElementById('user-menu-button');
    const userProfileDropdown = document.getElementById('userProfileDropdown');

    if (userMenuButton && userProfileDropdown) {
        userMenuButton.addEventListener('click', () => {
            const isExpanded = userMenuButton.getAttribute('aria-expanded') === 'true' || false;
            userMenuButton.setAttribute('aria-expanded', String(!isExpanded));
            userProfileDropdown.classList.toggle('hidden');
        });
        document.addEventListener('click', (event) => {
            if (userProfileDropdown && !userProfileDropdown.classList.contains('hidden') && userMenuButton && !userMenuButton.contains(event.target) && !userProfileDropdown.contains(event.target)) {
                userProfileDropdown.classList.add('hidden');
                userMenuButton.setAttribute('aria-expanded', 'false');
            }
        });
    }

    // Toast Notification Logic
    const toastNotification = document.getElementById('toastNotification');
    const toastMessage = document.getElementById('toastMessage');
    function showToast(message, type = 'success') {
        if (toastMessage && toastNotification) {
            toastMessage.textContent = message;
            toastNotification.classList.remove('bg-red-500', 'bg-yellow-500', 'bg-green-500', 'bg-sky-500'); // Clear other types
            if (type === 'success') toastNotification.classList.add('bg-green-500');
            else if (type === 'error') toastNotification.classList.add('bg-red-500');
            else if (type === 'warning') toastNotification.classList.add('bg-yellow-500');
            else if (type === 'info') toastNotification.classList.add('bg-sky-500'); // Added info type

            toastNotification.classList.add('show');
            setTimeout(() => {
                toastNotification.classList.remove('show');
            }, 3000);
        }
    }

    // Confirm Booking Button
    const confirmBookingButton = document.getElementById('confirmBookingButton');
    if (confirmBookingButton) {
        confirmBookingButton.addEventListener('click', () => {
            showToast('Booking Confirmed! Check your email for details.', 'success');
            setTimeout(() => setActivePage('dashboard'), 1000);
        });
    }

    // Seat Selection Logic
    const seatMapContainer = document.getElementById('seatMapContainer');
    const selectedSeatDisplay = document.getElementById('selectedSeatDisplay');
    if (seatMapContainer && selectedSeatDisplay) {
        seatMapContainer.addEventListener('click', (e) => {
            const seat = e.target.closest('.seat-base'); // Target base class
            if (seat && !seat.classList.contains('seat-occupied')) {
                const currentSelected = seatMapContainer.querySelector('.seat-selected');
                if (currentSelected && currentSelected !== seat) {
                    currentSelected.classList.remove('seat-selected');
                    currentSelected.classList.add('seat-available');
                }
                seat.classList.toggle('seat-selected');
                seat.classList.toggle('seat-available'); // Toggle available only if not becoming selected

                const newlySelectedSeat = seatMapContainer.querySelector('.seat-selected');
                selectedSeatDisplay.textContent = newlySelectedSeat ? newlySelectedSeat.dataset.seat : 'None';
            }
        });
    }

    // Dashboard Navigation
    const dashboardNavItems = document.querySelectorAll('.dashboard-nav-item');
    const dashboardContents = document.querySelectorAll('.dashboard-content');

    dashboardNavItems.forEach(item => {
        if (item) {
            item.addEventListener('click', (e) => {
                e.preventDefault();
                const targetHref = item.getAttribute('href');
                if (!targetHref || !targetHref.startsWith('#')) return; // Basic check for valid href

                // Handle logout separately
                if (item.id === 'dashboardLogoutButton') {
                    showToast('Logged out successfully.', 'info');
                    // Simulate logged out state
                    if (loginModalButton) loginModalButton.classList.remove('hidden');
                    if (loginModalButtonMobile) loginModalButtonMobile.classList.remove('hidden');
                    if (userProfileDropdownContainer) userProfileDropdownContainer.classList.add('hidden');
                    if (userProfileDropdownContainerMobile) userProfileDropdownContainerMobile.classList.add('hidden');
                    if (userProfileDropdown && !userProfileDropdown.classList.contains('hidden')) userProfileDropdown.classList.add('hidden'); // Close dropdown if open
                    setActivePage('home');
                    return;
                }

                const targetId = targetHref.substring(1) + 'Content';

                dashboardNavItems.forEach(nav => {
                    if (nav) {
                        nav.classList.remove('bg-sky-100', 'text-sky-700');
                        nav.classList.add('text-gray-600');
                    }
                });
                item.classList.add('bg-sky-100', 'text-sky-700');
                item.classList.remove('text-gray-600');

                dashboardContents.forEach(content => {
                    if (content) content.classList.add('hidden');
                });
                const targetContent = document.getElementById(targetId);
                if (targetContent) {
                    targetContent.classList.remove('hidden');
                } else {
                    console.warn(`Dashboard content with ID "${targetId}" not found.`);
                }
                lucide.createIcons();
            });
        }
    });

    // Admin Panel Navigation
    const adminNavItems = document.querySelectorAll('.admin-nav-item');
    const adminContents = document.querySelectorAll('.admin-content');

    adminNavItems.forEach(item => {
        if (item) {
            item.addEventListener('click', (e) => {
                e.preventDefault();
                const targetHref = item.getAttribute('href');
                if (!targetHref || !targetHref.startsWith('#')) return;
                const targetId = targetHref.substring(1) + 'Content';

                adminNavItems.forEach(nav => {
                    if (nav) {
                        nav.classList.remove('bg-sky-100', 'text-sky-700');
                        nav.classList.add('text-gray-600');
                    }
                });
                item.classList.add('bg-sky-100', 'text-sky-700');
                item.classList.remove('text-gray-600');

                adminContents.forEach(content => {
                    if (content) content.classList.add('hidden');
                });
                const targetContent = document.getElementById(targetId);
                if (targetContent) {
                    targetContent.classList.remove('hidden');
                } else {
                    console.warn(`Admin content with ID "${targetId}" not found.`);
                }
                lucide.createIcons();
            });
        }
    });

    // Set current year in footer
    const currentYearEl = document.getElementById('currentYear');
    if (currentYearEl) {
        currentYearEl.textContent = new Date().getFullYear();
    }

    // Flight Search Form Submission
    const flightSearchForm = document.getElementById('flightSearchForm');
    if (flightSearchForm) {
        flightSearchForm.addEventListener('submit', (e) => {
            e.preventDefault();
            setActivePage('searchResults');
            showToast('Searching for flights...', 'info');
        });
    }
}); // End of DOMContentLoaded

Final Output:

create-airline-reservation-system-using-html-css-and-javascript.gif

Conclusion:

In this tutorial, we’ve walked through the process of creating a basic airline reservation system using HTML, CSS (TailwindCSS), and JavaScript. The HTML provided the structure, CSS gave it a clean design, and JavaScript added functionality and interactivity.

To make this system even more robust, you could integrate a payment gateway, allow users to search for available flights, or add booking confirmations. By improving and expanding this system, you can create a more advanced flight booking platform suitable for real-world applications.

Now you have a solid foundation to create your own airline reservation system!

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Thanks!
Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox


Latest Components

Please allow ads on our site🥺