Rent Apartment Booking Template with HTML, TailwindCSS, and JavaScript

Faraz

By Faraz -

Learn how to make a clean rent apartment booking template using HTML, TailwindCSS, and JavaScript. Perfect for real estate websites and rental platforms.


rent-apartment-booking-template-with-html-tailwind-css-and-javascript.webp

Table of Contents

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

If you own a real estate website or a property rental platform, having a clear and user-friendly rent apartment booking template is very important. In this guide, we will show you how to create a rental apartment booking form using HTML and TailwindCSS.

It will have a clean design, a responsive layout, and will be easy to use on both desktop and mobile. Even if you're new to coding, you can follow this step-by-step process.

Prerequisites

Before we begin, you should have:

  • Basic knowledge of HTML, CSS, and JavaScript
  • A code editor like VS Code
  • Internet connection (to load TailwindCSS via CDN)
  • A browser to view your design

Source Code

Step 1 (HTML Code):

To get started, we first need to create a basic HTML file. In this file, we will include the main structure for our rental apartment template.

After creating the file, paste the following code into it. Make sure to save your HTML document with a .html extension so that it can be properly viewed in a web browser.

This is the basic structure of our template using HTML. Now, we can move on to styling it with CSS.

Step 2 (CSS Code):

We’re using Tailwind CSS via CDN, so most of the styling is done with utility classes directly in the HTML. This means we don’t need to write much traditional CSS.

However, to enable smoother scrolling and style the hero section and apartment cards, we’ll add a few custom CSS rules in a separate styles.css file.

 body {
     font-family: 'Inter', sans-serif;
 }

 ::-webkit-scrollbar {
     width: 8px;
 }

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

 ::-webkit-scrollbar-thumb {
     background: #888;
     border-radius: 10px;
 }

 ::-webkit-scrollbar-thumb:hover {
     background: #555;
 }

 .hero-bg {
     background-image: linear-gradient(rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.5)), url('https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/hero-section.webp');
     background-size: cover;
     background-position: center;
 }

 .modal-backdrop {
     background-color: rgba(0, 0, 0, 0.5);
 }

 .map-placeholder {
     background-color: #e0e0e0;
     display: flex;
     align-items: center;
     justify-content: center;
     color: #757575;
     font-size: 1.2rem;
     border-radius: 0.5rem;
 }

 .apartment-card-description {
     height: 80px;
     overflow: hidden;
     text-overflow: ellipsis;
     display: -webkit-box;
     -webkit-line-clamp: 4;
     -webkit-box-orient: vertical;
 } 

Step 3 (JavaScript Code):

Finally, we need to create a function in JavaScript.

Create a JavaScript file with the name script.js and paste the given codes into your JavaScript file and make sure it's linked properly to your HTML document so that the scripts are executed on the page. Remember, you’ve to create a file with .js extension.

