"Learn how to create a scrolling div using a combination of CSS and JavaScript with absolute and relative

After relying solely on "pre-made" components like Mui or TailWind, I decided to create a component using only CSS and maybe JavaScript. However, I encountered some difficulties when attempting to position a div inside an image using relative and absolute positions. I am aware that absolute positioning disrupts the natural flow... and I need to find a way to make this scrollable div work.

The issue at hand: when the page width is less than the combined width of all images, the images overflow into the next div, disregarding the margins set by another div.

I am considering a solution where I use useRef to retrieve the width from the 'a' tag and calculate the left position to create a gap. For example, left: 0, left: 580*funcGetWidthFromRef(), left: funcGetWidthFromRef().

Is there another alternative solution?

Here is my code:

import Image from "next/image";
import styles from "../../styles/Card.module.css";
export default function Card() {
    const listArticles = [1, 2, 3, 4];
    const textTitle = ["Vant", "Vam", "Puits", "JUmpP"];
    return (
        <>
            {" "}
            <section className={`${styles.scrollableCategoryContent}`}>
                {listArticles.map((art, index) => {
                    return (
                        <article key={index} className={`styles.Game${art}`}>
                            <a
                                href=""
                                className={`${styles.cardAnchorConteirner}`}
                                style={{
                                    left: `${170 * index}px`,
                                }}
                            >
                                <Image
                                    className={`${styles.cardImage}`}
                                    width={580}
                                    height={480}
                                    objectFit="cover"
                                    objectPosition="top left"
                                    src={
                                        "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Postgres_Query.jpg/1920px-Postgres_Query.jpg"
                                    }
                                    alt="test"
                                ></Image>
                                <div
                                    className={`${styles.textCardBackGround}`}
                                >
                                    <h2
                                        className={`${styles.cardTitleText}`}
                                    >{`${textTitle[index]}`}</h2>
                                </div>
                            </a>
                        </article>
                    );
                })}
            </section>
        </>
    );
}

.scrollableCategoryContent{
  display: grid;
  grid-auto-flow: column;
  background-color: black;
  max-width: 700;
  height: 480px;
  overflow-x: scroll;
}

Game1, .Game2, .Game3, .Game4 {
  
}

.cardAnchorConteirner{
  width: 100%;
  height: 100%;
  position: relative;
}

.cardImage{
  position: absolute;
}

.textCardBackGround {
 position: absolute;
 background-color: aqua;
 width: 100%;
 height: 20%;
 left: 0px;
 right: 0px;
 bottom: 20%;
}

.cardTitleText{
  color: white;
}

Answer №1

Here is a simple solution: place a div outside all relative and absolute positioned divs. This div without positions can utilize Grid and allow the normal flow to be followed. However, problems may arise if the div or other component has zero width or height. I previously attempted to use UseRef with good results, but the code became excessively large when implementing additional solutions such as resizing images.

import Image from "next/image";
import styles from "../../styles/CardAlt.module.css";

export default function CarCompAlt() {
    const games = [1, 2, 3, 4];
    const titles = ["Valorant", "Mw2", "RPGs", "Actions"];

    return (
        <>
            <section className={`${styles.trywarp}`}>
                {games.map((value, index) => {
                    return (
                        <article
                            key={index}
                            className={`${styles.thisJustWork}`}
                        >
                            <a
                                href=""
                                className={`${styles.cardArchorContainer}`}
                            >
                                <Image
                                    className={`${styles.imageContainer}`}
                                    src={
                                        "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Postgres_Query.jpg/1920px-Postgres_Query.jpg"
                                    }
                                    width={584}
                                    height={480}
                                    alt={`${2265}`}
                                    objectFit="cover"
                                    objectPosition="center"
                                ></Image>
                                <h3 className={`${styles.titleContainer}`}>
                                    {titles[index]}
                                </h3>
                            </a>
                        </article>
                    );
                })}
            </section>
        </>
    );
}

CSS

.trywarp{
    display: grid;
    grid-auto-flow: column;
    gap: 100px;
    overflow-x: scroll;
    overflow-y: clip;
}

.thisJustWork{
    width: 500px;
    height: 500px;
    background-color: brown;
}


.cardAnchorContainer{
    position: relative;
}

