Skip to main content

4 posts tagged with "CSS"

View All Tags

Dynamically Adding Input Fields Using React.js

· 4 min read
Kamlesh
Quality Assurance @TestKarts

Managing dynamic input fields in React.js is a common requirement for modern web applications. Whether you’re building a form that allows users to add multiple email addresses, phone numbers, or any other type of information, dynamically adding and removing input fields can significantly enhance user experience.

In this article, we’ll walk through the process of creating a form with dynamic input fields in React.js. Our form will allow users to add new input fields, delete existing ones, and ensure that at least one input field is always present.

Introduction

Forms are a crucial part of web applications, enabling user interaction and data collection. However, the static nature of traditional forms can be limiting, especially when users need to add multiple entries dynamically. React.js, with its powerful state management and component-based architecture, offers an elegant solution to this problem.

By leveraging React’s capabilities, we can create forms that allow users to add and remove input fields on the fly, providing a more flexible and user-friendly experience. This tutorial will guide you through building such a form step-by-step, covering state management, event handling, and rendering dynamic components.

Setting Up the Project

First, let's create a new React project. If you haven’t already, install the create-react-app tool using npm or yarn.

npx create-react-app dynamic-input-fields
cd dynamic-input-fields
npm start

This will set up a new React project and start the development server.

Creating the DynamicInput Component

Next, we'll create a component called DynamicInput that will handle the dynamic input fields.

Step 1: Initial Setup

Create a new file named DynamicInput.js inside the src directory and add the following code:

import React, { useState } from 'react';

const DynamicInput = () => {
const [inputs, setInputs] = useState([{ value: '' }]);

const handleChange = (index, event) => {
const values = [...inputs];
values[index].value = event.target.value;
setInputs(values);
};

const handleAdd = () => {
setInputs([...inputs, { value: '' }]);
};

const handleRemove = (index) => {
if (inputs.length > 1) {
const values = [...inputs];
values.splice(index, 1);
setInputs(values);
}
};

return (
<div>
{inputs.map((input, index) => (
<div key={index}>
<input
type="text"
value={input.value}
onChange={(event) => handleChange(index, event)}
/>
{inputs.length > 1 && (
<button type="button" onClick={() => handleRemove(index)}>
Remove
</button>
)}
</div>
))}
<button type="button" onClick={handleAdd}>
Add Input
</button>
</div>
);
};

export default DynamicInput;

Step 2: Adding the Component to the App

Open src/App.js and import the DynamicInput component. Then, add it to the component tree:

import React from 'react';
import './App.css';
import DynamicInput from './DynamicInput';

function App() {
return (
<div className="App">
<h1>Dynamic Input Fields</h1>
<DynamicInput />
</div>
);
}

export default App;

Step 3: Styling the Component

You can add some basic CSS to src/App.css to make the form look better:

.App {
font-family: sans-serif;
text-align: center;
}

input {
margin: 5px;
padding: 10px;
}

button {
margin: 5px;
padding: 10px;
}

Understanding the Code

  1. State Management: The inputs state is an array of objects, each containing a value property. This state holds the values of all dynamic input fields.
  2. handleChange Function: This function updates the value of a specific input field based on the user's input.
  3. handleAdd Function: This function adds a new input field by appending an empty object to the inputs array.
  4. handleRemove Function: This function removes an input field at a specified index. It ensures that at least one input field remains by checking the length of the inputs array before allowing deletion.
  5. Rendering the Inputs: The component maps over the inputs array and renders an input field for each item. A remove button is conditionally rendered if there is more than one input field.

Conclusion

Dynamically adding and removing input fields in React.js is a powerful feature that can greatly enhance the flexibility and user-friendliness of your forms. By following the steps outlined in this article, you can implement this functionality in your own projects, ensuring a seamless and interactive user experience.

Remember to consider edge cases, such as preventing the removal of the last input field, to ensure your form behaves as expected.


Pin One Element to Scroll Until Bottom of Second Element

· 7 min read
Kamlesh
Quality Assurance @TestKarts

In the vast landscape of web design, certain features can elevate user experience to new heights. One such feature is the combination of scrollable sections and sticky columns, providing a seamless and intuitive browsing experience. In this article, we'll delve into the intricacies of implementing scrollable sections and sticky columns using React and CSS, empowering you to enhance your website's usability and engagement.

Scrolling Particular Section Only