const apartmentsData = [
    {
        id: 'apt1',
        name: 'Chic Downtown Loft',
        location: 'Downtown Core',
        price: 2200,
        beds: 1,
        baths: 1,
        sqft: 850,
        description: 'A stylish loft with modern amenities, perfect for professionals seeking city life and vibrant surroundings.',
        imgSrc: 'https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/1.jpeg',
        amenities: ['gym', 'wifi', 'balcony'],
        rating: 4.8
    },
    {
        id: 'apt2',
        name: 'Riverside Serenity Suite',
        location: 'Riverside District',
        price: 1850,
        beds: 2,
        baths: 2,
        sqft: 1100,
        description: 'Enjoy peaceful river views from this beautifully appointed 2-bedroom suite. Ideal for relaxation.',
        imgSrc: 'https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/2.jpeg',
        amenities: ['pool', 'pet friendly', 'balcony'],
        rating: 4.5
    },
    {
        id: 'apt3',
        name: 'Parkview Family Home',
        location: 'Parkside Suburb',
        price: 2900,
        beds: 3,
        baths: 2,
        sqft: 1500,
        description: 'Spacious 3-bedroom home with a garden, ideal for families. Close to parks and schools.',
        imgSrc: 'https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/3.jpeg',
        amenities: ['pet friendly', 'gym'],
        rating: 4.2
    },
    {
        id: 'apt4',
        name: 'Studio Sparkle',
        location: 'Downtown Core',
        price: 1450, // Adjusted price
        beds: 0, // Studio often means 0 dedicated bedrooms
        baths: 1,
        sqft: 550,
        description: 'A bright and modern studio apartment, perfect for solo travelers or couples. Compact and chic.',
        imgSrc: 'https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/4.jpeg',
        amenities: ['wifi', 'gym'],
        rating: 4.0
    },
    {
        id: 'apt5',
        name: 'Uptown Modern Flat',
        location: 'Uptown Views',
        price: 2600,
        beds: 2,
        baths: 2,
        sqft: 1250,
        description: 'Sleek and contemporary 2-bedroom flat in the bustling uptown area with great city views.',
        imgSrc: 'https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/5.jpeg',
        amenities: ['gym', 'pool', 'balcony'],
        rating: 4.7
    },
    {
        id: 'apt6',
        name: 'Cozy Garden Studio',
        location: 'Parkside Suburb',
        price: 1350,
        beds: 1, // Can be a larger studio with a defined bed area
        baths: 1,
        sqft: 600,
        description: 'Charming studio with a private garden entrance. Offers a quiet retreat from city noise.',
        imgSrc: 'https://raw.githubusercontent.com/farazc60/Project-Images/refs/heads/main/Rent%20Apartment%20Booking%20Template/6.jpeg',
        amenities: ['pet friendly', 'wifi'],
        rating: 4.3
    }
];

// --- DOM ELEMENTS ---
const apartmentGrid = document.getElementById('apartment-grid');
const filterLocationSelect = document.getElementById('filter-location');
const filterPriceSelect = document.getElementById('filter-price');
const filterAmenitiesSelect = document.getElementById('filter-amenities');
const sortApartmentsSelect = document.getElementById('sort-apartments');

