<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Codebox</title>
    <description>The latest articles on DEV Community by Codebox (@code_box).</description>
    <link>https://dev.to/code_box</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2802072%2F1318481f-b8fe-4669-a90b-9d80ea1d4644.png</url>
      <title>DEV Community: Codebox</title>
      <link>https://dev.to/code_box</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/code_box"/>
    <language>en</language>
    <item>
      <title>Create 3D Model Card Hover Effect using HTML CSS and Javascript</title>
      <dc:creator>Codebox</dc:creator>
      <pubDate>Fri, 07 Feb 2025 16:58:13 +0000</pubDate>
      <link>https://dev.to/code_box/create-3d-model-card-hover-effect-using-html-css-and-javascript-1im4</link>
      <guid>https://dev.to/code_box/create-3d-model-card-hover-effect-using-html-css-and-javascript-1im4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In modern web design, interactivity plays a crucial role in enhancing user engagement and experience. To make your website stand out, try incorporating amazing hover effects. &lt;/p&gt;

&lt;p&gt;A 3D model card is a sleek way to give depth and interactive features to your website.&lt;/p&gt;

&lt;p&gt;In this tutorial, we’ll explain the complete steps on how to create a 3D model card hover effect using only HTML, CSS, and Javascript.&lt;/p&gt;

&lt;p&gt;Whether you're working on a portfolio, e-commerce site, or personal project, this effect will boost your web design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You May Also Like:&lt;/strong&gt; &lt;a href="https://codebox.keyframetechsolution.com/responsive-autoplay-image-slider/" rel="noopener noreferrer"&gt;Autoplay Image Slider with Manual Navigation Button with HTML CSS and JS&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Watch Live Preview&lt;/strong&gt; 👉👉&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/uTPN783tCp8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codebox.keyframetechsolution.com/3d-model-card-hover-effects-with-css-amazing-animations/" rel="noopener noreferrer"&gt;Click Here to Download Source Code&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before diving into the code, it's important to have a basic understanding of the following concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTML:&lt;/strong&gt; The structure of your web page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS:&lt;/strong&gt; The styling and layout of your web page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Transitions and Transforms:&lt;/strong&gt; We'll use for smooth animations and transformations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CSS Pseudo-classes:&lt;/strong&gt; These allow you to apply styles based on the state of an element (e.g., &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/:hover" rel="noopener noreferrer"&gt;:hover&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that in mind, let’s begin.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alert:&lt;/strong&gt; To run the file, you'll need to start the &lt;a href="https://www.apachefriends.org/download.html" rel="noopener noreferrer"&gt;XAMPP server&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;h3&gt;
  
  
  HTML Code Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en" &amp;gt;
&amp;lt;!-- Code by Keyframe Tech Solution --&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;title&amp;gt;Marvel Character Select&amp;lt;/title&amp;gt;
    &amp;lt;script type="module" src="https://ajax.googleapis.com/ajax/libs/model-viewer/4.0.0/model-viewer.min.js"&amp;gt;&amp;lt;/script&amp;gt;
    &amp;lt;link rel="stylesheet" href="./style.css"&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

&amp;lt;div class="card-container"&amp;gt;
    &amp;lt;div class="card"&amp;gt;
        &amp;lt;div class="overflow"&amp;gt;
            &amp;lt;div class="model"&amp;gt;
                &amp;lt;model-viewer camera-orbit="0deg 90deg 164m" camera-target="0m 140m 10m" src="models/spiderman.glb" shadow-intensity="0.4"&amp;gt;&amp;lt;/model-viewer&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="glass"&amp;gt;
            &amp;lt;div class="gradient-blur"&amp;gt;
                &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
                &amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div class="content"&amp;gt;
            &amp;lt;h2&amp;gt;Spider-Man&amp;lt;/h2&amp;gt;
            &amp;lt;p&amp;gt;Spider-Man is a superhero in American comic books published by Marvel Comics.&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;script  src="./script.js"&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CSS Code Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import url("https://fonts.googleapis.com/css2?family=Dancing+Script:wght@400..700&amp;amp;display=swap");
@import url("https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100..900&amp;amp;display=swap");
* {
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    scroll-behavior: smooth;
}
html,
body {
    margin: 0;
    padding: 0;
    height: 100%;
    overflow: hidden;
}
body {
    background: #0096885c;
    --scale: 230px;
    position: relative;
}
body::before {
    content: "";
    width: 100%;
    height: 100%;
    position: absolute;
    background: radial-gradient(circle, #2d2d2d 20%, transparent 11%);
    background-size: 0.5em 0.5em;
    opacity: 0.5;
    inset: 0;
    z-index: 0;
}
.card-container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    flex-wrap: nowrap;
    justify-content: center;
    align-items: center;
    margin: 0;
    padding-top: 28vh;
    padding-bottom: 14vh;
    overflow: hidden;
}
@media (max-width: 800px) {
    html,
    body {
        overflow: inherit;
    }
    .card-container {
        flex-direction: column;
        gap: 80px;
        height: fit-content;
    }
}