Understanding Scrollable Sections: Scrollable sections are essential for enabling users to navigate through content seamlessly, particularly in lengthy web pages. They offer a structured and organized browsing experience, allowing users to consume information at their own pace. By leveraging React and CSS, developers can implement scrollable sections with ease, offering flexibility and customization options to tailor the experience to users' needs.

Exploring Sticky Columns: Sticky columns play a vital role in keeping essential content visible as users scroll. Whether it's navigation menus, sidebars, or call-to-action elements, sticky columns ensure that important information remains within reach, enhancing user engagement and reducing friction in the browsing experience. By dissecting the provided code snippet, we'll gain insights into how sticky columns are implemented and customized using React and CSS.

Creating a Seamless User Experience: The synergy between scrollable sections and sticky columns is key to creating a seamless user experience. By combining these features, websites can enhance navigation, readability, and overall user engagement. Real-world examples will illustrate how scrollable sections and sticky columns work together to optimize user experience, inspiring you to implement these techniques in your own web projects.

Understanding the Code:

Let's break down the following React code snippet:

import React, { useEffect, useState } from 'react';
import reactLogo from "./assets/react.svg";
import "./App.css";

function App() {
// State to track whether section 1 should be fixed
const [isSection1Fixed, setIsSection1Fixed] = useState(false);

useEffect(() => {
// Function to handle scroll events
const handleScroll = () => {
// Get references to section 1 and section 2
const section1 = document.getElementById('section-1');
const section2 = document.getElementById('section-2');

// Get the top offset of section 1 and section 2
const section1Top = section1.offsetTop;
const section2Top = section2.offsetTop;

// Get the current scroll position
const scrollTop = window.scrollY || document.documentElement.scrollTop;

// Determine if section 1 should be fixed
if (scrollTop > section1Top) {
if (scrollTop < section2Top - window.innerHeight) {
setIsSection1Fixed(true);
} else {
setIsSection1Fixed(false);
}
} else {
setIsSection1Fixed(false);
}
};

// Add event listener for scroll events
window.addEventListener('scroll', handleScroll);

// Clean up by removing event listener when component unmounts
return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []); // Empty dependency array ensures the effect runs only once on component mount

return (
<>
{/* Sticky Header */}
<div className='header'>Sticky Header</div>

{/* Two-item container for left and right columns */}
<div className='two-item-container'>
{/* Left column */}
<div id='sticky' className='item-one'>
{/* Content goes here */}
</div>

{/* Right column */}
<div id='section-1' className={`item-two ${isSection1Fixed ? 'fixed-section' : ''}`}>
{/* Content goes here */}
</div>
</div>

{/* Scrolling section */}
<div id='section-2' className="another-section">
{/* Content goes here */}
</div>
</>
);
}

export default App;

In this code:

  • We import necessary dependencies, including React, icons, and CSS styles.
  • We define a functional component App.
  • We use the useState hook to manage the state of isSection1Fixed, which determines whether the left column (section 1) should be fixed.
  • We use the useEffect hook to add an event listener for scroll events. Inside the effect, we calculate the scroll position and determine whether section 1 should be fixed.
  • We return JSX, which includes the sticky header, two-item container with left and right columns, and a scrolling section.

Now, let's delve into the CSS styles:

.header {
width: 100%;
height: 56px;
background: #72a24d;
top: 0;
position: sticky; /* Keeps the header fixed at the top */
z-index: 999;
padding-left: 12px;
padding-right: 12px;
}

.two-item-container {
position: relative;
margin-top: 50px; /* Ensures space below the sticky header */
display: flex;
flex-direction: row;
}

.item-one {
width: 50%;
background: #000;
height: 500px;
}

.item-two {
width: 50%;
background: #970f0f;
}

.another-section {
background: #136322;
}

@media (min-width: 768px) {
.item-one {
position: sticky; /* Makes the left column sticky on larger screens */
top: 56px; /* Ensures it starts below the header */
}
}

Here's what each CSS rule does:

  • .header: Styles the sticky header with a background color, fixed position, and padding.
  • .two-item-container: Sets up the layout for the two-column structure using flexbox.
  • .item-one and .item-two: Styles the left and right columns with background colors and dimensions.
  • .another-section: Styles the scrolling section with a background color.
  • @media (min-width: 768px): Applies additional styles to the left column for larger screens, making it sticky below the header.

Determine if section 1 should be fixed

Let's break down the logic behind this conditional statement:

if (scrollTop > section1Top) {
if (scrollTop < section2Top - window.innerHeight) {
setIsSection1Fixed(true);
} else {
setIsSection1Fixed(false);
}
} else {
setIsSection1Fixed(false);
}

This code is responsible for determining whether the left column (section 1) should be fixed/sticky based on the user's scroll position.

Here's the breakdown of each part:

  1. Outer Condition:

    if (scrollTop > section1Top) {

    This condition checks if the current scroll position (scrollTop) is greater than the top offset of section 1 (section1Top). In other words, it checks if the user has scrolled past the point where section 1 should become sticky.

  2. Inner Condition:

    if (scrollTop < section2Top - window.innerHeight) {

    Inside the outer condition, this inner condition checks if the current scroll position is less than the top offset of section 2 (section2Top) minus the height of the viewport (window.innerHeight). This condition ensures that section 1 remains sticky until the top of section 2 approaches the bottom of the viewport. In other words, it checks if section 1 should remain sticky within the viewport's boundaries.

  3. Setting State:

    • If both conditions are met (i.e., the user has scrolled past section 1 and hasn't reached section 2 yet), setIsSection1Fixed(true) is called. This means that section 1 should be fixed/sticky.
    • If the inner condition is not met (i.e., the user has scrolled past section 2 or reached the bottom of the viewport), setIsSection1Fixed(false) is called. This means that section 1 should not be fixed/sticky.
    • If the outer condition is not met (i.e., the user hasn't scrolled past section 1), setIsSection1Fixed(false) is called. This ensures that section 1 is not fixed/sticky when the user hasn't scrolled past it.
  4. Fallback:

    } else {
    setIsSection1Fixed(false);
    }

    If the outer condition is not met (i.e., the user hasn't scrolled past section 1), this fallback ensures that isSection1Fixed is set to false. This handles the case where the user scrolls back up above section 1, ensuring that it's not fixed/sticky in that scenario.

This conditional statement dynamically updates the state isSection1Fixed based on the user's scroll position, ensuring that section 1 becomes sticky when needed and returns to its default position when appropriate.

Related Questions-

1-ScrollTrigger: Responsive Pin with Horizontal Scroll without (GSAP)

2- How to set scrolling on product page just like flipkart?

Conclusion: In conclusion, scrollable sections and sticky columns are powerful tools for improving usability and engagement on websites. By understanding the intricacies of their implementation using React and CSS, you can elevate your website's user experience to new heights. We encourage you to experiment with these features in your projects and embrace the transformative impact they can have on user satisfaction and retention.

How to Create a Responsive Horizontal Scrolling Card Slider in JavaScript

· 7 min read
Kamlesh
Quality Assurance @TestKarts

Introduction:

Horizontal scrolling is a popular UI pattern used in many modern web applications. A horizontal card slider is a similar design pattern that allows users to scroll through a set of cards horizontally. In this tutorial, we'll be using JavaScript and CSS to create a horizontal card slider with forward and backward scrolling buttons. Horizontal Card slider with arrow

Features:

  • Step-by-step instructions: The post provides a detailed and easy-to-follow tutorial on how to create a horizontal scrolling card with forward and back buttons.

  • Interactive functionality: The post provides code that allows users to interact with the horizontal scrolling card by clicking on the forward and back buttons to slide the cards left or right.

  • End-of-scroll detection: The post includes code to detect when the horizontal scroll has reached either end, and disables the relevant button to prevent users from scrolling further.

  • Default state: The post explains how to set the default state of the horizontal scroll to be at the leftmost card and disable the back button.

  • Customizable code: The post provides code that can be customized to fit different design and functionality requirements.

Implementation:

To create a horizontal card slider, we first need to create a container element with a fixed width and overflow-x set to scroll. Inside the container, we'll add a set of card elements that are floated left and have a fixed width.

Next, we'll use JavaScript to detect when the slider reaches the left or right end and disable the corresponding arrow button. We'll also add event listeners to the arrow buttons to scroll the slider left or right when clicked.

Here's the complete code to implement a horizontal card slider with forward and backward scrolling buttons:

Here are the steps to follow:

Step 1: Create the HTML markup

Create an HTML element to hold the cards that will be horizontally scrolled. Inside this element, create a container for the cards that will be scrolled. Each card should be wrapped in a div element. Here's an example:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<script src="https://kit.fontawesome.com/a59b9b09ab.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.3.1/dist/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<link rel="stylesheet" href="style.css" />
<title>Static Template</title>
</head>

<body>
<div class="cover">
<button class="left" onclick="leftScroll()">
<i class="fas fa-angle-double-left"></i>
</button>
<div class="scroll-images">
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-1-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM9.283 4.002H7.971L6.072 5.385v1.271l1.834-1.318h.065V12h1.312V4.002Z"/>
</svg>
<h4>Card 1</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-2-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM6.646 6.24c0-.691.493-1.306 1.336-1.306.756 0 1.313.492 1.313 1.236 0 .697-.469 1.23-.902 1.705l-2.971 3.293V12h5.344v-1.107H7.268v-.077l1.974-2.22.096-.107c.688-.763 1.287-1.428 1.287-2.43 0-1.266-1.031-2.215-2.613-2.215-1.758 0-2.637 1.19-2.637 2.402v.065h1.271v-.07Z"/>
</svg>
<h4>Card 2</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-3-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.082.414c.92 0 1.535.54 1.541 1.318.012.791-.615 1.36-1.588 1.354-.861-.006-1.482-.469-1.54-1.066H5.104c.047 1.177 1.05 2.144 2.754 2.144 1.653 0 2.954-.937 2.93-2.396-.023-1.278-1.031-1.846-1.734-1.916v-.07c.597-.1 1.505-.739 1.482-1.876-.03-1.177-1.043-2.074-2.637-2.062-1.675.006-2.59.984-2.625 2.12h1.248c.036-.556.557-1.054 1.348-1.054.785 0 1.348.486 1.348 1.195.006.715-.563 1.237-1.342 1.237h-.838v1.072h.879Z"/>
</svg>
<h4>Card 3</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-4-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM7.519 5.057c-.886 1.418-1.772 2.838-2.542 4.265v1.12H8.85V12h1.26v-1.559h1.007V9.334H10.11V4.002H8.176c-.218.352-.438.703-.657 1.055ZM6.225 9.281v.053H8.85V5.063h-.065c-.867 1.33-1.787 2.806-2.56 4.218Z"/>
</svg>
<h4>Card 4</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-5-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.006 4.158c1.74 0 2.924-1.119 2.924-2.806 0-1.641-1.178-2.584-2.56-2.584-.897 0-1.442.421-1.612.68h-.064l.193-2.344h3.621V4.002H5.791L5.445 8.63h1.149c.193-.358.668-.809 1.435-.809.85 0 1.582.604 1.582 1.57 0 1.085-.779 1.682-1.57 1.682-.697 0-1.389-.31-1.53-1.031H5.276c.065 1.213 1.149 2.115 2.72 2.115Z"/>
</svg>
<h4>Card 5</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-6-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM8.21 3.855c-1.868 0-3.116 1.395-3.116 4.407 0 1.183.228 2.039.597 2.642.569.926 1.477 1.254 2.409 1.254 1.629 0 2.847-1.013 2.847-2.783 0-1.676-1.254-2.555-2.508-2.555-1.125 0-1.752.61-1.98 1.155h-.082c-.012-1.946.727-3.036 1.805-3.036.802 0 1.213.457 1.312.815h1.29c-.06-.908-.962-1.899-2.573-1.899Zm-.099 4.008c-.92 0-1.564.65-1.564 1.576 0 1.032.703 1.635 1.558 1.635.868 0 1.553-.533 1.553-1.629 0-1.06-.744-1.582-1.547-1.582Z"/>
</svg>
<h4>Card 6</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-7-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0ZM5.37 5.11h3.972v.07L6.025 12H7.42l3.258-6.85V4.002H5.369v1.107Z"/>
</svg>
<h4>Card 7</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-8-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-5.03 1.803c0-1.248-.943-1.84-1.646-1.992v-.065c.598-.187 1.336-.72 1.336-1.781 0-1.225-1.084-2.121-2.654-2.121-1.57 0-2.66.896-2.66 2.12 0 1.044.709 1.589 1.33 1.782v.065c-.697.152-1.647.732-1.647 2.003 0 1.39 1.19 2.344 2.953 2.344 1.77 0 2.989-.96 2.989-2.355Zm-4.347-3.71c0 .739.586 1.255 1.383 1.255s1.377-.516 1.377-1.254c0-.733-.58-1.23-1.377-1.23s-1.383.497-1.383 1.23Zm-.281 3.645c0 .838.72 1.412 1.664 1.412.943 0 1.658-.574 1.658-1.412 0-.843-.715-1.424-1.658-1.424-.944 0-1.664.58-1.664 1.424Z"/>
</svg>
<h4>Card 8</h4>
</div>
<div class="child">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-9-circle-fill" viewBox="0 0 16 16">
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0Zm-8.223 4.146c2.104 0 3.123-1.464 3.123-4.3 0-3.147-1.459-4.014-2.97-4.014-1.63 0-2.871 1.02-2.871 2.73 0 1.706 1.171 2.667 2.566 2.667 1.06 0 1.7-.557 1.934-1.184h.076c.047 1.67-.475 3.023-1.834 3.023-.71 0-1.149-.363-1.248-.72H5.258c.094.908.926 1.798 2.52 1.798Zm.118-3.972c.808 0 1.535-.528 1.535-1.594s-.668-1.676-1.56-1.676c-.838 0-1.517.616-1.517 1.659 0 1.072.708 1.61 1.54 1.61Z"/>
</svg>
<h4>Card 9</h4>
</div>
</div>
<button class="right" onclick="rightScroll()">
<i class="fas fa-angle-double-right"></i>
</button>
</div>
</body>
</html>

Step 2: Add CSS

Add CSS to create the horizontal scroll effect. Set the scroll-container element to overflow-x: scroll to allow horizontal scrolling. Set the width of each card to the desired width and make sure they are displayed inline-block. Here's an example:

.cover {
position: relative;
padding: 0px 30px;
margin-top: 100px;
}

.left {
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}

.right {
position: absolute;
right: 0;
top: 50%;
transform: translateY(-50%);
}

.scroll-images {
position: relative;
width: 100%;
padding: 40px 0px;
height: auto;
display: flex;
flex-wrap: nowrap;
overflow-x: hidden;
overflow-y: hidden;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
}

.child {
display: flex;
justify-content: center;
align-items: center;
min-width: 250px;
height: 200px;
padding: 0px 15px;
margin: 1px 10px;
border: 1px solid #f1f1f1;
overflow: hidden;
-webkit-box-shadow: 0px 0px 15px 2px rgb(0 0 0 / 10%);;
box-shadow: 0px 0px 15px 2px rgb(0 0 0 / 10%);;
}

.child img, .child > svg {
position: absolute;
margin-top: -195px;
width: 80px;
height: 80px;
object-fit: cover;
object-position: center;
border-radius: 50%;
background: #03A9F4;
}

.scroll-images::-webkit-scrollbar {
width: 5px;
height: 8px;
background-color: #aaa;
}

.scroll-images::-webkit-scrollbar-thumb {
background-color: black;
}

button {
background-color: transparent;
border: none;
outline: none;
cursor: pointer;
font-size: 25px;
}

Step 3: Add JavaScript

Add JavaScript to handle the scrolling and enable/disable the arrow buttons. Here's an example:

document.addEventListener("DOMContentLoaded", function () {
const scrollImages = document.querySelector(".scroll-images");
const scrollLength = scrollImages.scrollWidth - scrollImages.clientWidth;
const leftButton = document.querySelector(".left");
const rightButton = document.querySelector(".right");

function checkScroll() {
const currentScroll = scrollImages.scrollLeft;
if (currentScroll === 0) {
leftButton.setAttribute("disabled", "true");
rightButton.removeAttribute("disabled");
} else if (currentScroll === scrollLength) {
rightButton.setAttribute("disabled", "true");
leftButton.removeAttribute("disabled");
} else {
leftButton.removeAttribute("disabled");
rightButton.removeAttribute("disabled");
}
}

scrollImages.addEventListener("scroll", checkScroll);
window.addEventListener("resize", checkScroll);
checkScroll();

function leftScroll() {
scrollImages.scrollBy({
left: -200,
behavior: "smooth"
});
}

function rightScroll() {
scrollImages.scrollBy({
left: 200,
behavior: "smooth"
});
}

leftButton.addEventListener("click", leftScroll);
rightButton.addEventListener("click", rightScroll);
});

Customize the JavaScript to fit your specific needs. For example, you may need to change the width of each card or the amount that the scroll container scrolls when the arrow buttons are clicked.

And that's it! With these steps, you can create a card horizontal scrolling with forward and back arrow buttons that enable/disable depending on the scroll position.

Try on CodePen :-

Create a responsive multiple card with equal size and height using Html, CSS and React

· 6 min read
Kamlesh
Quality Assurance @TestKarts

In modern web design, it is crucial to create responsive and visually appealing layouts that work across various devices. One of the most popular design elements is cards that can be used to display various types of content in a compact and visually pleasing way. In this blog, we will walk through how to create a responsive multiple card with equal size and height using HTML, CSS, and React.

Preview-