Social Links
HTML
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <title>Draggable Bottom Modal | CodingAyush</title> <link rel="stylesheet" href="style.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="script.js" defer></script> </head> <body> <button class="show-modal">Open Modal</button> <div class="bottom-sheet"> <div class="sheet-overlay"></div> <div class="content"> <div class="header"> <div class="drag-icon"><span></span></div> </div> <div class="modal-body"> <h2>Draggable Bottom Modal</h2> <p>Create a bottom sheet modal that functions similarly to Facebook modal using HTML CSS and JavaScript. This modal allows user to view its contents, drag it up or down, and close it. It also works on touch-enabled devices. Lorem Ipsum are simply dummy text of there printing and typesetting industry. Lorem new Ipsum has been the industryss standard dummy text ever since the 1500s, when an off unknown printer tooks a galley of type and scrambled it to makes type spemen book It has survived not only five centuries.</p> <p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellat quae facere, quaerat deleniti, voluptates optio ipsam ipsum beatae, maxime quis ea quasi minima numquam. Minima accusamus reiciendis, impedit blanditiis nulla quia? Odio deleniti commodi id nesciunt voluptas cumque odit, vel molestias ratione sit consectetur inventore error ullam magni labore voluptate doloribus sed similique. Delectus non pariatur eligendi eos voluptatum provident eveniet consequuntur. Laboriosam, nesciunt reiciendis libero sunt adipisci numquam voluptas ullam, iure voluptates soluta mollitia quam voluptatem? Nemo, ipsum magnam.</p> </div> </div> </div> </body> </html>
CSS
/* Import Google font - Poppins */ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body { display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #11131e; } .show-modal { outline: none; border: none; cursor: pointer; color: #fff; border-radius: 6px; font-size: 1.2rem; padding: 15px 22px; background: #4A98F7; transition: 0.3s ease; box-shadow: 0 10px 18px rgba(52,87,220,0.18); } .show-modal:hover { background: #2382f6; } .bottom-sheet { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; opacity: 0; pointer-events: none; align-items: center; flex-direction: column; justify-content: flex-end; transition: 0.1s linear; } .bottom-sheet.show { opacity: 1; pointer-events: auto; } .bottom-sheet .sheet-overlay { position: fixed; top: 0; left: 0; z-index: -1; width: 100%; height: 100%; opacity: 0.2; background: #000; } .bottom-sheet .content { width: 100%; position: relative; background: #fff; max-height: 100vh; height: 50vh; max-width: 1150px; padding: 25px 30px; transform: translateY(100%); border-radius: 12px 12px 0 0; box-shadow: 0 10px 20px rgba(0,0,0,0.03); transition: 0.3s ease; } .bottom-sheet.show .content{ transform: translateY(0%); } .bottom-sheet.dragging .content { transition: none; } .bottom-sheet.fullscreen .content { border-radius: 0; overflow-y: hidden; } .bottom-sheet .header { display: flex; justify-content: center; } .header .drag-icon { cursor: grab; user-select: none; padding: 15px; margin-top: -15px; } .header .drag-icon span { height: 4px; width: 40px; display: block; background: #C7D0E1; border-radius: 50px; } .bottom-sheet .modal-body { height: 100%; overflow-y: auto; padding: 15px 0 40px; scrollbar-width: none; } .bottom-sheet .modal-body::-webkit-scrollbar { width: 0; } .bottom-sheet .modal-body h2 { font-size: 1.8rem; } .bottom-sheet .modal-body p { margin-top: 20px; font-size: 1.05rem; }
JS
// Select DOM elements const showModalBtn = document.querySelector(".show-modal"); const bottomSheet = document.querySelector(".bottom-sheet"); const sheetOverlay = bottomSheet.querySelector(".sheet-overlay"); const sheetContent = bottomSheet.querySelector(".content"); const dragIcon = bottomSheet.querySelector(".drag-icon"); // Global variables for tracking drag events let isDragging = false, startY, startHeight; // Show the bottom sheet, hide body vertical scrollbar, and call updateSheetHeight const showBottomSheet = () => { bottomSheet.classList.add("show"); document.body.style.overflowY = "hidden"; updateSheetHeight(50); } const updateSheetHeight = (height) => { sheetContent.style.height = `${height}vh`; //updates the height of the sheet content // Toggles the fullscreen class to bottomSheet if the height is equal to 100 bottomSheet.classList.toggle("fullscreen", height === 100); } // Hide the bottom sheet and show body vertical scrollbar const hideBottomSheet = () => { bottomSheet.classList.remove("show"); document.body.style.overflowY = "auto"; } // Sets initial drag position, sheetContent height and add dragging class to the bottom sheet const dragStart = (e) => { isDragging = true; startY = e.pageY || e.touches?.[0].pageY; startHeight = parseInt(sheetContent.style.height); bottomSheet.classList.add("dragging"); } // Calculates the new height for the sheet content and call the updateSheetHeight function const dragging = (e) => { if(!isDragging) return; const delta = startY - (e.pageY || e.touches?.[0].pageY); const newHeight = startHeight + delta / window.innerHeight * 100; updateSheetHeight(newHeight); } // Determines whether to hide, set to fullscreen, or set to default // height based on the current height of the sheet content const dragStop = () => { isDragging = false; bottomSheet.classList.remove("dragging"); const sheetHeight = parseInt(sheetContent.style.height); sheetHeight < 25 ? hideBottomSheet() : sheetHeight > 75 ? updateSheetHeight(100) : updateSheetHeight(50); } dragIcon.addEventListener("mousedown", dragStart); document.addEventListener("mousemove", dragging); document.addEventListener("mouseup", dragStop); dragIcon.addEventListener("touchstart", dragStart); document.addEventListener("touchmove", dragging); document.addEventListener("touchend", dragStop); sheetOverlay.addEventListener("click", hideBottomSheet); showModalBtn.addEventListener("click", showBottomSheet);