Recently I came across this BBC article that contained these horizontally sliding cards. I thought it looked pretty cool so I tried to recreate it.
--
Step 1
Firstly I added the content for the cards. I made a new pen on codepen with a bunch of divs for each card and put placeholder content in each one (just a bunch of lorem ipsums).
<h1>Title of page</h1>
<div id="container">
<div id="card-01" class="card card-intro">
<h2>Card intro title</h2>
<p class="subtitle">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
<p class="instruction">Scroll or drag for more.</p>
</div>
<div id="card-02" class="card">
<h3>Card content 01</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div id="card-03" class="card">
<h3>Card content 02</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div id="card-04" class="card">
<h3>Card content 3</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<div id="card-05" class="card">
<h3>Card content 04</h3>
<p class="content">Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
</div>
Step 2
The next step was to make them look like cards. I made adjustments to the typeface and font sizes for the headings and body text, gave each card a rounded corner and added a drop shadow.
Looking at the BBC article under Inspect, I can see that they used flexbox for the layout. I used display: flex;
which put all the cards onto the same row. After some googling, I added overflow-x: auto;
which created the horizontal scrolling.
I am using SCSS which I am still a beginner in so I'm not sure how good or bad the following snippet is, but this is what I wrote:
html,
body {
font-family: Arial, sans-serif;
}
p {
line-height: 165%;
}
#container {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
overflow-x: auto;
}
.card {
background: white;
min-width: 300px;
min-height: 450px;
padding: 25px;
border-radius: 10px;
margin: 10px;
filter: drop-shadow(0px 0px 5px #dcdcdc);
h2 {
font-family: "Arial Black", "Arial", sans-serif;
color: white;
line-height: 110%;
margin-top: 0px;
text-transform: uppercase;
font-size: 56px;
font-weight: 700;
}
h3 {
margin-top: 0;
font-family: "Arial Black", "Arial", sans-serif;
font-size: 24px;
font-weight: 600;
text-transform: uppercase;
}
&.card-intro {
background: #174273;
}
&#card-01 {
color: white;
}
.subtitle {
font-weight: 600;
line-height: 130%;
font-size: 20px;
}
}
Step 3
The next step was to add the click-and-drag to the cards. I found a helpful YouTube video that explains how to write the code for this feature so I tried it in my pen. This worked really nicely!
const container = document.querySelector("#container");
let isDown = false;
let startX;
let scrollLeft;
container.addEventListener("mousedown", (e) => {
isDown = true;
container.classList.add("active");
startX = e.pageX - container.offsetLeft;
scrollLeft = container.scrollLeft;
});
container.addEventListener("mouseleave", () => {
isDown = false;
container.classList.remove("active");
});
container.addEventListener("mouseup", () => {
isDown = false;
container.classList.remove("active");
});
container.addEventListener("mousemove", (e) => {
if (!isDown) return;
const x = e.pageX - container.offsetLeft;
const walk = x - startX;
container.scrollLeft = scrollLeft - walk;
});
I noticed that when I was click-and-dragging, some of the text would highlight. The next step is to update the CSS so that this doesn't happen. I also added the grabbing cursor which is referenced in the Javascript.
#container {
-webkit-overflow-scrolling: touch;
//Stops highlighting text
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Standard */
}
.active {
cursor: grabbing;
cursor: -webkit-grabbing;
}
Final step
The last step is to write more suitable content into the cards and test that it works. This is the final result.
I noticed that because I was using codepen with the code editor on the side (reducing the rendered page width), I didn't realise that on full width, the cards were an unusual side. I added an additional part to the .card class in the CSS that only affects desktop >768px width pages so that the cards are a fixed width. I'm not sure if this is how it's supposed to be done but it fixed the issue so I'm going to assume it is for now....
.card {
@media (min-width: 768px) {width: 300px;}
}
One thing that I am quite happy with is that the cards increase in size dynamically with the content so I don't need to add a word limit for it to work without breaking! I am assuming it is because I used the min-height
attribute. Adding additional divs in the HTML for more cards also works fine.
Reflection
These are the things I learnt whilst coding this project:
- It only took me about 1-2 hours to build these cards so it wasn't as daunting as I thought it would be.
- When writing Javascript for dragging stuff, you need 4 states: mouse down, mouse up, mouse leave, and mouse move.
- I am still sometimes careless and don't test on multiple devices as I am going. I suppose that is the nature working on codepen since it doesn't have a device preview.
- I should remember to research and add webkits as I go so problems don't occur for different browsers or OS's.
Overall this was a quick project I created just on the fly whilst reading an article so I am happy with how this came out. I'm not sure if I want to continue working on small projects on codepen or make something a little bit more complex next. I do want to make a portfolio website soon!
Top comments (0)