.imageContainer{
    position: absolute;
}

.titleContainer{
    position: absolute;
    z-index: 50;
    color: aliceblue;
}

The solution using useRef involves giving a width to "scrollableCategoryContent" to prevent an increase in gap.

import Image from "next/image";
import { HtmlHTMLAttributes, useEffect, useRef, useState } from "react";
import styles from "../../styles/Card.module.css";

export default function Card() {
    const refScrollableCategoryContent = useRef<any>();
    const [pixelGain, setPixelGain] = useState<number>(0);
    const [widthScrollable, setWidthScrollable] = useState<any>(
        refScrollableCategoryContent.current?.getBoundingClientRect().width
    );
    const listArticles = [1, 2, 3, 4];
    const textTitle = ["Vant", "Vam", "Puits", "JUmpP"];

    function resizeScrollable() {
        const widthRefScroll =
            refScrollableCategoryContent.current?.getBoundingClientRect().width;
        setWidthScrollable(widthRefScroll);
    }

    useEffect(() => {
        window.addEventListener("resize", resizeScrollable);
        resizeScrollable();

        return () => {
            window.removeEventListener("resize", resizeScrollable);
        };
    }, []);

    return (
        <>
            <div>
                <div>Window size: {widthScrollable}</div>
                <button
                    onClick={() => {
                        setWidthScrollable(
                            refScrollableCategoryContent.current?.getBoundingClientRect()
                        );
                    }}
                >
                    refScrollableCategoryContent
                </button>
            </div>
            
            <section
                className={`${styles.scrollableCategoryContent}`}
                ref={refScrollableCategoryContent}
            >

                {listArticles.map((art, index) => {
                    return (
                        <article key={index} className={`styles.Game${art}`}>
                            <a
                                href=""
                                className={`${styles.cardAnchorConteirner}`}
                                style={{
                                    left: `${(425 + pixelGain) * index}px`,
                                }}
                            >
                                <Image
                                    className={`${styles.cardImage}`}
                                    width={584}
                                    height={480}
                                    objectFit="cover"
                                    objectPosition="center"
                                    src={
                                        "https://upload.wikimedia.org/wikipedia/commons/thumb/c/cb/Postgres_Query.jpg/1920px-Postgres_Query.jpg"
                                    }
                                    alt="test"
                                ></Image>

                                <div
                                    className={`${styles.textCardBackGround}`}
                                >
                                    <h2
                                        className={`${styles.cardTitleText}`}
                                    >{`${textTitle[index]}`}</h2>
                                </div>
                            </a>
                        </article>
                    );
                })}
            </section>
        </>
    );
}

CSS

.scrollableCategoryContent{
    display: grid;
    grid-auto-flow: column;
    background-color: black;
    width: 1000px;
    height: 480px;
    overflow-x: scroll;
    overflow-y: clip;
}

.cardAnchorConreiner{
    position: relative;
}

.cardImage{
    position: absolute;
}

.textCardBackground {
    position: absolute;
    background-color: aqua;
    width: 100%;
    height: 20%;
    bottom: 20%;
}

.cardTitleText{
    color: white;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using jQuery with AJAX to transfer data and store it within PHP

Hello! I am looking for assistance in sending or retrieving data from a form using jQuery and AJAX to transfer the data to a PHP page for database storage. Any guidance on how to achieve this using jQuery and AJAX would be greatly appreciated. Thank you! ...

Is there any way to remove the two default aspNetHidden Divs in asp.net web forms?

After creating an empty webform page in asp.net, the generated code looks like this: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="Threetier.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org ...

The FontLoader feature seems to be causing issues when integrated with Vuejs

While working on a Vue project with threejs, I encountered an error similar to the one described here. The issue arose when attempting to generate a text geometry despite confirming that the path to the typeface font is accurate and in json format. ...

Preventing Angular $rootElement.on('click') from affecting ReactJS anchor tag interactions

Running both AngularJS and ReactJS on the same page has caused an issue for me. Whenever I click on a ReactJS <a> tag, Angular's $rootElement.on('click) event is triggered and the page redirects. I need to perform some functionality in Re ...

React form input values fail to refresh upon submission

After attempting to upload the form using React, I noticed that the states are not updating properly. They seem to update momentarily before reverting back to their original values. I am unsure of why this is happening. Take a look at this gif demonstrati ...

