Create Interactive Booking Button with mask-image using HTML and CSS (Source Code)


By Faraz -

Learn how to design a stylish booking button using HTML and CSS with mask-image effect.

Create Interactive Booking Button with mask-image using HTML and CSS.webp

Table of Contents

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

A booking button serves as a call-to-action element on websites, prompting users to take specific actions like booking appointments, making reservations, or purchasing services. Adding a mask-image effect to the button enhances its visual appeal, making it more engaging for users. In this tutorial, we'll delve into the creation of a booking button with a mask-image effect using HTML and CSS.

Source Code

Step 1 (HTML Code):

Begin by creating the HTML structure for the booking button. Utilize the <button> tag to create a button element within your HTML document.

Here's a breakdown of each part:

1. <!DOCTYPE html>: Declares the document type and version of HTML being used.

2. <html lang="en">: Defines the root element of the HTML document and specifies the language as English.

3. <head>: Contains meta-information about the HTML document, such as character encoding, viewport settings, and title.

  • <meta charset="UTF-8">: Specifies the character encoding for the document as UTF-8, which supports a wide range of characters.
  • <meta http-equiv="X-UA-Compatible" content="IE=edge">: Instructs Internet Explorer to use the latest rendering engine available.
  • <meta name="viewport" content="width=device-width, initial-scale=1.0">: Sets the viewport width to the device width and sets the initial zoom level to 1.0. This is important for responsive design on different devices.
  • <title>Booking Button</title>: Sets the title of the webpage displayed in the browser tab.
  • <link rel="stylesheet" href="https://cdnjs...css">: Links an external stylesheet from the CDN (Content Delivery Network) to normalize CSS styles across different browsers.
  • <link rel="stylesheet" href="styles.css">: Links an external stylesheet named "styles.css" for additional styling of the webpage.

4. <body>: Contains the content of the webpage visible to the user.

  • <button>: Defines a button element.
  • <span>: A generic inline container used for grouping and styling purposes.
  • <span class="container">: A container span used for further grouping and styling.
  • <span class="primary"></span>: An empty span element with the class "primary." This serves as a visual element within the button.
  • <span class="complimentary"></span>: An empty span element with the class "complimentary," also serves as a visual element within the button.
  • <span>Book a demo</span>: Another span containing the text "Book a demo" which appears inside the button.

Step 2 (CSS Code):

Once the basic HTML structure of the button is in place, the next step is to add styling to the button using CSS.

Next, we will create our CSS file. In this file, we will use some basic CSS rules to create our booking button.

Let's break down the CSS code step by step:

1. @font-face: This rule defines a custom font named "Geist Sans" and specifies its source using a URL pointing to a TrueType Font (TTF) file.

2. Universal box-sizing: This selector applies the box-sizing property to all elements, including pseudo-elements, ensuring that the specified width and height properties include padding and border, not margins.

3. Body styling:

  • display: grid; - Makes the body a grid container.
  • place-items: center; - Centers the content both horizontally and vertically within the grid container.
  • min-height: 100vh; - Sets the minimum height of the body to 100% of the viewport height.
  • font-family: - Defines a font stack to be used for text content, with "Geist Sans" as the preferred font followed by a series of fallback fonts.

4. Button styling:

  • height: 48px; - Sets the height of the button.
  • padding: 0; - Removes any padding inside the button.
  • display: grid; - Makes the button a grid container.
  • border-radius: 8px; - Rounds the corners of the button.
  • border: 2px solid black; - Adds a solid black border around the button.
  • letter-spacing: 0.25px; - Adjusts the spacing between letters.
  • cursor: pointer; - Changes the cursor to a pointer when hovering over the button.
  • position: relative; - Positions the button relative to its normal position.
  • background: - Sets the background color of the button to black.
  • color: white; - Sets the text color to white.
  • font-weight: 80; - Sets the font weight to 80.
  • scale: 2; - Scales the button size.
  • outline-color: - Sets the color of the outline when focused.
  • outline-offset: - Adjusts the offset of the outline.

5. Button hover and focus styling:

  • button:is(:hover, :focus-visible) - Applies styles when the button is hovered over or focused.
  • button:active - Applies styles when the button is active (pressed).

6. Button span styling:

  • button > span:nth-of-type(1) - Styles the first span child of the button.
  • scale: calc(1 - (var(--pressed, 0) * 0.05)); - Scales the span based on the value of the custom property "--pressed".
  • transition: scale 0.1s; - Adds a smooth transition effect when scaling.

7. Container styling:

  • Sets styling for a container element including dimensions, background color, position, border radius, box shadow, and transition effects.

8. Primary and Complimentary styling:

  • These classes define styles for pseudo-elements used within the container, including background color, mask, opacity, and transition effects.

9. Button span styling:

  • button > span:nth-of-type(2) - Styles the second span child of the button, including padding, display, and vertical alignment.