// --- RENDER FUNCTION ---
function renderApartments(apartmentsToRender) {
    apartmentGrid.innerHTML = ''; // Clear existing cards

    if (apartmentsToRender.length === 0) {
        apartmentGrid.innerHTML = '

No apartments match your criteria.

'; return; } apartmentsToRender.forEach(apt => { const card = ` <div class="bg-white rounded-xl shadow-lg overflow-hidden transform hover:scale-105 transition-transform duration-300 group"> <img src="${apt.imgSrc}" alt="${apt.name}" class="w-full object-cover group-hover:opacity-90 transition-opacity"> <div class="p-6"> <h3 class="text-xl font-semibold text-slate-800 mb-2">${apt.name}</h3> <p class="text-sm text-slate-500 mb-1 flex items-center"> <i class="fas fa-map-marker-alt mr-2 text-emerald-500"></i> ${apt.location} </p> <div class="flex flex-wrap justify-start items-center text-xs text-slate-600 mt-2 mb-3 space-x-3"> <span><i class="fas fa-bed mr-1 text-emerald-500"></i> ${apt.beds === 0 ? 'Studio' : apt.beds + ' Bed'}</span> <span><i class="fas fa-bath mr-1 text-emerald-500"></i> ${apt.baths} Bath</span> <span><i class="fas fa-ruler-combined mr-1 text-emerald-500"></i> ${apt.sqft} sqft</span> </div> <p class="text-lg font-bold text-emerald-600 mb-3">$${apt.price.toLocaleString()} <span class="text-sm font-normal text-slate-500">/month</span></p> <p class="text-slate-600 text-sm mb-4 leading-relaxed apartment-card-description">${apt.description}</p> <button onclick="scrollToBooking('${apt.name}')" class="w-full bg-emerald-500 hover:bg-emerald-600 text-white font-medium py-2.5 px-4 rounded-lg shadow-sm hover:shadow-md transition-all"> Book Now </button> </div> </div> `; apartmentGrid.innerHTML += card; }); } // --- FILTER AND SORT LOGIC --- function applyFiltersAndSort() { let filteredApartments = [...apartmentsData]; // Start with all apartments // Location Filter const selectedLocation = filterLocationSelect.value; if (selectedLocation) { filteredApartments = filteredApartments.filter(apt => apt.location === selectedLocation); } // Price Filter const selectedPriceRange = filterPriceSelect.value; if (selectedPriceRange) { const [minPriceStr, maxPriceStr] = selectedPriceRange.split('-'); const minPrice = parseInt(minPriceStr); const maxPrice = parseInt(maxPriceStr); filteredApartments = filteredApartments.filter(apt => apt.price >= minPrice && apt.price < maxPrice); // Max is exclusive for ranges like "Under 1500" (0-1500) } // Amenities Filter const selectedAmenity = filterAmenitiesSelect.value; if (selectedAmenity) { filteredApartments = filteredApartments.filter(apt => apt.amenities.includes(selectedAmenity.toLowerCase())); } // Sorting const sortBy = sortApartmentsSelect.value; switch (sortBy) { case 'price-asc': filteredApartments.sort((a, b) => a.price - b.price); break; case 'price-desc': filteredApartments.sort((a, b) => b.price - a.price); break; case 'rating-desc': filteredApartments.sort((a, b) => b.rating - a.rating); break; case 'featured': // Default or by ID filteredApartments.sort((a, b) => apartmentsData.findIndex(x => x.id === a.id) - apartmentsData.findIndex(x => x.id === b.id)); break; } renderApartments(filteredApartments); } // --- EVENT LISTENERS --- filterLocationSelect.addEventListener('change', applyFiltersAndSort); filterPriceSelect.addEventListener('change', applyFiltersAndSort); filterAmenitiesSelect.addEventListener('change', applyFiltersAndSort); sortApartmentsSelect.addEventListener('change', applyFiltersAndSort); // --- INITIAL RENDER --- document.addEventListener('DOMContentLoaded', () => { renderApartments(apartmentsData); // Initial load of all apartments // Populate booking form select options dynamically (optional, but good practice) const apartmentBookingSelect = document.getElementById('apartment-select'); // Clear existing options except the first disabled one // apartmentBookingSelect.innerHTML = '<option value="" disabled selected>Choose an apartment</option>'; // The above line will clear static ones. Keeping static ones as per current structure and only adding ones not present. // For this version, I've manually updated the static options in HTML to match apartmentsData. // If apartmentsData was the single source of truth, you'd populate it like this: /* apartmentsData.forEach(apt => { const option = document.createElement('option'); option.value = apt.name; option.textContent = `${apt.name} - $${apt.price}/month`; option.dataset.price = apt.price; apartmentBookingSelect.appendChild(option); }); */ }); const mobileMenuButton = document.getElementById('mobile-menu-button'); const mobileMenu = document.getElementById('mobile-menu'); const hamburgerIcon = document.getElementById('hamburger-icon'); const closeIcon = document.getElementById('close-icon'); mobileMenuButton.addEventListener('click', () => { mobileMenu.classList.toggle('hidden'); hamburgerIcon.classList.toggle('hidden'); closeIcon.classList.toggle('hidden'); if (!mobileMenu.classList.contains('hidden')) { mobileMenu.style.maxHeight = mobileMenu.scrollHeight + "px"; } else { mobileMenu.style.maxHeight = "0px"; } }); document.querySelectorAll('#mobile-menu a').forEach(link => { link.addEventListener('click', () => { mobileMenu.classList.add('hidden'); hamburgerIcon.classList.remove('hidden'); closeIcon.classList.add('hidden'); mobileMenu.style.maxHeight = "0px"; }); }); const today = new Date().toISOString().split('T')[0]; document.getElementById('start-date').setAttribute('min', today); const bookingForm = document.getElementById('bookingForm'); const bookingModal = document.getElementById('bookingModal'); const modalContent = document.getElementById('modalContent'); const closeModalButton = document.getElementById('closeModalButton'); const modalConfirmButton = document.getElementById('modalConfirmButton'); bookingForm.addEventListener('submit', function (event) { event.preventDefault(); const name = document.getElementById('name').value; const email = document.getElementById('email').value; const phone = document.getElementById('phone').value; const apartmentSelect = document.getElementById('apartment-select'); const selectedOption = apartmentSelect.options[apartmentSelect.selectedIndex]; const apartmentName = selectedOption.value; const apartmentPrice = parseFloat(selectedOption.dataset.price); const startDate = document.getElementById('start-date').value; const duration = parseInt(document.getElementById('duration').value); if (isNaN(apartmentPrice) || isNaN(duration) || !apartmentName) { alert("Please select a valid apartment and duration."); return; } const totalCost = apartmentPrice * duration; document.getElementById('summaryName').textContent = name; document.getElementById('summaryEmail').textContent = email; document.getElementById('summaryPhone').textContent = phone; document.getElementById('summaryApartmentName').textContent = apartmentName; document.getElementById('summaryMonthlyCost').textContent = apartmentPrice.toFixed(2); document.getElementById('summaryDuration').textContent = duration; document.getElementById('summaryStartDate').textContent = new Date(startDate).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }); document.getElementById('summaryTotalCost').textContent = totalCost.toFixed(2); bookingModal.classList.remove('hidden'); setTimeout(() => { bookingModal.classList.add('opacity-100'); modalContent.classList.remove('scale-95', 'opacity-0'); modalContent.classList.add('scale-100', 'opacity-100'); }, 10); document.body.style.overflow = 'hidden'; }); function hideModal() { modalContent.classList.remove('scale-100', 'opacity-100'); modalContent.classList.add('scale-95', 'opacity-0'); bookingModal.classList.remove('opacity-100'); setTimeout(() => { bookingModal.classList.add('hidden'); document.body.style.overflow = 'auto'; }, 300); } closeModalButton.addEventListener('click', hideModal); modalConfirmButton.addEventListener('click', () => { hideModal(); bookingForm.reset(); }); bookingModal.addEventListener('click', function (event) { if (event.target === bookingModal) { hideModal(); } }); function scrollToBooking(apartmentName) { const bookingSection = document.getElementById('booking'); const apartmentSelect = document.getElementById('apartment-select'); for (let i = 0; i < apartmentSelect.options.length; i++) { if (apartmentSelect.options[i].value === apartmentName) { apartmentSelect.selectedIndex = i; break; } } bookingSection.scrollIntoView({ behavior: 'smooth' }); } const contactForm = document.getElementById('contactForm'); contactForm.addEventListener('submit', function (event) { event.preventDefault(); alert('Thank you for your message! We will get back to you soon.'); contactForm.reset(); }); document.getElementById('currentYear').textContent = new Date().getFullYear(); const animationStyle = document.createElement('style'); animationStyle.innerHTML = ` .animation-delay-300 { animation-delay: 0.3s; } .animation-delay-600 { animation-delay: 0.6s; } .animate-fade-in-down { animation: fadeInDown 0.8s ease-out forwards; opacity: 0; } .animate-fade-in-up { animation: fadeInUp 0.8s ease-out forwards; opacity: 0; } @keyframes fadeInDown { from { opacity: 0; transform: translateY(-20px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } `; document.head.appendChild(animationStyle);

Final Output:

rent-apartment-booking-template-with-html-tailwind-css-and-javascript.gif

Conclusion:

In this blog, we showed you how to create a rental apartment booking template using HTML and TailwindCSS. This form is perfect for any real estate or rental property website.

It’s simple to build, easy to update, and mobile-friendly. You can now add this form to your project or expand it with extra features like payment, apartment images, or map integration.

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🥺