.card {
    --clr: #c63e3c;
    --fclr: #f0ffe2;

    width: var(--scale);
    height: 324px;
    min-width: var(--scale);

    &amp;amp;::before {
        content: "";
        display: block;
        position: absolute;
        left: 0;
        right: 0;
        top: 0;
        width: 100%;
        height: 107%;
        background: linear-gradient(var(--clr), #000000 100%);
        transform: skewY(10deg);
        box-shadow: 0 0 0 0px #f9da27, 1px 1px 3px 0px #0002,
            12px 42px 24px -8px #0001, 10px 24px 42px 0 #0001, 1px 4px 12px 0 #0002;

        transition: all 0.2s ease-in-out;
    }

    &amp;amp;::after {
        content: "";
        display: block;
        position: absolute;
        left: -6%;
        right: 0;
        top: 64%;
        width: 112%;
        height: 16%;
        background: var(--clr);
        transform: rotate(-8deg) skewX(-54deg);
        clip-path: polygon(
            -100% -100%,
            200% -100%,
            200% 200%,
            130% 200%,
            59% -100%,
            -30.4% -100%,
            41% 200%,
            -100% 200%
        );

        box-shadow: 0 0 0 0px #f9da27;
        scale: 0.6;
        opacity: 0;
        transition: all 0.2s ease-in-out;
    }

    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: end;
    align-items: center;
    cursor: pointer;

    margin: auto 16px;

    &amp;amp;:hover {
        z-index: 2;

        &amp;amp;::before {
            box-shadow: 0 0 0 8px #234563, 1px 1px 3px 0px #0002,
                12px 42px 24px -8px #0001, 10px 24px 42px 0 #0001, 1px 4px 12px 0 #0002;
        }
    }

    .content {
        position: relative;
        z-index: 1;
        bottom: 0;
        top: unset;
        height: fit-content;
        padding: 12px 24px 0 24px;
        text-align: center;
        h2,
        p {
            margin: 0;
            padding: 0;
            line-height: 124%;
            margin-bottom: 8px;
            font-weight: 700;
            color: var(--fclr);
        }
        p {
            font-size: 14px;
            font-weight: 400;
            margin-bottom: 16px;
            font-family: "Roboto", serif;
        }
        h2{
            font-size: 30px;
            font-family: "Dancing Script", serif;
        }
    }

    .glass {
        pointer-events: none;
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 80%;
        background: linear-gradient(transparent, #000 100%);
        overflow: hidden;
    }
    .overflow {
        pointer-events: none;
        position: absolute;
        width: 200%;
        height: 200%;
        overflow: hidden;
        display: flex;
        justify-content: end;
        align-items: end;
        clip-path: polygon(25% 0, 75% 0, 75% 100%, 25% 100%);
    }
    .model {
        position: absolute;
        width: 100%;
        height: 100%;
        bottom: -10%;
        display: flex;
        justify-content: center;
        align-items: center;
        model-viewer {
            position: absolute;
            width: 500px;
            height: 500px;
            width: 500px;
            height: calc((5 / 3) * var(--scale));
            --progress-bar-color: none;
            --progress-bar-height: 0px;
            opacity: 0;
            transition: filter 0.4s ease-in-out;
            &amp;amp;.loaded {
                animation: onLoad 1s ease-in forwards;
            }
        }
    }
}
.card:hover .overflow {
    clip-path: unset !important;
}
@keyframes onLoad {
    to {
        opacity: 1;
    }
}

.gradient-blur {
    position: absolute;
    z-index: 1;
    height: 100%;
    inset: auto 0 0 0;
    pointer-events: none;
}
.gradient-blur &amp;gt; div,
.gradient-blur::before,
.gradient-blur::after {
    position: absolute;
    inset: 0;
    --p1: 0%;
    --p2: 12.5%;
    --p3: 25%;
    --p4: 37.5%;
    --p5: 50%;
    --p6: 62.5%;
    --p7: 75%;
    --p8: 87.5%;
    --p9: 100%;
    --bclr0: #0000;
    --bclr1: #000;
}
.gradient-blur::before {
    content: "";
    z-index: 1;
    backdrop-filter: blur(0.5px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p1),
        var(--bclr1) var(--p2),
        var(--bclr1) var(--p3),
        var(--bclr0) var(--p4)
    );
}
.gradient-blur &amp;gt; div:nth-of-type(1) {
    z-index: 2;
    backdrop-filter: blur(1px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p2),
        var(--bclr1) var(--p3),
        var(--bclr1) var(--p4),
        var(--bclr0) var(--p5)
    );
}
.gradient-blur &amp;gt; div:nth-of-type(2) {
    z-index: 3;
    backdrop-filter: blur(2px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p3),
        var(--bclr1) var(--p4),
        var(--bclr1) var(--p5),
        var(--bclr0) var(--p6)
    );
}
.gradient-blur &amp;gt; div:nth-of-type(3) {
    z-index: 4;
    backdrop-filter: blur(4px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p4),
        var(--bclr1) var(--p5),
        var(--bclr1) var(--p6),
        var(--bclr0) var(--p7)
    );
}
.gradient-blur &amp;gt; div:nth-of-type(4) {
    z-index: 5;
    backdrop-filter: blur(8px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p5),
        var(--bclr1) var(--p6),
        var(--bclr1) var(--p7),
        var(--bclr0) var(--p8)
    );
}
.gradient-blur &amp;gt; div:nth-of-type(5) {
    z-index: 6;
    backdrop-filter: blur(16px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p6),
        var(--bclr1) var(--p7),
        var(--bclr1) var(--p8),
        var(--bclr0) var(--p9)
    );
}
.gradient-blur &amp;gt; div:nth-of-type(6) {
    z-index: 7;
    backdrop-filter: blur(32px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p7),
        var(--bclr1) var(--p8),
        var(--bclr1) var(--p9)
    );
}
.gradient-blur::after {
    content: "";
    z-index: 8;
    backdrop-filter: blur(64px);
    mask: linear-gradient(
        to bottom,
        var(--bclr0) var(--p8),
        var(--bclr1) var(--p9)
    );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  JavaScript Code Structure
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(() =&amp;gt; {
    const modelViewers = document.querySelectorAll("model-viewer");
    const cards = document.querySelectorAll(".card");
    const defaultOrbit = "0deg 90deg 164m";
    const applyOrbit = (modelViewer, orbit, vert) =&amp;gt; {
        modelViewer.setAttribute("camera-orbit", orbit);
        modelViewer.setAttribute("interpolation-decay", "200");
        modelViewer.setAttribute("camera-target", `0m ${vert}m 10m`);
    };
    cards.forEach((card, index) =&amp;gt; {
        const modelViewer = modelViewers[index];
        if (modelViewer) {
            const calcOrbit = (xPos, cardRect) =&amp;gt; {
                const normalizedX = (xPos - cardRect.left) / cardRect.width;
                const angle = normalizedX * 90 - 45;
                return `${-angle}deg 90deg 164m`;
            };
            card.addEventListener("mousemove", (event) =&amp;gt; {
                const cardRect = card.getBoundingClientRect();
                const orbit = calcOrbit(event.clientX, cardRect);
                applyOrbit(modelViewer, orbit, 120);
            });
            card.addEventListener("mouseleave", () =&amp;gt; {
                applyOrbit(modelViewer, defaultOrbit, 140);
            });
            modelViewer.addEventListener("load", () =&amp;gt; {
                modelViewer.classList.add("loaded");
            });
        } else {
            console.log(`No model found for card at i:${index}`);
        }
    });
})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You May Also Like:&lt;/strong&gt; &lt;a href="https://codebox.keyframetechsolution.com/vertical-timeline-design/" rel="noopener noreferrer"&gt;How to Build Vertical Timeline Design using HTML CSS &amp;amp; jQuery&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing and Debugging
&lt;/h3&gt;

&lt;p&gt;Before deploying, it’s crucial to test your card hover effect in various browsers and on different devices to ensure smooth performance. &lt;/p&gt;

&lt;p&gt;Make sure the animations are responsive and that the hover effect works as expected.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You’ve now created a 3D model card hover effect. &lt;/p&gt;

&lt;p&gt;By using simple but powerful properties like perspective, transform, and transition, this technique creates an interactive and engaging user experience&lt;/p&gt;

&lt;p&gt;You can easily adapt and customize this effect to suit your specific needs, such as adding more content, tweaking the design, or experimenting with different animations.&lt;/p&gt;

&lt;p&gt;By mastering hover effects, you can add depth and interactivity to your websites, making them visually appealing and more engaging to users.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>css</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
