{ "$schema": "../schemas/code-crispies-module-schema.json", "id": "css-carousels", "title": "Carousels", "description": "Learn to create modern, accessible carousels using pure CSS with scroll snapping, scroll buttons, and scroll markers. This module covers advanced CSS features that enable interactive carousel components without JavaScript, focusing on responsive design and user accessibility.", "difficulty": "intermediate", "lessons": [ { "id": "basic-horizontal-scroll", "title": "Scroll Container", "description": "Before building carousels, we need to understand how to create horizontally scrolling containers. A scroll container is created by setting the overflow-x property to scroll on a container element. This allows content that exceeds the container's width to be scrolled horizontally instead of breaking to new lines or being hidden.", "task": "Create a horizontal scroll container by setting overflow-x: scroll on the .container element. This will allow the wide content inside to scroll horizontally.", "previewHTML": "
Try scrolling in the container above - items should snap into place!
", "previewBaseCSS": "body { font-family: sans-serif; padding: 20px; }\n.container { width: 300px; height: 120px; border: 2px solid #333; padding: 10px; overflow-x: scroll; display: flex; gap: 10px; }\n.item { flex: 0 0 120px; height: 80px; background: lightcoral; text-align: center; line-height: 80px; border-radius: 4px; }", "sandboxCSS": "", "codePrefix": "/* Add scroll snapping to the container */\n.container {\n ", "initialCode": "", "codeSuffix": "\n}\n\n/* Make items snap to center */\n.item {\n \n}", "previewContainer": "preview-area", "solution": "scroll-snap-type: x mandatory;\n}\n\n.item {\n scroll-snap-align: center;", "validations": [ { "type": "contains", "value": "scroll-snap-type:", "message": "Add the scroll-snap-type property to the container" }, { "type": "contains", "value": "x mandatory", "message": "Use x mandatory for horizontal mandatory snapping" }, { "type": "contains", "value": "scroll-snap-align:", "message": "Add scroll-snap-align to the items" }, { "type": "contains", "value": "center", "message": "Use center to align items to the center of the container" } ] }, { "id": "flexbox-carousel-layout", "title": "Full-Width Items", "description": "For carousels where each item takes the full width (like image slideshows), we use flexbox with flex: 0 0 100% on each item. This means: no grow (0), no shrink (0), and take 100% of the container width. Combined with a horizontal gap, this creates distinct pages.", "task": "Create a full-width carousel layout using flexbox. Set display: flex and gap: 20px on the container, then flex: 0 0 100% on the items.", "previewHTML": "Scroll or click markers to see the active state change!
", "previewBaseCSS": "body { font-family: sans-serif; padding: 20px; }\n.carousel { width: 100%; height: 200px; border: 2px solid #333; overflow-x: scroll; scroll-snap-type: x mandatory; display: flex; gap: 20px; scroll-marker-group: after; }\n.slide { flex: 0 0 100%; height: 180px; background: linear-gradient(45deg, #a8edea, #fed6e3); color: #333; display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: bold; scroll-snap-align: center; }\n.slide::scroll-marker { content: \"\"; width: 12px; height: 12px; border-radius: 50%; background: #eee; border: 2px solid #333; }\n.carousel::scroll-button(*) { font-size: 18px; color: #333; background: white; border: 1px solid #333; padding: 6px; }\n.carousel::scroll-button(left) { content: \"◀\"; }\n.carousel::scroll-button(right) { content: \"▶\"; }", "sandboxCSS": "", "codePrefix": "/* Highlight the active/current scroll marker */\n.slide::scroll-marker:target-current {\n ", "initialCode": "", "codeSuffix": "\n}", "previewContainer": "preview-area", "solution": "background: #333;\n border-color: #666;", "validations": [ { "type": "contains", "value": ":target-current", "message": "Use the :target-current pseudo-class to target the active marker" }, { "type": "contains", "value": "background:", "message": "Change the background color to highlight the active marker" }, { "type": "regex", "value": "::scroll-marker:target-current", "message": "Apply :target-current to the ::scroll-marker pseudo-element" } ] }, { "id": "multi-column-carousel", "title": "Multi-Item", "description": "For responsive carousels showing multiple items per page, CSS multi-column layout is ideal. Using columns: 1 creates full-width columns, and items flow naturally into each column. The ::column pseudo-element represents each generated column and can have scroll-snap alignment.", "task": "Create a multi-item carousel using columns: 1 for the layout and scroll-snap-align: center on the ::column pseudo-elements to snap to each column.", "previewHTML": "