Linked Info-Cards using Vanilla JavaScript

Linked Info-Cards using Vanilla JavaScript
Project: Interactive Photo Cards
Author: Jacob Foster
Edit Online: View on CodePen
License: MIT

This JavaScript code snippet helps you to create an info card. It starts by selecting all the elements with a class of “panel” using the querySelectorAll method and stores them in the panels variable. The next part of the code uses a for loop to loop through the first three elements of the panels array. Inside the loop, there are four variables declared: base which has a value of 150, duration which has a value of 1000, delay which is calculated by adding the base and duration multiplied by the current loop index, and panel which is the current panel being looped through. Two setTimeout functions are then used to add and remove the class ‘hover’ from the panel element, with the second function removing the class after a delay of duration * 0.8.

Finally, there is an if statement which checks if the current URL contains the string “fullcpgrid”. If it does, it changes the font size of the body element to 11 pixels.

How to Create Linked Info-Cards using Vanilla JavaScript

Create the HTML structure for the info card as follows:

<div class="panels">
  <div class="panel">
    <div class="background" style="background-image: url(https://alca.sfo2.cdn.digitaloceanspaces.com/uploads/codepen/2019/04/20/8829de75-5e07-4268-8049-f55afb72e301.png)"></div>
    <div class="text">
      <div class="location">Tokyo, Japan</div>
      <div class="title">Tokyo Infinity</div>
      <div class="author">Pawel Nolbert</div><a class="link" href="https://unsplash.com/photos/4u2U8EO9OzY" target="_blank" rel="noreferrer">View on Unsplash</a>
    </div>
  </div>
  <div class="panel">
    <div class="background" style="background-image: url(https://alca.sfo2.cdn.digitaloceanspaces.com/uploads/codepen/2019/04/20/510fe87e-a7ed-41c1-b705-9b6586443528.png)"></div>
    <div class="text">
      <div class="location">New York City, New York</div>
      <div class="title">Neon Square</div>
      <div class="author">Andre Benz</div><a class="link" href="https://unsplash.com/photos/LEikIOMSxfs" target="_blank" rel="noreferrer">View on Unsplash</a>
    </div>
  </div>
  <div class="panel">
    <div class="background" style="background-image: url(https://alca.sfo2.cdn.digitaloceanspaces.com/uploads/codepen/2019/04/20/24f263dc-9191-4c36-931a-9baa1b21a5cd.png)"></div>
    <div class="text">
      <div class="location">Hong Kong</div>
      <div class="title">Hong Kong Night City</div>
      <div class="author">Irina Iriser</div><a class="link" href="https://unsplash.com/photos/KQ75n3P8EJA" target="_blank" rel="noreferrer">View on Unsplash</a>
    </div>
  </div>
</div>

Now, style the info card using the following CSS styles:

@import url("https://fonts.googleapis.com/css?family=Roboto:100,400,700");
body {
  font-family: "Roboto", sans-serif;
  background: #0f0f0f;
  color: white;
  margin: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

.panels {
  display: flex;
  flex-wrap: nowrap;
  padding: 1.5em;
  position: absolute;
}
.panels .panel {
  flex-shrink: 0;
  width: 20em;
  height: 33.75em;
  outline: 0.25em solid rgba(26, 97, 203, 0);
  transition: 500ms;
  position: relative;
}
.panels .panel:not(:last-child) {
  margin-right: 1.5em;
}
.panels .panel .background:after,
.panels .panel .text > * {
  transition: transform 200ms, opacity 200ms;
}
.panels .panel .background {
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  transition: 100ms;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.panels .panel .background:before, .panels .panel .background:after {
  content: "";
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
.panels .panel .background:before {
  opacity: 0;
}
.panels .panel .background:after {
  opacity: 0.4;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0) 20%, rgba(23, 86, 181, 0.6) 70%, #04152f 100%);
}
.panels .panel .text {
  cursor: default;
  position: absolute;
  left: 1em;
  right: 1em;
  bottom: -2.5em;
}
.panels .panel .text .location {
  font-weight: 100;
  font-size: 1em;
  margin-bottom: 1em;
}
.panels .panel .text .title {
  font-weight: 700;
  font-size: 2em;
  margin-bottom: 0.5em;
}
.panels .panel .text .author {
  font-weight: 400;
  font-size: 1.25em;
  margin-bottom: 1em;
}
.panels .panel .text .link {
  display: inline-block;
  padding: 0.375em 0.5em;
  background: #1a61cb;
  text-align: center;
  opacity: 0;
}
.panels .panel.hover, .panels .panel:hover {
  outline: 0.875em solid #1a61cb;
  transition: 300ms;
}
.panels .panel.hover .background, .panels .panel:hover .background {
  transition: 125ms;
  top: -0.5em;
  left: -0.5em;
  right: -0.5em;
  bottom: -0.5em;
}
.panels .panel.hover .background:after, .panels .panel:hover .background:after {
  opacity: 1;
}
.panels .panel.hover .text > *, .panels .panel:hover .text > * {
  transform: translate3d(0, -3.5rem, 0);
}
.panels .panel.hover .text .location, .panels .panel:hover .text .location {
  transition-delay: 0ms;
}
.panels .panel.hover .text .title, .panels .panel:hover .text .title {
  transition-delay: 60ms;
}
.panels .panel.hover .text .author, .panels .panel:hover .text .author {
  transition-delay: 110ms;
}
.panels .panel.hover .text .link, .panels .panel:hover .text .link {
  opacity: 1;
  transition-delay: 150ms;
}

Finally, add the following JavaScript function for its functionality:

let panels = document.querySelectorAll('.panel');

for (let i = 0; i < 3; i++) {
  let base = 150;
  let duration = 1000;
  let delay = base + duration * i;
  let panel = panels[i];
  setTimeout(() => panel.classList.add('hover'), delay);
  setTimeout(() => panel.classList.remove('hover'), delay + duration * 0.8);
}

if (location.href.includes('fullcpgrid')) {
  document.body.style.fontSize = '11px';
}

That’s all! hopefully, you have successfully created Linked info-cards using vanilla JavaScript. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *