Skip to content
← Carousel
Edit Carousel
Name
Also known as (comma separated)
Brief definition
Rotating sequence of content panels.
Notes
Tier
Core
Useful
Reference
Deleted
Controls schema (JSON array)
[ { "id": "transition", "type": "select", "label": "Transition", "default": "slide", "options": [ "slide", "fade" ] }, { "id": "accent", "type": "color", "label": "Accent colour", "default": "#E8A020", "presets": [ "#A8E6C1", "#F5C2E0", "#BFD9F2", "#D9C8F0", "#E8A020", "#241430" ] }, { "id": "showArrows", "type": "toggle", "label": "Show arrows", "default": true }, { "id": "radius", "type": "number", "label": "Corner radius", "default": 12, "min": 0, "max": 24, "step": 1 } ]
Templates (JSON object keyed by format)
{ "html": "<div class=\"carousel carousel--{{transition}}\" style=\"--accent:{{accent}};\">\n <input class=\"carousel__radio\" type=\"radio\" name=\"carousel-slide\" id=\"carousel-s1\" checked />\n <input class=\"carousel__radio\" type=\"radio\" name=\"carousel-slide\" id=\"carousel-s2\" />\n <input class=\"carousel__radio\" type=\"radio\" name=\"carousel-slide\" id=\"carousel-s3\" />\n\n <div class=\"carousel__viewport\" style=\"border-radius:{{radius}}px;\">\n <div class=\"carousel__track\">\n <figure class=\"carousel__slide\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\"><rect width=\"400\" height=\"240\" fill=\"#A8E6C1\"/><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\"/></svg>\n </figure>\n <figure class=\"carousel__slide\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\"><rect width=\"400\" height=\"240\" fill=\"#BFD9F2\"/><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\"/></svg>\n </figure>\n <figure class=\"carousel__slide\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\"><rect width=\"400\" height=\"240\" fill=\"#F5C2E0\"/><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\"/></svg>\n </figure>\n </div>\n\n {{#if showArrows}}\n <div class=\"carousel__arrows\">\n <label class=\"carousel__arrow carousel__arrow--prev carousel__arrow--for-1\" for=\"carousel-s3\" aria-label=\"Previous slide\">‹</label>\n <label class=\"carousel__arrow carousel__arrow--next carousel__arrow--for-1\" for=\"carousel-s2\" aria-label=\"Next slide\">›</label>\n <label class=\"carousel__arrow carousel__arrow--prev carousel__arrow--for-2\" for=\"carousel-s1\" aria-label=\"Previous slide\">‹</label>\n <label class=\"carousel__arrow carousel__arrow--next carousel__arrow--for-2\" for=\"carousel-s3\" aria-label=\"Next slide\">›</label>\n <label class=\"carousel__arrow carousel__arrow--prev carousel__arrow--for-3\" for=\"carousel-s2\" aria-label=\"Previous slide\">‹</label>\n <label class=\"carousel__arrow carousel__arrow--next carousel__arrow--for-3\" for=\"carousel-s1\" aria-label=\"Next slide\">›</label>\n </div>\n {{/if}}\n </div>\n\n <div class=\"carousel__dots\">\n <label class=\"carousel__dot\" for=\"carousel-s1\" aria-label=\"Go to slide 1\"></label>\n <label class=\"carousel__dot\" for=\"carousel-s2\" aria-label=\"Go to slide 2\"></label>\n <label class=\"carousel__dot\" for=\"carousel-s3\" aria-label=\"Go to slide 3\"></label>\n </div>\n</div>\n<style>\n.carousel { max-width: 360px; font: 13px/1.4 system-ui, sans-serif; color: #241430; }\n.carousel__radio { position: absolute; opacity: 0; width: 1px; height: 1px; overflow: hidden; }\n.carousel__viewport { position: relative; overflow: hidden; border: 1px solid #24143022; background: #FAF7F2; }\n.carousel__track { display: flex; width: 300%; }\n@media (prefers-reduced-motion: no-preference) {\n.carousel__track { transition: transform .2s ease; }\n}\n.carousel__slide { flex: 0 0 33.333%; margin: 0; aspect-ratio: 5 / 3; }\n.carousel__slide svg { display: block; width: 100%; height: 100%; }\n#carousel-s1:checked ~ .carousel__viewport .carousel__track { transform: translateX(0%); }\n#carousel-s2:checked ~ .carousel__viewport .carousel__track { transform: translateX(-33.333%); }\n#carousel-s3:checked ~ .carousel__viewport .carousel__track { transform: translateX(-66.666%); }\n.carousel--fade .carousel__track { width: 100%; transform: none !important; position: relative; }\n.carousel--fade .carousel__slide { position: absolute; inset: 0; flex-basis: 100%; opacity: 0; }\n@media (prefers-reduced-motion: no-preference) {\n.carousel--fade .carousel__slide { transition: opacity .2s ease; }\n}\n.carousel--fade #carousel-s1:checked ~ .carousel__viewport .carousel__slide:nth-child(1) { opacity: 1; }\n.carousel--fade #carousel-s2:checked ~ .carousel__viewport .carousel__slide:nth-child(2) { opacity: 1; }\n.carousel--fade #carousel-s3:checked ~ .carousel__viewport .carousel__slide:nth-child(3) { opacity: 1; }\n.carousel__arrows { position: absolute; inset: 0; display: flex; align-items: center; justify-content: space-between; padding: 0 8px; pointer-events: none; }\n.carousel__arrow { pointer-events: auto; display: none; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; background: #FAF7F2cc; color: #241430; cursor: pointer; font-size: 16px; line-height: 1; text-decoration: none; }\n.carousel__arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n#carousel-s1:checked ~ .carousel__viewport .carousel__arrow--for-1 { display: flex; }\n#carousel-s2:checked ~ .carousel__viewport .carousel__arrow--for-2 { display: flex; }\n#carousel-s3:checked ~ .carousel__viewport .carousel__arrow--for-3 { display: flex; }\n.carousel__dots { display: flex; gap: 6px; justify-content: center; margin-top: 10px; }\n.carousel__dot { display: block; width: 8px; height: 8px; border-radius: 50%; background: #24143033; cursor: pointer; }\n.carousel__dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n#carousel-s1:checked ~ .carousel__dots label:nth-of-type(1) { background: var(--accent); }\n#carousel-s2:checked ~ .carousel__dots label:nth-of-type(2) { background: var(--accent); }\n#carousel-s3:checked ~ .carousel__dots label:nth-of-type(3) { background: var(--accent); }\n</style>", "tailwind": "<div class=\"carousel-tw max-w-[360px] font-sans text-[13px] text-[#241430]\" data-transition=\"{{transition}}\" style=\"--accent:{{accent}};\">\n <input class=\"carousel-tw__radio\" type=\"radio\" name=\"carousel-tw-slide\" id=\"carousel-tw-s1\" checked />\n <input class=\"carousel-tw__radio\" type=\"radio\" name=\"carousel-tw-slide\" id=\"carousel-tw-s2\" />\n <input class=\"carousel-tw__radio\" type=\"radio\" name=\"carousel-tw-slide\" id=\"carousel-tw-s3\" />\n\n <div class=\"carousel-tw__viewport relative overflow-hidden border border-[#24143022] bg-[#FAF7F2]\" style=\"border-radius:{{radius}}px;\">\n <div class=\"carousel-tw__track flex w-[300%] motion-safe:transition-transform motion-safe:duration-300\">\n <figure class=\"carousel-tw__slide m-0\" style=\"flex:0 0 33.333%;aspect-ratio:5/3;\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\" class=\"block w-full h-full\"><rect width=\"400\" height=\"240\" fill=\"#A8E6C1\"/><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\"/></svg>\n </figure>\n <figure class=\"carousel-tw__slide m-0\" style=\"flex:0 0 33.333%;aspect-ratio:5/3;\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\" class=\"block w-full h-full\"><rect width=\"400\" height=\"240\" fill=\"#BFD9F2\"/><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\"/></svg>\n </figure>\n <figure class=\"carousel-tw__slide m-0\" style=\"flex:0 0 33.333%;aspect-ratio:5/3;\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\" class=\"block w-full h-full\"><rect width=\"400\" height=\"240\" fill=\"#F5C2E0\"/><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\"/></svg>\n </figure>\n </div>\n\n {{#if showArrows}}\n <div class=\"carousel-tw__arrows absolute inset-0 flex items-center justify-between px-2\" style=\"pointer-events:none;\">\n <label class=\"carousel-tw__arrow carousel-tw__arrow--for-1 w-7 h-7 rounded-full items-center justify-center bg-[#FAF7F2]/80 text-[#241430] cursor-pointer\" style=\"pointer-events:auto;\" for=\"carousel-tw-s3\" aria-label=\"Previous slide\">‹</label>\n <label class=\"carousel-tw__arrow carousel-tw__arrow--for-1 w-7 h-7 rounded-full items-center justify-center bg-[#FAF7F2]/80 text-[#241430] cursor-pointer\" style=\"pointer-events:auto;\" for=\"carousel-tw-s2\" aria-label=\"Next slide\">›</label>\n <label class=\"carousel-tw__arrow carousel-tw__arrow--for-2 w-7 h-7 rounded-full items-center justify-center bg-[#FAF7F2]/80 text-[#241430] cursor-pointer\" style=\"pointer-events:auto;\" for=\"carousel-tw-s1\" aria-label=\"Previous slide\">‹</label>\n <label class=\"carousel-tw__arrow carousel-tw__arrow--for-2 w-7 h-7 rounded-full items-center justify-center bg-[#FAF7F2]/80 text-[#241430] cursor-pointer\" style=\"pointer-events:auto;\" for=\"carousel-tw-s3\" aria-label=\"Next slide\">›</label>\n <label class=\"carousel-tw__arrow carousel-tw__arrow--for-3 w-7 h-7 rounded-full items-center justify-center bg-[#FAF7F2]/80 text-[#241430] cursor-pointer\" style=\"pointer-events:auto;\" for=\"carousel-tw-s2\" aria-label=\"Previous slide\">‹</label>\n <label class=\"carousel-tw__arrow carousel-tw__arrow--for-3 w-7 h-7 rounded-full items-center justify-center bg-[#FAF7F2]/80 text-[#241430] cursor-pointer\" style=\"pointer-events:auto;\" for=\"carousel-tw-s1\" aria-label=\"Next slide\">›</label>\n </div>\n {{/if}}\n </div>\n\n <div class=\"carousel-tw__dots flex gap-1.5 justify-center mt-2.5\">\n <label class=\"carousel-tw__dot block w-2 h-2 rounded-full bg-[#24143033] cursor-pointer\" for=\"carousel-tw-s1\" aria-label=\"Go to slide 1\"></label>\n <label class=\"carousel-tw__dot block w-2 h-2 rounded-full bg-[#24143033] cursor-pointer\" for=\"carousel-tw-s2\" aria-label=\"Go to slide 2\"></label>\n <label class=\"carousel-tw__dot block w-2 h-2 rounded-full bg-[#24143033] cursor-pointer\" for=\"carousel-tw-s3\" aria-label=\"Go to slide 3\"></label>\n </div>\n</div>\n<style>\n.carousel-tw__radio { position: absolute; opacity: 0; width: 1px; height: 1px; overflow: hidden; }\n#carousel-tw-s1:checked ~ .carousel-tw__viewport .carousel-tw__track { transform: translateX(0%); }\n#carousel-tw-s2:checked ~ .carousel-tw__viewport .carousel-tw__track { transform: translateX(-33.333%); }\n#carousel-tw-s3:checked ~ .carousel-tw__viewport .carousel-tw__track { transform: translateX(-66.666%); }\n[data-transition=\"fade\"] .carousel-tw__track { width: 100%; transform: none !important; position: relative; }\n[data-transition=\"fade\"] .carousel-tw__slide { position: absolute; inset: 0; opacity: 0; }\n@media (prefers-reduced-motion: no-preference) {\n[data-transition=\"fade\"] .carousel-tw__slide { transition: opacity .2s ease; }\n}\n[data-transition=\"fade\"] #carousel-tw-s1:checked ~ .carousel-tw__viewport .carousel-tw__slide:nth-child(1) { opacity: 1; }\n[data-transition=\"fade\"] #carousel-tw-s2:checked ~ .carousel-tw__viewport .carousel-tw__slide:nth-child(2) { opacity: 1; }\n[data-transition=\"fade\"] #carousel-tw-s3:checked ~ .carousel-tw__viewport .carousel-tw__slide:nth-child(3) { opacity: 1; }\n.carousel-tw__arrow { display: none; }\n.carousel-tw__arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n#carousel-tw-s1:checked ~ .carousel-tw__viewport .carousel-tw__arrow--for-1 { display: flex; }\n#carousel-tw-s2:checked ~ .carousel-tw__viewport .carousel-tw__arrow--for-2 { display: flex; }\n#carousel-tw-s3:checked ~ .carousel-tw__viewport .carousel-tw__arrow--for-3 { display: flex; }\n.carousel-tw__dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n#carousel-tw-s1:checked ~ .carousel-tw__dots label:nth-of-type(1) { background: var(--accent); }\n#carousel-tw-s2:checked ~ .carousel-tw__dots label:nth-of-type(2) { background: var(--accent); }\n#carousel-tw-s3:checked ~ .carousel-tw__dots label:nth-of-type(3) { background: var(--accent); }\n</style>", "react": "export function Carousel({\n transition = \"{{transition}}\",\n accent = \"{{accent}}\",\n showArrows = {{showArrows}},\n radius = {{radius}},\n}) {\n const fills = [\"#A8E6C1\", \"#BFD9F2\", \"#F5C2E0\"];\n return (\n <div className={`carousel-rc carousel-rc--${transition}`} style={{ maxWidth: 360, font: \"13px/1.4 system-ui, sans-serif\", color: \"#241430\", \"--accent\": accent }}>\n <input className=\"carousel-rc__radio\" type=\"radio\" name=\"carousel-rc-slide\" id=\"carousel-rc-s1\" defaultChecked />\n <input className=\"carousel-rc__radio\" type=\"radio\" name=\"carousel-rc-slide\" id=\"carousel-rc-s2\" />\n <input className=\"carousel-rc__radio\" type=\"radio\" name=\"carousel-rc-slide\" id=\"carousel-rc-s3\" />\n\n <div className=\"carousel-rc__viewport\" style={{ position: \"relative\", overflow: \"hidden\", border: \"1px solid #24143022\", background: \"#FAF7F2\", borderRadius: radius }}>\n <div className=\"carousel-rc__track\" style={{ display: \"flex\", width: \"300%\" }}>\n {fills.map((fill, i) => (\n <figure key={i} className=\"carousel-rc__slide\" style={{ flex: \"0 0 33.333%\", margin: 0, aspectRatio: \"5 / 3\" }} aria-hidden=\"true\">\n <svg viewBox=\"0 0 400 240\" width=\"100%\" height=\"100%\" style={{ display: \"block\" }}><rect width=\"400\" height=\"240\" fill={fill} /><circle cx=\"200\" cy=\"120\" r=\"60\" fill=\"#FAF7F2\" /></svg>\n </figure>\n ))}\n </div>\n {showArrows && (\n <div className=\"carousel-rc__arrows\" style={{ position: \"absolute\", inset: 0, display: \"flex\", alignItems: \"center\", justifyContent: \"space-between\", padding: \"0 8px\", pointerEvents: \"none\" }}>\n <label className=\"carousel-rc__arrow carousel-rc__arrow--for-1\" htmlFor=\"carousel-rc-s3\" aria-label=\"Previous slide\">‹</label>\n <label className=\"carousel-rc__arrow carousel-rc__arrow--for-1\" htmlFor=\"carousel-rc-s2\" aria-label=\"Next slide\">›</label>\n <label className=\"carousel-rc__arrow carousel-rc__arrow--for-2\" htmlFor=\"carousel-rc-s1\" aria-label=\"Previous slide\">‹</label>\n <label className=\"carousel-rc__arrow carousel-rc__arrow--for-2\" htmlFor=\"carousel-rc-s3\" aria-label=\"Next slide\">›</label>\n <label className=\"carousel-rc__arrow carousel-rc__arrow--for-3\" htmlFor=\"carousel-rc-s2\" aria-label=\"Previous slide\">‹</label>\n <label className=\"carousel-rc__arrow carousel-rc__arrow--for-3\" htmlFor=\"carousel-rc-s1\" aria-label=\"Next slide\">›</label>\n </div>\n )}\n </div>\n\n <div className=\"carousel-rc__dots\" style={{ display: \"flex\", gap: 6, justifyContent: \"center\", marginTop: 10 }}>\n <label className=\"carousel-rc__dot\" htmlFor=\"carousel-rc-s1\" aria-label=\"Go to slide 1\" />\n <label className=\"carousel-rc__dot\" htmlFor=\"carousel-rc-s2\" aria-label=\"Go to slide 2\" />\n <label className=\"carousel-rc__dot\" htmlFor=\"carousel-rc-s3\" aria-label=\"Go to slide 3\" />\n </div>\n\n <style>{`\n .carousel-rc__radio { position: absolute; opacity: 0; width: 1px; height: 1px; overflow: hidden; }\n @media (prefers-reduced-motion: no-preference) {\n.carousel-rc__track { transition: transform .2s ease; }\n}\n #carousel-rc-s1:checked ~ .carousel-rc__viewport .carousel-rc__track { transform: translateX(0%); }\n #carousel-rc-s2:checked ~ .carousel-rc__viewport .carousel-rc__track { transform: translateX(-33.333%); }\n #carousel-rc-s3:checked ~ .carousel-rc__viewport .carousel-rc__track { transform: translateX(-66.666%); }\n .carousel-rc--fade .carousel-rc__track { width: 100%; transform: none !important; position: relative; }\n .carousel-rc--fade .carousel-rc__slide { position: absolute; inset: 0; opacity: 0; }\n@media (prefers-reduced-motion: no-preference) {\n.carousel-rc--fade .carousel-rc__slide { transition: opacity .2s ease; }\n}\n .carousel-rc--fade #carousel-rc-s1:checked ~ .carousel-rc__viewport .carousel-rc__slide:nth-child(1) { opacity: 1; }\n .carousel-rc--fade #carousel-rc-s2:checked ~ .carousel-rc__viewport .carousel-rc__slide:nth-child(2) { opacity: 1; }\n .carousel-rc--fade #carousel-rc-s3:checked ~ .carousel-rc__viewport .carousel-rc__slide:nth-child(3) { opacity: 1; }\n .carousel-rc__arrow { display: none; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; background: #FAF7F2cc; color: #241430; cursor: pointer; font-size: 16px; line-height: 1; text-decoration: none; pointer-events: auto; }\n .carousel-rc__arrow:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n #carousel-rc-s1:checked ~ .carousel-rc__viewport .carousel-rc__arrow--for-1 { display: flex; }\n #carousel-rc-s2:checked ~ .carousel-rc__viewport .carousel-rc__arrow--for-2 { display: flex; }\n #carousel-rc-s3:checked ~ .carousel-rc__viewport .carousel-rc__arrow--for-3 { display: flex; }\n .carousel-rc__dot { display: block; width: 8px; height: 8px; border-radius: 50%; background: #24143033; cursor: pointer; }\n .carousel-rc__dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }\n #carousel-rc-s1:checked ~ .carousel-rc__dots label:nth-of-type(1) { background: var(--accent); }\n #carousel-rc-s2:checked ~ .carousel-rc__dots label:nth-of-type(2) { background: var(--accent); }\n #carousel-rc-s3:checked ~ .carousel-rc__dots label:nth-of-type(3) { background: var(--accent); }\n `}</style>\n </div>\n );\n}" }
Save
History