10. Animation for Pseudo-elements:

  • :where(.primary, .complimentary)::after - Applies styles to the pseudo-elements of class "primary" and "complimentary".
  • --distance: calc(100cqi + 100%); - Calculates the distance for animation.
  • content: ""; - Adds content to the pseudo-element.
  • height: calc(var(--size) * 4); - Sets the height of the pseudo-element based on a custom property.
  • aspect-ratio: 1; - Maintains a 1:1 aspect ratio.
  • position: absolute; - Positions the pseudo-element absolutely within its container.
  • left: 0%; - Aligns the pseudo-element to the left of its container.
  • top: 50%; - Aligns the pseudo-element vertically centered.
  • translate: -50% -50%; - Translates the pseudo-element to center it properly.
  • background: radial-gradient(hsl(0 0% 0%), transparent); - Applies a radial gradient as the background.
  • animation: fly-by calc((2 - var(--active, 0)) * 1s) infinite linear; - Initiates the fly-by animation with calculated duration and timing.

11. Keyframes Animation:

  • @keyframes fly-by - Defines the fly-by animation.
  • 0% { translate: -100% -50%; } - Initial position of the animation.
  • 100% { translate: var(--distance) -50%; } - Final position of the animation.

This will give our booking button 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.

@font-face {
  font-family: "Geist Sans";
  src: url("") format("truetype");

*:before {
	box-sizing: border-box;

body {
	display: grid;
	place-items: center;
	min-height: 100vh;
	font-family:  "Geist Sans", "SF Pro Text", "SF Pro Icons", "AOS Icons", "Helvetica Neue", Helvetica, Arial, sans-serif, system-ui;
	font-weight: 80;

button {
	height: 48px;
	padding: 0;
	display: grid;
	border-radius: 8px;
	border: 2px solid black;
	letter-spacing: 0.25px;
	cursor: pointer;
	position: relative;
	background: black;
	color: white;
	font-weight: 80;
	scale: 2;
  outline-color: hsl(75 100% 45%);
  outline-offset: 0.25rem;

button:is(:hover, :focus-visible) {
	--active: 1;

button:active {
  --pressed: 1;

button > span:nth-of-type(1) {
	height: 100%;
	width: 100%;
	border-radius: 8px;
	position: absolute;
	inset: 0;
  scale: calc(1 - (var(--pressed, 0) * 0.05));
  transition: scale 0.1s;

button:is(:hover, :focus-visible) .container {
	width: 100%;

.container {
	--mask-image: url(;
	--spread: 24px;
	--size: 28px;
	width: 58px;
	height: 100%;
	background: hsl(75 100% 65%);
	position: absolute;
	left: 0;
	transition: width 0.25s;
	border-radius: 6px;
	box-shadow: 0 10px 10px -5px hsl(0 0% 0% / 0.5);
	container-type: inline-size;

.primary {
	content: "";
	position: absolute;
	inset: 0;
	background: hsl(0 0% 0% / 0.15);
	z-index: 2;
	mask: var(--mask-image) 50% 50% / var(--size) var(--size) no-repeat;
	container-type: inline-size;

:where(.primary, .complimentary)::after {
	--distance: calc(100cqi + 100%);
	content: "";
	height: calc(var(--size) * 4);
	aspect-ratio: 1;
	position: absolute;
	left: 0%;
	top: 50%;
	translate: -50% -50%;
	background: radial-gradient(hsl(0 0% 0%), transparent);
	animation: fly-by calc((2 - var(--active, 0)) * 1s) infinite linear;

@keyframes fly-by {
	0% { translate: -100% -50%; }
	100% { translate: var(--distance) -50%; }

.complimentary {
	content: "";
	position: absolute;
	inset: 0;
	opacity: var(--active, 0);
	transition: opacity 0.25s;
	background: hsl(0 0% 0% / 0.15);
		var(--mask-image) calc(50% - (var(--spread) * 1)) 50% / var(--size) var(--size) no-repeat,
		var(--mask-image) calc(50% - (var(--spread) * 2)) 50% / var(--size) var(--size) no-repeat,
		var(--mask-image) calc(50% - (var(--spread) * 3)) 50% / var(--size) var(--size) no-repeat,
		var(--mask-image) calc(50% + (var(--spread) * 1)) 50% / var(--size) var(--size) no-repeat,
		var(--mask-image) calc(50% + (var(--spread) * 2)) 50% / var(--size) var(--size) no-repeat,
		var(--mask-image) calc(50% + (var(--spread) * 3)) 50% / var(--size) var(--size) no-repeat;

button > span:nth-of-type(2) {
	padding: 0 1.1rem 0 calc(58px + 1.1rem);
	display: grid;
	place-items: center;
	height: 100%;

Final Output:

Create Interactive Booking Button with mask-image using HTML and CSS.gif


Creating a booking button with a mask-image effect using HTML and CSS can significantly enhance your website's user interface and user experience. By following the steps outlined in this tutorial, you can design visually appealing buttons that drive user engagement and conversions effectively. Experiment with different design elements to create a button that resonates with your target audience and complements your website's design aesthetics.

Design by: Jhey

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