Introduction:
Social media carousels are a fantastic way to engage your website visitors with visually appealing content. In this tutorial, we’ll show you how to create a stunning social media carousel from scratch using HTML, CSS, and JavaScript.
Setting Up Your Project
Before diving into the code, let’s ensure you have a project environment ready. Make sure you have a text editor and a web browser for testing.
How to Set Up Your Project
- Open your preferred text editor (e.g., Visual Studio Code).
- Create a new folder for your project.
- Inside the folder, create three files: index.html, styles.css, and script.js.
Building the HTML Structure
Now, let’s start building the foundation of our social media carousel with HTML.
Source Code:
Step 1 (HTML Code):
To get started, we will first need to create a basic HTML file. In this file, we will include the main structure for our image carousel.
After creating the files just paste the following codes into your file. Make sure to save your HTML document with a .html extension, so that it can be properly viewed in a web browser.
Let’s break down the code step by step:
1. <!DOCTYPE html>: This line defines the document type and version of HTML being used, which is HTML5 in this case.
2. <html lang=”en”>: This tag indicates the beginning of the HTML document and specifies that the document is in English (“en”).
3. <head>: This section contains metadata about the web page, including information like character encoding, viewport settings, and the page title.
- <meta charset=”UTF-8″ />: Specifies that the character encoding for the document is UTF-8, which supports a wide range of characters.
- <meta name=”viewport” content=”width=device-width, initial-scale=1.0″ />: Defines the viewport settings for responsive design. It ensures that the page content adjusts to the width of the device’s screen and starts at an initial zoom level of 1.0.
- <title>Social Media Carousel – Scroll-Driven Animations API</title>: Sets the title of the web page, which appears in the browser’s title bar or tab.
- <link href=”https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css” rel=”stylesheet”/>: Imports an external CSS stylesheet for Remixicon fonts. This is used for icons on the page.
- <link rel=”stylesheet” href=”styles.css” />: Links to an external CSS file called “styles.css” for additional styling of the page.
4. <body>: This is the main content area of the web page.
5. <section>: A section element typically represents a thematic grouping of content. In this case, it contains the entire content of the page.
6. <header>: This section represents the header of the content, typically containing introductory information.
- <img src=”…” alt=”profile image”>: Displays an image with the source URL provided. This is a profile image.
- <div>: A container for other elements.
- <p>Buster</p>: Displays the name “Buster.”
- <i class=”ri-verified-badge-fill”></i>: Displays an icon that represents a verified badge.
7. <div class=”card”>: This div represents a card element that contains the main content of the page.
8. <div id=”carousel” class=”visual”>: This div contains a carousel of images with the id “carousel.” It has the class “visual,” which suggests it might be styled for visual effects.
- Multiple <img> elements: These are image elements representing different pictures of cute dogs. They have unique IDs and share the same “alt” attribute text.
- <div class=”controls”>: This div contains buttons for controlling the carousel.
- <button id=”prev” class=”previous” onclick=”carousel.scrollBy(-100, 0)”>: This button, with the id “prev” and class “previous,” triggers a JavaScript function to scroll the carousel to the left.
- <button id=”next” class=”next” onclick=”carousel.scrollBy(100, 0)”>: This button, with the id “next” and class “next,” triggers a JavaScript function to scroll the carousel to the right.
- <div id=”pagination” class=”pagination”></div>: This div is for pagination controls, but it’s currently empty.
9. <div class=”social”>: This div represents a social media section.
10. <div class=”inter”>: A container for social interaction buttons.
- Multiple <button> elements with icons inside for actions like liking, commenting, and sharing.
- <button> with an icon for bookmarking.
11. <p>3,802 likes</p>: Displays the number of likes.
12. <p>Getting ready to paw-ty! 🎉🐾</p>: Displays a text caption, related to the image content.
13. <script src=” script.js”></script>: Imports an external JavaScript file called “script.js,” suggesting that there is JavaScript code that controls the behavior of the page.
This is the basic structure of our social media carousel using HTML, and now we can move on to styling it using CSS.
Social Media Carousel - Scroll-Driven Animations API
Buster
3,802 likes
Getting ready to paw-ty! 🎉🐾
Step 2 (CSS Code):
Once the basic HTML structure of the image carousel is in place, the next step is to add styling to the carousel using CSS.
Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our carousel.
Let’s break down the code and explain each part:
1. @import Statements:
- The code starts with @import statements, which are used to import external CSS files or resources.
- The first @import statement imports the ‘open-props’ library from ‘https://unpkg.com/‘ and assigns it to the ‘design.system‘ layer.
- The second @import statement imports the ‘normalize.dark.min.css’ file from ‘https://unpkg.com/open-props/‘ and assigns it to the ‘demo.support‘ layer.
- The third @import statement imports font styles from Google Fonts for the ‘Inter’ font family with various weights.
2. @layer Rule:
- The @layer rule is used to define named layers within the stylesheet.
- In this code, there are two @layer rules: ‘demo.base‘ and ‘demo.scroll-driven-animation‘, which group styles for different parts of the page.
3. :root Selector:
- Within the ‘demo.base‘ layer, the :root selector is used to define global CSS variables (custom properties).
- These variables are used to define font family, font size, and various size-related properties.
4. Selectors and Styles:
- The code includes various CSS selectors and style rules to define the appearance of different page elements.
- Notable selectors include body, section, .card, .visual, .controls, .pagination, .social, and more.
- The styles define properties such as display behavior, grid layouts, font sizes, background colors, padding, alignment, borders, shadows, and transitions for these elements.
5. Media Queries:
- The code includes media queries, such as @media (width < 468px), which apply styles based on the width of the viewport.
- These media queries adjust padding and other styles for smaller screens.
6. Animation:
- The code defines keyframe animations using @keyframes rules.
- Notable animations include ‘scale‘, ‘prev‘, and ‘next‘. These animations control scaling and visibility of elements.
- Animation properties like timing functions and keyframe percentages are defined within these rules.
7. Scroll Behavior:
- The ‘demo.scroll-driven-animation‘ layer includes styles related to scroll behavior.
- It defines scroll-snap behavior, overscroll behavior, and smooth scrolling for the ‘.visual’ element.
- The ‘.pagination > button‘ selector is associated with a scale animation.
- ‘.next‘ and ‘.previous‘ classes are also associated with animations and a timeline called ‘–carousel’.
This will give our social media carousel an upgraded presentation. Create a CSS file with the name of styles.css and paste the given codes into your CSS file. Remember that you must create a file with the .css extension.
@import 'https://unpkg.com/open-props' layer(design.system);
@import 'https://unpkg.com/open-props/normalize.dark.min.css'
layer(demo.support);
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@200..900&display=swap');
@layer demo.base {
:root {
font-family: 'Inter', sans-serif;
--sm-font-size: 0.875rem;
--size: min(470px, 100dvw);
}
body {
display: grid;
place-content: center;
background-color: black;
padding-block: var(--size-fluid-3);
}
section {
display: grid;
justify-content: center;
gap: var(--size-2);
& header {
display: flex;
align-items: center;
gap: var(--size-2);
> img {
inline-size: 2.5rem;
aspect-ratio: var(--ratio-square);
border-radius: var(--radius-round);
}
& p {
font-size: var(--sm-font-size);
font-weight: var(--font-weight-6);
}
& i {
color: var(--blue-5);
}
> div {
display: flex;
align-items: center;
gap: var(--size-1);
}
@media (width < 468px) {
padding-inline: var(--size-3);
}
}
.card {
display: flex;
flex-direction: column;
gap: var(--size-3);
position: relative;
& button {
background: transparent;
}
.visual {
display: grid;
grid-auto-flow: column;
grid-auto-columns: var(--size);
inline-size: var(--size);
block-size: var(--size);
overflow-x: auto;
/* Hide scrollbar */
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
&::-webkit-scrollbar {
display: none;
}
& img {
inline-size: var(--size);
border-radius: var(--radius-1);
border: var(--border-size-1) solid var(--stone-11);
}
}
.controls {
position: absolute;
z-index: 1;
inset-inline: var(--size-2);
inset-block-start: 50%;
display: flex;
justify-content: space-between;
}
& button {
inline-size: var(--size-8);
border-radius: var(--radius-round);
aspect-ratio: var(--ratio-square);
font-size: 1.75rem;
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
box-shadow: var(--shadow-1);
color: var(--stone-1);
transition: color 0.2s ease;
&:hover {
color: var(--stone-2);
}
}
}
.pagination {
position: absolute;
z-index: 1;
inset-inline: 0;
inset-block-end: var(--size-5);
display: flex;
justify-content: center;
gap: var(--size-1);
& button {
display: inline-flex;
place-content: center;
inline-size: 0.5ex;
flex-shrink: 0;
aspect-ratio: var(--ratio-square);
border-radius: var(--radius-round);
background-color: hsl(0 0% 100%/ 60%);
}
}
.social {
display: grid;
gap: var(--size-1);
& button {
background-color: unset;
font-size: var(--font-size-3);
padding: 0;
}
.inter {
display: flex;
align-items: center;
justify-content: space-between;
> div {
display: flex;
gap: var(--size-3);
}
}
& p {
font-size: var(--sm-font-size);
font-weight: var(--font-weight-6);
}
@media (width < 468px) {
padding-inline: var(--size-3);
}
}
}
}
@layer demo.scroll-driven-animation {
.visual {
scroll-snap-type: x mandatory;
overscroll-behavior: contain;
scroll-behavior: smooth;
scroll-timeline: --carousel inline;
> * {
scroll-snap-align: center;
}
& img {
view-timeline-axis: inline;
perspective: var(--size);
}
}
.pagination > button {
/* every dot use the scale animation */
animation: scale linear both;
}
.next {
animation: auto next ease;
animation-timeline: --carousel;
}
.previous {
animation: auto prev ease;
animation-timeline: --carousel;
}
}
@keyframes scale {
0%,
100% {
scale: 0.75;
}
50% {
scale: 1;
background-color: white;
}
}
@keyframes prev {
from {
visibility: hidden;
}
}
@keyframes next {
to {
visibility: hidden;
}
}
Step 3 (JavaScript Code):
Finally, we need to create a function in JavaScript. This JavaScript code is used to create pagination markers dynamically for a carousel of images. These markers allow users to click on them to navigate to specific images within the carousel. It utilizes the CSS Scroll-driven Animations API for handling the animation logic.
Here’s a step-by-step explanation of the code:
1. The code begins by selecting all <img> elements within an element with the id of “carousel” and storing them in the images variable.
2. It also selects an element with the id “pagination” and stores it in the pagination variable. This element is where the pagination markers will be appended.
3. The createPaginationMarkers function is defined. This function does the following:
- It iterates over each image in the images NodeList using the forEach method.
- For each image, it generates a unique name for the view timeline associated with that image using its id. This name is stored in the imgViewName variable.
- It sets the style.viewTimelineName property of the image to the imgViewName. This property is used by CSS for animation purposes.
- It creates a <button> element to serve as a pagination marker.
- Sets the type attribute of the button to “button” and the role attribute to “tab” to ensure accessibility.
- Sets the style.animationTimeline property of the button to the imgViewName, connecting the button to the specific image’s animation timeline.
- Adds a click event listener to the button, which, when clicked, scrolls the associated image into view.
- Finally, it appends the button as a child of the pagination element.
4. The code then sets the style.timelineScope property of the <body> element to a string created by mapping each image’s style.viewTimelineName. This likely sets the animation scope for the CSS animations, linking them to the images.
5. The code checks if the browser supports the Scroll-driven Animations API with the condition CSS.supports(‘view-timeline-axis’, ‘inline’). If supported, it calls the createPaginationMarkers function to generate the pagination markers.
6. Finally, it initiates the scrolling to the second image in the carousel using images[1].scrollIntoView(). This ensures that the carousel starts with the second image in view when the page loads.
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 images = document.querySelectorAll('#carousel img');
const pagination = document.querySelector('#pagination');
function createPaginationMarkers() {
images.forEach((img) => {
const imgViewName = `--${img.id}`;
img.style.viewTimelineName = imgViewName;
const marker = document.createElement('button');
marker.type = 'button';
marker.role = 'tab';
marker.style.animationTimeline = imgViewName;
marker.addEventListener('click', () => img.scrollIntoView());
pagination.appendChild(marker);
});
document.body.style.timelineScope = `${Array.from(images).map(
(image) => image.style.viewTimelineName
)}`;
}
// Check browser support for Scroll-driven Animations
if (CSS.supports('view-timeline-axis', 'inline')) {
createPaginationMarkers();
}
// Start scrolling from the second image
images[1].scrollIntoView();
Final Output:
Conclusion:
Congratulations! You’ve successfully created a captivating social media carousel using HTML, CSS, and JavaScript. This engaging feature will undoubtedly enhance user interaction on your website.
Feel free to customize and further enhance your carousel to meet your specific needs. Carousels are a powerful tool in web design, and with the skills you’ve gained, you can create dynamic and visually appealing content sliders for any project. Happy coding!