Liveweave: Generative AI Web Editor & HTML/CSS/JS Playground
Initializing
Liveweave
Web
expand_more
home
Home
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
frame_source
Python Playground
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Fork
account_circle
Login
settings
Settings
expand_more
Editor font
14
px
A
A
Night mode
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
left_panel_close
AI Assistant
dashboard
All
HTML
CSS
JS
visibility
Preview
bolt
Live Preview
terminal
JS Console
<div class="demo"> <div class="content" id="scrollArea"> <h1>Custom Scrollbar</h1> <p> This is a fully custom scrollbar built with HTML, CSS and JavaScript. The native browser scrollbar is hidden and replaced with a custom interface. </p> <div class="card"> <h2>Browser independent</h2> <p> The scrolling itself is handled by the browser's native scroll engine, while JavaScript controls the appearance of the scrollbar. </p> </div> <div class="card"> <h2>Drag the thumb</h2> <p> Grab the scrollbar thumb on the right and drag it up or down. </p> </div> <div class="card"> <h2>Click the track</h2> <p> Clicking above or below the thumb moves the content toward that location. </p> </div> <div class="card"> <h2>Mouse wheel</h2> <p> Your regular mouse wheel or trackpad scrolling continues to work. </p> </div> <div class="card"> <h2>Responsive</h2> <p> The scrollbar automatically changes size depending on the amount of content available. </p> </div> <div class="card"> <h2>Works with dynamic content</h2> <p> Add or remove content and the scrollbar recalculates automatically. </p> </div> <div class="card"> <h2>Pure web technologies</h2> <p> No frameworks or build tools are required. </p> </div> <div class="card"> <h2>Keep scrolling</h2> <p> This extra content demonstrates how the scrollbar behaves with a longer document. </p> </div> <div class="card"> <h2>Almost there</h2> <p> The thumb gets smaller as the content becomes longer. </p> </div> <div class="card final"> <h2>End</h2> <p> You reached the bottom. </p> </div> </div> <div class="scrollbar" id="scrollbar"> <div class="scroll-track" id="scrollTrack"> </div> <div class="scroll-thumb" id="scrollThumb"> </div> </div> </div>
* { box-sizing: border-box; } html, body { margin: 0; height: 100%; } body { font-family: Arial, sans-serif; background: #0d1117; color: #e8eaed; display: flex; align-items: center; justify-content: center; } /* -------------------------------- DEMO CONTAINER -------------------------------- */ .demo { position: relative; width: min(700px, 90vw); height: 600px; border: 1px solid #30363d; border-radius: 18px; background: #161b22; overflow: hidden; box-shadow: 0 20px 50px rgba(0,0,0,.45); } /* -------------------------------- SCROLL CONTENT -------------------------------- */ .content { position: absolute; inset: 0; overflow-y: scroll; overflow-x: hidden; padding: 40px 70px 60px 40px; scrollbar-width: none; -ms-overflow-style: none; } /* Chrome / Safari / Edge */ .content::-webkit-scrollbar { display: none; } h1 { margin-top: 0; font-size: 34px; letter-spacing: -1px; } p { line-height: 1.7; color: #aeb6c2; } .card { margin-top: 24px; padding: 22px; border-radius: 14px; background: #1e242d; border: 1px solid #303743; } .card h2 { margin-top: 0; font-size: 18px; } .final { margin-bottom: 30px; } /* -------------------------------- CUSTOM SCROLLBAR -------------------------------- */ .scrollbar { position: absolute; top: 14px; right: 10px; bottom: 14px; width: 12px; z-index: 20; } /* -------------------------------- TRACK -------------------------------- */ .scroll-track { position: absolute; left: 3px; top: 0; bottom: 0; width: 6px; border-radius: 6px; background: rgba(255,255,255,.06); cursor: pointer; } /* -------------------------------- THUMB -------------------------------- */ .scroll-thumb { position: absolute; left: 1px; width: 10px; min-height: 55px; border-radius: 10px; background: linear-gradient( 180deg, #7f8996, #5d6672 ); cursor: grab; transition: background .15s, width .15s, left .15s; box-shadow: 0 2px 8px rgba(0,0,0,.45); } .scroll-thumb:hover { left: 0; width: 12px; background: linear-gradient( 180deg, #aab3bf, #7b8591 ); } .scroll-thumb.dragging { cursor: grabbing; left: 0; width: 12px; background: #c5ccd5; } /* -------------------------------- MOBILE -------------------------------- */ @media (max-width: 600px) { .demo { width: 94vw; height: 80vh; } .content { padding: 30px 45px 40px 25px; } }
var content = document.getElementById("scrollArea"); var thumb = document.getElementById("scrollThumb"); var track = document.getElementById("scrollTrack"); var dragging = false; var startY = 0; var startScrollTop = 0; /* -------------------------------- UPDATE SCROLLBAR -------------------------------- */ function updateScrollbar() { var scrollHeight = content.scrollHeight; var clientHeight = content.clientHeight; var trackHeight = track.clientHeight; /* How much content is scrollable */ var maxScroll = scrollHeight - clientHeight; /* Nothing to scroll */ if (maxScroll <= 0) { thumb.style.display = "none"; return; } thumb.style.display = "block"; /* Calculate thumb height */ var thumbHeight = Math.max( 55, trackHeight * (clientHeight / scrollHeight) ); thumb.style.height = thumbHeight + "px"; /* Calculate thumb position */ var maxThumbTop = trackHeight - thumbHeight; var thumbTop = (content.scrollTop / maxScroll) * maxThumbTop; thumb.style.top = thumbTop + "px"; } /* -------------------------------- CONTENT SCROLL -------------------------------- */ content.addEventListener( "scroll", updateScrollbar ); /* -------------------------------- WINDOW RESIZE -------------------------------- */ window.addEventListener( "resize", updateScrollbar ); /* -------------------------------- DRAG START -------------------------------- */ thumb.addEventListener( "pointerdown", function(event) { dragging = true; startY = event.clientY; startScrollTop = content.scrollTop; thumb.classList.add( "dragging" ); thumb.setPointerCapture( event.pointerId ); event.preventDefault(); } ); /* -------------------------------- DRAGGING -------------------------------- */ thumb.addEventListener( "pointermove", function(event) { if (!dragging) return; var delta = event.clientY - startY; var trackHeight = track.clientHeight; var thumbHeight = thumb.offsetHeight; var maxThumbTop = trackHeight - thumbHeight; if (maxThumbTop <= 0) return; var scrollRange = content.scrollHeight - content.clientHeight; var scrollAmount = delta / maxThumbTop * scrollRange; content.scrollTop = startScrollTop + scrollAmount; } ); /* -------------------------------- DRAG END -------------------------------- */ thumb.addEventListener( "pointerup", stopDragging ); thumb.addEventListener( "pointercancel", stopDragging ); function stopDragging() { dragging = false; thumb.classList.remove( "dragging" ); } /* -------------------------------- TRACK CLICK -------------------------------- */ track.addEventListener( "pointerdown", function(event) { /* Ignore clicks directly on thumb. */ if ( event.target === thumb ) { return; } var rect = track.getBoundingClientRect(); var clickY = event.clientY - rect.top; var thumbHeight = thumb.offsetHeight; var desiredTop = clickY - thumbHeight / 2; var maxThumbTop = track.clientHeight - thumbHeight; desiredTop = Math.max( 0, Math.min( desiredTop, maxThumbTop ) ); var ratio = desiredTop / maxThumbTop; content.scrollTop = ratio * ( content.scrollHeight - content.clientHeight ); } ); /* -------------------------------- INITIALIZE -------------------------------- */ updateScrollbar();
terminal
JavaScript Console
Preview
Clear
close
›
Run