`Finding the nodejs API route for displaying images from a database`

How can I successfully display an image from the database without getting a string of question marks instead? Click here to see the issue >>> When attempting to directly call the API using the provided link, the following result is returned: {&qu ...

Webpack is having trouble resolving the specified file or directory

MyAPP: |--src   |--index.js   |--content.js |--webpack.config.js index.js : const React = require('react'); const ReactDom = require('react-dom'); const View = require('./content'); ReactDom.render(<View/ ...

determining the file size of images being loaded remotely by retrieving their image URLs

There is a straightforward regex function in jQuery that I'm using to automatically add an image tag to image URLs shared by users. This means that when a user posts something like www.example.com/image.jpg, the image tag will be included so that user ...

I encountered an issue with my foreach loop where the checkbox failed to properly send the value

Having an issue with the checkbox not sending the desired value. This is my HTML code for the checkbox. I am using a foreach loop. <form id="signupform" autocomplete="off" method="post" action="inputchecklist.php" class="form_container left_label"> ...

Troubleshooting the issue of CSS animations activating twice and causing a flickering effect specifically in the Firefox browser

I am facing an issue with CSS animations in Firefox. When I try to slide in some radio buttons upon clicking a button, the animation seems to be firing twice in Firefox while it works fine in Chrome. I have attempted several solutions but haven't been ...

Tips for effectively utilizing a cart collection system

I am currently exploring how to utilize sessions for user tracking and updating my cart collection. Below is the code from my route.js file in an Express and Node application: app.post('/cart/:id', function (req, res) { if (!userKey) { ...

Dealing with website links in Next.js and Chakra-UI: Tips and Tricks

When incorporating react linkify directly with chakra-ui components such as Text, the links cannot be managed. Issue Example import Linkify from 'react-linkify'; import {Box, Text} from '@chakra-ui/react'; export default function Usag ...

Finding attributes with spaces in their values using XPath

Is there a way to select an attribute with spaces in xpath? I am currently trying to select a checkbox attribute named "checked type". I have experimented with //[@checked type], //[@checked-type], //[@checked_type], and //[@checked\stype], but none ...

Excessive image display | HTML and CSS synergize

I am having some trouble with my image gallery. Each image is displayed as a vertical column and has zooming effects when hovered over. Clicking on an image should show it in full screen with a caption. The problem arises when dealing with images that are ...

Navigating in AngularJS with various URL parameters

Within my application, I am in need of using routes that require multiple attributes from the URL to be passed into PHP. The current setup that is functioning correctly is as follows: .when('/jobs/:type', { templateUrl: function(attrs){ ...

I've been attempting to develop a React application, but I consistently encounter the following error: "npm ERR! cb() function was never invoked!"

Here is the issue at hand: HP@DESKTOP-1HP83V8 MINGW64 ~/Desktop/Web-Development (master) $ npx create-react-app my-app A new React app is being created in C:\Users\HP\Desktop\Web-Development\my-app. Packages are being installed. ...

How to create a dropdown menu in React js with an array of items

Can we structure the array without splitting it into two parts and iterating over them? arrayList=[Jeans, Jackets, Pants, Fragrance, Sunglasses, Health Products] <div className='Flexbox'> //arrayList1.map](//arrayList1.map)(x=>return(< ...

Strange behavior detected in TypeScript generic function when using a class as the generic parameter

class Class { } const f0 = <T extends typeof Class> (c:T): T => { return c } const call0 = f0 (Class) //ok const f1 = <T extends typeof Class> (c:T): T => { const a = new c() return a //TS2322: Type 'Class' is not assigna ...

where is the yarn global registry located?

After updating yarn to point to my custom registry and verifying the changes, here is what I found: $yarn config list -g yarn config v1.22.10 info yarn config { 'version-tag-prefix': 'v', 'version-git-tag': true, ' ...

Searching for text within an HTML document using Selenium in Python can be easily achieved by using the appropriate methods and

Is there a way to find and retrieve specific texts within an HTML file using Selenium in Python, especially if the text is not enclosed within an element? <div class="datagrid row"> ==$0 <h2 class="bottom-border block">Accepted Shipment</h ...