skip to Main Content

This is my HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Hovering Boxes</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="container"></div>
    <script>
        let container = document.getElementById('container');
        let boxCount = 100;

        for(let i = 0; i < boxCount; i++) {
            let box = document.createElement('div');
            box.className = 'box';
            container.appendChild(box);
        }
    </script>
</body>
</html>

And this is my CSS:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

#container {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px;
    width: 100%;
    perspective: 1000px;
}

.box {
    background-color: red;
    height: 50px;
    width: 50px;
    transform-style: preserve-3d;
    transition: transform 0.5s, filter 0.3s;
}

.box:hover {
    transform: translateZ(150px);
    filter: brightness(1);
    background-color: #87F1FF;
}

.box:hover + * {
    transform: translateZ(100px) rotateY(60deg);
    filter: brightness(0.8);
}

.box:hover + * + * {
    transform: translateZ(50px) rotateY(30deg);
    filter: brightness(0.6);
}



.box:hover + * + * + * {
    transform: translateZ(25px) rotateY(15deg);
    filter: brightness(0.4);
}

.box:has(+ *:hover) {
    transform: translateZ(100px) rotateY(-60deg);
    filter: brightness(0.8);
}

.box:has(+ * + *:hover) {
    transform: translateZ(50px) rotateY(-30deg);
    filter: brightness(0.6);
}

.box:has(+ * + * + *:hover) {
    transform: translateZ(25px) rotateY(-15deg);
    filter: brightness(0.4);
}

This code currently selects the hovered element and sets effects to its following and preceding elements. However, I also want the top and bottom elements relative to the hovered element to receive similar effects.

What would be the best approach to select and style these top and bottom elements when hovering over a box?

I have tried using JavaScript to achieve this but couldn’t find an effective solution. Any help or guidance would be greatly appreciated!

2

Answers


  1. Chosen as BEST ANSWER

    * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
    }
    
    #container {
        display: grid;
        justify-content: center;
        grid-template-columns: repeat(10, 0fr);
        grid-template-rows: repeat(10, 0fr);
        width: 90%;
        perspective: 1000px;
    }
    
    .hovered-top {
        background-color: chartreuse;
    }
    
    .box {
        background-color: red;
        height: 50px;
        width: 50px;
        transform-style: preserve-3d;
        transition: transform 0.2s, filter 0.2s;
    }
    
    .box:hover {
        transform: translateZ(150px);
        filter: brightness(1);
        background-color: #87F1FF;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>hovering boxes</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div id="container"></div>
        <script>
                    const container = document.getElementById('container');
                        const rows = 10;
                        const cols = 10;
                        const boxCount = rows * cols;
    
                        for (let i = 0; i < boxCount; i++) {
                            const box = document.createElement('div');
                            box.classList.add('box');
                            container.appendChild(box);
                        }
    
                        const boxes = document.querySelectorAll('.box');
    
                        boxes.forEach((box, index) => {
                            box.addEventListener('mouseover', () => {
                                const row = Math.floor(index / cols);
                                const col = index % cols;
    
                                boxes.forEach((b, i) => {
                                    const bRow = Math.floor(i / cols);
                                    const bCol = i % cols;
                                    const distance = Math.sqrt(Math.pow(row - bRow, 2) + Math.pow(col - bCol, 2));
                                    b.style.transform = `translateZ(${100 - distance * 10}px)`;
                                    b.style.filter = `brightness(${1 - distance * 0.1})`;
                                    b.style.transitionDelay = `${distance * 50}ms`;
                                });
                            });
    
                            box.addEventListener('mouseout', () => {
                                boxes.forEach(b => {
                                    b.style.transform = 'translateZ(0)';
                                    b.style.filter = 'brightness(0)';
                                    b.style.transitionDelay = '0ms';
                                });
                            });
                        });
        </script>
    </body>
    </html>


  2. * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background-color: #f0f0f0; /* Added background color for contrast */
    }
    
    #container {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-wrap: wrap;
        gap: 5px;
        width: 90%; /* Added width constraint */
        perspective: 1000px;
    }
    
    .box {
        background-color: red;
        height: 50px;
        width: 50px;
        transform-style: preserve-3d;
        transition: transform 0.5s, filter 0.3s;
    }
    
    .box:hover {
        transform: translateZ(150px);
        filter: brightness(1);
        background-color: #87F1FF;
    }
    
    .box:hover + .box {
        transform: translateZ(100px) rotateY(60deg);
        filter: brightness(0.8);
    }
    
    .box:hover + .box + .box {
        transform: translateZ(50px) rotateY(30deg);
        filter: brightness(0.6);
    }
    
    .box:hover + .box + .box + .box {
        transform: translateZ(25px) rotateY(15deg);
        filter: brightness(0.4);
    }
    
    /* Hover effect for previous siblings */
    .box:has(+ .box:hover) {
        transform: translateZ(100px) rotateY(-60deg);
        filter: brightness(0.8);
    }
    
    .box:has(+ .box + .box:hover) {
        transform: translateZ(50px) rotateY(-30deg);
        filter: brightness(0.6);
    }
    
    .box:has(+ .box + .box + .box:hover) {
        transform: translateZ(25px) rotateY(-15deg);
        filter: brightness(0.4);
    }
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Hovering Boxes</title>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
        <div id="container"></div>
        <script>
            // Create 100 boxes and append them to the container
            const container = document.getElementById('container');
            const boxCount = 100;
    
            for(let i = 0; i < boxCount; i++) {
                const box = document.createElement('div');
                box.className = 'box';
                container.appendChild(box);
            }
        </script>
    </body>
    </html>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search