So good - smooth responsive type scaling with css vars

Coefficient Calculations

These coefficients help determine how quickly the font size should increase or decrease as the viewport width changes. 

These coefficients are calculated using calc() to determine the rate of change in font sizes.

Each coefficient corresponds to a range of viewport widths, ensuring that the text scales smoothly and proportionally as the viewport changes.css


--coefficient-0: calc((16 - 4) / (calc(479 / 100) - calc(1 / 100))); 
--coefficient-1: calc((14 - 13) / (calc(767 / 100) - calc(478 / 100))); 
--coefficient-2: calc((15 - 14) / (calc(991 / 100) - calc(767 / 100))); 
--coefficient-3: calc((16 - 15) / (calc(1440 / 100) - calc(991 / 100))); 
--coefficient-4: calc((18 - 16) / (calc(1920 / 100) - calc(1440 / 100))); 
--coefficient-5: calc((20 - 18) / (calc(2400 / 100) - calc(1920 / 100)));


Update:

Always looking for ways to make the UI transitions smoother, with more fluidity, I turned the calculations above into a code sketch to see the behavior I was after. 

I noticed the default behavior, upon browser resize, though it was a more incremental rate of change, could be a lot smoother. 

So, I thought I would take the idea a little farther. 

I should really be unifying my site code, but this is a more interesting distraction. 

It would be more fluid of an effect to add transitions that trigger as the browser is resized by the user, rather than just keep the default resizing behaviors, which are fine, but could be better. 

If you want a more experiential scroll story with scroll triggered animations, you want to keep the continuity of the experience if technically possible.

So, I started sketching that transition effect out.

I wanted much more fluidity than the native responsive text resize default behavior, even with the coefficient method above. 

I want to trigger transitions (which I can smooth out) as elements resize, as the user resizes their browser. 

I like having the ability to make that fluid. I think it would be a nice touch. This is a sketch that sort of starts to do that. I'm liking the method so far. I'll file it under smooth controlled or animated responsive resizing motion transitions. 

Here's a sketch:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Responsive Layout with Transition</title>
    <style>
        /* Basic Reset */
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            margin: 0;
            font-family: Arial, sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            overflow: hidden;
            background-color: #FFFFFF; 
        }

        /* Container to maintain aspect ratio and minimum width */
        .container {
            width: 80vw; /* Adjusts with viewport width */
            max-width: 800px; /* Maximum width to control scaling */
            min-width: 320px; /* Minimum width to ensure readability on small screens */
            aspect-ratio: 1 / 1.2; /* Aspect ratio to maintain exact proportions */
            background-color: #FFFFFF; /* Changed to white background */
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            padding: 2vw;
            border: 2px solid #000; /* Optional border for layout visualization */
            transform: scale(0.8); /* Initial scaling for a balanced look */
            transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1), width 0.5s cubic-bezier(0.4, 0, 0.2, 1); /* Smooth transition for scaling and width */
        }

        /* Responsive scaling for headline */
        h1 {
            font-size: clamp(1.5rem, 4vw, 2.5rem); /* Sets responsive font size using clamp */
            margin-bottom: 1vh;
            text-align: center;
            transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); /* Smooth transition for scaling */
        }

        /* Responsive scaling for paragraph */
        p {
            font-size: clamp(1rem, 2vw + 0.5rem, 1.25rem); /* Sets responsive font size using clamp with adjusted range */
            max-width: 90%; /* Ensures text does not stretch too wide */
            text-align: center;
            margin-bottom: 1vh;
            transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); /* Smooth transition using transform */
        }

        /* Button styling with scaling */
        button {
            font-size: clamp(1rem, 2vw, 1.5rem); /* Responsive font size for buttons */
            padding: 0.5vw 2vw; /* Scaled padding */
            border: none;
            cursor: pointer;
            background-color: black;
            color: white;
            margin-bottom: 1vh;
            transition: background-color 0.3s ease-in-out, transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); /* Smooth transitions for size, color, and scaling */
        }

        button:hover {
            background-color: #444;
            transform: scale(1.05); /* Slightly enlarges the button on hover */
        }

        /* Image with scaling */
        img {
            width: 30vw; /* Scales with viewport width */
            max-width: 300px; /* Caps the width at a maximum value */
            height: auto; /* Maintains aspect ratio */
            transition: transform 0.5s cubic-bezier(0.4, 0, 0.2, 1); /* Smooth transitions for scaling */
        }

        img:hover {
            transform: scale(1.05); /* Slightly enlarges the image on hover */
        }

        /* Media Queries for further control */
        @media (max-width: 768px) {
            .container {
                transform: scale(0.9); /* Adjust scaling for mobile view */
            }
        }

        @media (max-width: 480px) {
            .container {
                width: 90vw; /* Expand width for small screens */
                transform: scale(0.95); /* Further adjust scaling */
                padding: 3vw; /* Adjust padding for smaller screens */
            }
            h1, p, button {
                font-size: clamp(1rem, 3vw, 1.5rem); /* Adjusts font size for readability */
            }
        }
    </style>
</head>
<body>
    <!-- Main container for layout with fixed aspect ratio -->
    <div class="container">
        <h1>Headline 1</h1> <!-- Headline -->
        <p>This layout demonstrates a responsive design that adjusts to different screen sizes using CSS techniques such as flexbox, aspect ratio, and the clamp function for font sizes. It maintains a minimum width for usability on small devices, scales smoothly, and uses GSAP for enhanced transitions and hover effects.</p> <!-- Updated paragraph -->
        <button>Button</button> <!-- Button -->
        <img src="https://via.placeholder.com/300" alt="Placeholder Image"> <!-- Placeholder Image -->
    </div>

    <!-- GSAP CDN -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.5/gsap.min.js"></script>
    <script>
        // Select the container
        const container = document.querySelector('.container');
        const headline = document.querySelector('h1');
        const paragraph = document.querySelector('p');
        const button = document.querySelector('button');
        const image = document.querySelector('img');

        // GSAP animation for initial load
        gsap.fromTo(container, 
            { scale: 0.7, opacity: 0 }, 
            { scale: 0.8, opacity: 1, duration: 1, ease: "power2.out" }
        );

        // GSAP resize effect on window resize
        window.addEventListener('resize', () => {
            const scaleFactor = window.innerWidth / 1000;
            gsap.to(container, { 
                scale: Math.min(scaleFactor, 0.9), 
                duration: 0.5, 
                ease: "power2.out" 
            });
        });

        // Hover effect using GSAP for button
        button.addEventListener('mouseenter', () => {
            gsap.to(button, { scale: 1.1, backgroundColor: '#444', duration: 0.3, ease: "power2.out" });
        });
        button.addEventListener('mouseleave', () => {
            gsap.to(button, { scale: 1, backgroundColor: 'black', duration: 0.3, ease: "power2.out" });
        });

        // Hover effect using GSAP for image
        image.addEventListener('mouseenter', () => {
            gsap.to(image, { scale: 1.05, duration: 0.3, ease: "power2.out" });
        });
        image.addEventListener('mouseleave', () => {
            gsap.to(image, { scale: 1, duration: 0.3, ease: "power2.out" });
        });
    </script>
</body>
</html>

Popular posts from this blog

AR Animated Card

Design Systems with Pre-Populated Design Token Variables

Text to Instant Video