DEV Community

Cover image for Make an element take up the entire page
Phuoc Nguyen
Phuoc Nguyen

Posted on

Make an element take up the entire page

Sometimes we want users to focus on a specific element that takes up the entire page. For example, when displaying code results, it's helpful to allow users to view the output without any distractions from the implementation details. As you can see, the playground in the original post offers similar functionality.

Another example is when we allow users to click on an image to see it in full-page mode. This has some benefits. First, it allows the user to see the image at its maximum size, which makes it easier to appreciate and examine details that might not be visible otherwise. Second, viewing an image in full-page mode often removes any visual distractions from the surrounding page, allowing the user to focus solely on the image itself. This can be especially useful for images that include text or other important information, as it ensures that the user can see all of the details clearly and without interruption.

In this post, we'll learn how to implement this functionality using JavaScript. Let's dive in!

HTML markup

The layout has two elements: an outer element that we want to view in full page, and an inner element which is a button that triggers the full page view.

<div id="container" class="container">
    <button id="view-full-page">Full page</button>
</div>
Enter fullscreen mode Exit fullscreen mode

Viewing in full-page mode

When users click the button, the container element will take up the whole page. To make this happen, we need to handle the click event of the button.

Inside the handler, we can add the full-page class to the target element. This class will set the position of the element to fixed and its width and height to 100%, so that it takes up the entire page. We also update the text of the button to say Close when in full-page mode so that users can easily exit out of full-page view.

Here's an example of what full-page class and the event handler could look like:

.full-page {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
Enter fullscreen mode Exit fullscreen mode
const containerEle = document.getElementById('container');
const viewFullPageButton = document.getElementById('view-full-page');

viewFullPageButton.addEventListener('click', () => {
    containerEle.classList.add('full-page');
    viewFullPageButton.innerHTML = 'Close';
});
Enter fullscreen mode Exit fullscreen mode

However, once the target element is in full-page mode, clicking the button should remove the full-page class and revert the label to its original value.

To make this happen, we need to update the event handler. We can check whether the target element is in full page mode by seeing if it has the full-page class. If it does, we remove the class and change the button label back to its original text.

Here's an example of what the updated event handler could look like:

viewFullPageButton.addEventListener('click', () => {
    const isFullPage = containerEle.classList.contains('full-page');
    if (isFullPage) {
        containerEle.classList.remove('full-page');
        viewFullPageButton.innerHTML = 'Full page';
    } else {
        containerEle.classList.add('full-page');
        viewFullPageButton.innerHTML = 'Close';
    }
});
Enter fullscreen mode Exit fullscreen mode

Adding animation to full-page mode

Let's spice up our full-page mode by adding some animation. This will not only make it look cooler but also improve the user experience by clearly indicating that the element is now in full-page mode.

To make this happen, we can use CSS animations. Here's how:

.container {
    transition: width 0.3s, height 0.3s;
}
Enter fullscreen mode Exit fullscreen mode

In our case, we're animating the container element as it switches to full-page mode. By transitioning the width and height properties over 0.3 seconds, we create a smooth animation that lets users know something has changed on the page.

However, you might notice that the layout breaks as soon as the element changes dimensions. Don't worry, we'll fix this issue in the next section. For now, give the demo a try and see for yourself how adding animation can make a big difference.

Fixing broken layout issue

To fix the layout issue mentioned earlier, we'll create a placeholder that has the same content and position as the original target element. We'll use the cloneElement() function to create a copy of the target element, ensuring that all the children of the target element are also cloned in the new element. To keep the copied element hidden, we'll set the visibility property to hidden. Finally, we'll insert the cloned element right after the original element using the insertAdjacentElement() function.

const clonedEle = containerEle.cloneNode(true);
clonedEle.removeAttribute('id');
clonedEle.style.visibility = 'hidden';
containerEle.insertAdjacentElement('afterend', clonedEle);
Enter fullscreen mode Exit fullscreen mode

Once the placeholder is in place, we'll animate the original element using JavaScript. Rather than using the CSS animation mentioned earlier, we'll use JavaScript to transition the target element from its original position to a full-page position.

We're going to make a quick change to the .full-page class by removing the top and left properties:

.full-page {
    position: fixed;
    width: 100%;
    height: 100%;
    background: #fff;
    z-index: 9999;
}
Enter fullscreen mode Exit fullscreen mode

To calculate the original position, we'll use the getBoundingClientRect() function to determine the bounding rectangle of the target element and retrieve the top and left properties from the result.

const rect = containerEle.getBoundingClientRect();
containerEle.style.top = `${rect.top}px`;
containerEle.style.left = `${rect.left}px`;
Enter fullscreen mode Exit fullscreen mode

Now we can animate the target element from its original position to the full-page mode position by calling the animate() function. This built-in JavaScript method allows us to create animations on HTML elements. We'll define an array with only one element that describes the final state of the animation. The object passed as an argument specifies how long the animation should last and what type of easing should be used.

By setting the fill property to forwards, we ensure that the target element retains its final state even after the animation is complete.

This is how we animate the target element:

containerEle.animate([{
    top: 0,
    left: 0,
}], {
    duration: 300,
    easing: 'ease-in-out',
    fill: 'forwards',
});
Enter fullscreen mode Exit fullscreen mode

Removing the cloned element when exiting full-page mode

When users exit full-page mode, we need to remove any cloned elements that were created and reset the styles for the container element. To accomplish this, we can use the JavaScript Animation API's finish event, which is triggered when an animation completes its job.

First, we determine the original position of the target element by using the cloned element and then use the animate() function to animate the target element from the full-page mode back to its original position.

const rect = clonedEle.getBoundingClientRect();
const collapseAnimation = containerEle.animate([{
    top: `${rect.top}px`,
    left: `${rect.left}px`,
}], {
    duration: 300,
    easing: 'ease-in-out',
    //fill: 'forwards',
});
Enter fullscreen mode Exit fullscreen mode

Once the animation is complete, we handle the finish event to remove the cloned element and reset any styles applied to indicate the position, such as position, top, and left properties.

Here's an example of how we can handle the finish event:

collapseAnimation.addEventListener('finish', () => {
    clonedEle.remove();
    containerEle.style.removeProperty('position');
    containerEle.style.removeProperty('top');
    containerEle.style.removeProperty('left');
});
Enter fullscreen mode Exit fullscreen mode

By removing the cloned element and resetting the styles for the container element, we can ensure that our page functions as expected and that there are no leftover elements or styles after exiting full-page mode.

Finally, let's check out the latest demo of the steps we've taken so far.

Note

It's important to note that the demo is contained within an iframe, so you may have noticed that the sample code uses the position: absolute declaration for the full-page mode. However, in reality, you'll need to change it to position: fixed.

See also


It's highly recommended that you visit the original post to play with the interactive demos.

If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

If you want more helpful content like this, feel free to follow me:

Top comments (0)