Creating Flashlight Hover Effect: HTML, CSS & JavaScript


By Faraz -

Enhance your website's interactivity with a flashlight hover effect. Learn how to implement it using HTML, CSS, and JavaScript in this step-by-step guide.

Creating Flashlight Hover Effect HTML, CSS & JavaScript.jpg

Table of Contents

  1. Project Introduction
  2. HTML Code
  3. CSS Code
  4. JavaScript Code
  5. Preview
  6. Conclusion

The flashlight effect is an interactive web design technique that highlights or focuses on a specific element when a user hovers their mouse over it. It mimics a flashlight beam, drawing attention to the selected area. This engaging effect can be achieved with HTML, CSS, and JavaScript.

Let's start making a flashlight hover effect using HTML, CSS, and JavaScript step by step.

Join My Telegram Channel to Download the Project Source Code: Click Here


Before starting this tutorial, you should have a basic understanding of HTML, CSS, and JavaScript. Additionally, you will need a code editor such as Visual Studio Code or Sublime Text to write and save your code.

Source Code

Step 1 (HTML Code):

To get started, create the HTML structure for your webpage. Ensure you have the elements you want to apply the flashlight effect to.

Let's break down the code step by step:

1. <!DOCTYPE html>: This is the document type declaration, indicating that the document is an HTML5 document.

2. <html lang="en">: This is the opening tag for the HTML document. The lang attribute is set to "en," which specifies that the primary language of the document is English.

3. <head>: The <head> element contains meta information and links to external resources that are necessary for the webpage but not directly visible to the user.

  • <meta charset="UTF-8">: This meta tag specifies the character encoding for the document, which is set to UTF-8, a common character encoding for handling various languages and special characters.
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">: This meta tag is used for responsive design. It configures the viewport to match the device's width and set the initial zoom level to 1.0, ensuring that the webpage adapts to different screen sizes and is not zoomed in or out by default.
  • <title>Flashlight Grid</title>: This sets the title of the webpage, which is typically displayed in the browser's title bar or tab.
  • <link rel="stylesheet" href="">: This is a link to an external stylesheet (CSS) hosted on a Content Delivery Network (CDN). It's used to style the webpage, and it appears to be related to a font named "cryptofont."
  • <link rel="stylesheet" href="styles.css">: This is another link to an external CSS file named "styles.css" for additional styling. It contains custom styles specific to this webpage.

4. <body>: The <body> element contains the visible content of the webpage.

  • Inside the <body>, there is a <div class="cards"> element that contains a series of cards. These cards appear to be used to display information related to various items or topics.
  • Each card consists of a <div class="card"> element, which represents an individual card.
  • Inside each card, there is a <div class="card-content"> element, which is used to structure the content within the card.
  • Within the card content, there is an <i> element with a class attribute such as <i class="cf cf-ace"></i>. These <i> elements are used to display icons or symbols associated with each card. The "cf" class is related to the cryptofont mentioned in the external stylesheet link.
  • Following the icon, there is an <h2> element with a title (e.g., <h2>Ace</h2>). This is a heading element used to display the title or name of each card.
  • Finally, there is a <script> element with a src attribute pointing to a JavaScript file named "script.js." This file is loaded at the end of the document and is used to add interactivity and functionality to the webpage.

Step 2 (CSS Code):

Define the initial appearance of the elements and specify the flashlight effect styles. This includes setting the initial opacity and positioning.

Let's break down the code step by step:

1. body Selector:

  • margin: 0;: This rule removes the default margin around the entire webpage.
  • height: 100vh;: Sets the height of the body to be equal to the viewport height (100% of the browser window's height).
  • display: grid;: Makes the body a CSS grid container.
  • place-items: center;: Centers the content both horizontally and vertically within the grid container.
  • background: #0c1016;: Sets the background color of the webpage to a dark color (#0c1016).
  • color: #ffffff;: Sets the text color to white (#ffffff).
  • font-family: "Euclid Circular A";: Defines the font family for text on the page as "Euclid Circular A."
  • overflow-x: hidden;: Hides the horizontal scrollbar if the content overflows the viewport horizontally.

2. * Selector:

  • box-sizing: border-box;: Makes sure that padding and border are included in the element's total width and height, preventing unexpected layout issues.
  • user-select: none;: Prevents the user from selecting text on the webpage.

3. .cards Selector:

  • display: grid;: Makes the elements with the class "cards" a grid container.
  • grid-template-columns: repeat(4, 150px); and grid-template-rows: repeat(4, 150px);: Specifies the grid layout with four columns and four rows, each with a fixed width and height of 150 pixels.
  • gap: 8px;: Defines the gap (spacing) between grid items as 8 pixels.
  • padding: 32px;: Adds padding to the grid container.

4. .cards:hover .card Selector:

  • This rule applies styles to elements with the class "card" when the parent element with the class "cards" is hovered.
  • It sets a radial gradient background for the hovered "card" elements.

5. .card Selector:

  • position: relative;: Sets the position of the elements with the class "card" as relative, allowing them to be positioned relative to their normal position.
  • display: flex;, justify-content: center;, and align-items: center;: These rules make the "card" elements flex containers, centering their content both horizontally and vertically.
  • background: radial-gradient(...): Sets a radial gradient background for the "card" elements.
  • border-radius: 8px;: Rounds the corners of the "card" elements.
  • transition: 0.15s;: Adds a smooth transition effect over 0.15 seconds for style changes.

6. .cards .card:hover::before Selector:

  • This rule targets pseudo-elements ::before of "card" elements when they are hovered and changes their opacity.

7. .card::before Selector:

  • Defines a pseudo-element ::before for "card" elements. This pseudo-element creates a gradient overlay that becomes visible when the card is hovered.

8. .card-content Selector:

  • Styles elements with the class "card-content" inside "card" elements.
  • Sets up flex properties for layout and applies background color and border radius.
  • Defines transitions and sizes for the content.

9. .card :is(i, h2) and .card:hover :is(i, h2) Selectors:

  • These rules target <i> and <h2> elements within "card" elements, controlling their opacity and adding hover effects.

10. .card i and .card h2 Selectors:

  • These rules style the <i> and <h2> elements inside "card" elements, specifying their font size, margin, and font weight.
body {
  margin: 0;
  height: 100vh;
  display: grid;
  place-items: center;
  background: #0c1016;
  color: #ffffff;
  font-family: "Euclid Circular A";
  overflow-x: hidden;

* {
  box-sizing: border-box;
  user-select: none;

.cards {
  display: grid;
  grid-template-columns: repeat(4, 150px);
  grid-template-rows: repeat(4, 150px);
  gap: 8px;
  padding: 32px;

.cards:hover .card {
  background: radial-gradient(
    800px circle at var(--xPos) var(--yPos),
    rgba(0, 255, 241, 0.4),
    transparent 15%

.card {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  background: radial-gradient(
    400px circle at 0 0,
    rgba(0, 255, 241, 0),
    transparent 0%
  border-radius: 8px;
  transition: 0.15s;

.cards .card:hover::before {
  opacity: 1;

.card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  border-radius: inherit;
  background: radial-gradient(
    500px circle at var(--xPos) var(--yPos),
    rgba(0, 255, 241, 0.1),
    transparent 35%
  opacity: 0;
  transition: all 0.15s ease-in-out;

.card-content {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 16px;
  background: #13161c;
  border-radius: inherit;
  transition: all 0.25s;
  height: calc(100% - 2px);
  width: calc(100% - 2px);

.card :is(i, h2) {
  opacity: 0.45;
  transition: 0.3s;

.card:hover :is(i, h2) {
  opacity: 1;

.card i {
  font-size: 38px;

.card h2 {
  margin: 0;
  font-weight: 400;
  font-size: 19px;

Step 3 (JavaScript Code):

Write JavaScript code to handle the hover event. This code will control the flashlight effect, changing the element's opacity and positioning on hover.

Let's break down what each part of the code does:

1. const cards = document.querySelectorAll(".card");

  • This line selects all the HTML elements with the class "card" on the webpage and stores them in a constant variable named cards. It's assumed that these are individual card elements within your web page.

2. const wrapper = document.querySelector(".cards");

  • This line selects a single HTML element with the class "cards" and stores it in a constant variable named wrapper. This element is presumably the container that holds the cards.

3. wrapper.addEventListener("mousemove", (event) => { ... });

  • This line adds an event listener to the wrapper element. It listens for the "mousemove" event, which occurs when the mouse is moved within the boundaries of the wrapper element. When the "mousemove" event is detected, the code inside the arrow function is executed.

4. cards.forEach((card) => { ... });

  • This line iterates through each card element in the cards array (which we selected earlier). For each card, the code inside the arrow function is executed.

5. const rect = card.getBoundingClientRect();

  • Within the loop, this line calculates the position and dimensions of the current card element relative to the viewport and stores it in the rect constant. This information includes the card's position from the top and left edges of the viewport.

6. const x = event.clientX - rect.left;

  • This line calculates the horizontal (X) position of the mouse pointer within the current card element by subtracting the left position of the card from the X-coordinate of the mouse pointer.

7. const y = event.clientY -;

  • Similarly, this line calculates the vertical (Y) position of the mouse pointer within the current card element by subtracting the top position of the card from the Y-coordinate of the mouse pointer.

8."--xPos", ${x}px);

  • This line sets a custom CSS property named "--xPos" on the current card element. It's used to define the X-coordinate position of the card relative to the mouse pointer.

9."--yPos", ${y}px);

  • Similarly, this line sets a custom CSS property named "--yPos" on the current card element to define the Y-coordinate position of the card relative to the mouse pointer.
const cards = document.querySelectorAll(".card");
const wrapper = document.querySelector(".cards");

wrapper.addEventListener("mousemove", (event) => {
  cards.forEach((card) => {
    const rect = card.getBoundingClientRect();
    const x = event.clientX - rect.left;
    const y = event.clientY -;"--xPos", `${x}px`);"--yPos", `${y}px`);

Final Output:

Creating Flashlight Hover Effect HTML, CSS & JavaScript.gif


In conclusion, by following this guide, you can successfully implement the flashlight effect on hover using HTML, CSS, and JavaScript. This interactive web design technique will set your website apart and captivate your audience.

Code by: Joe

That’s a wrap!

I hope you enjoyed this post. Now, with these examples, you can create your own amazing page.

Did you like it? Let me know in the comments below 🔥 and you can support me by buying me a coffee.

And don’t forget to sign up to our email newsletter so you can get useful content like this sent right to your inbox!

Faraz 😊

End of the article

Subscribe to my Newsletter

Get the latest posts delivered right to your inbox

Latest Post