Morphing Modal Window

Morphing Modal Window

A call-to-action button that animates and turns into a full-size modal window.

Nucleo icons

Sponsored by Nucleo, a free application to collect, customize and export all your icons as icon font and SVG symbols. Made by the CodyHouse folks!

All the resources available on CodyHouse are released under the BSD-3-Clause license. You can support our project with a Paypal donation 🙌

Modal windows are used to display related content, by hiding temporarily the main content. If we imagine our web page as layers distributed along the z-axis, modal windows are on top.

With this nugget we wanted to spice-up the way we fire the modal window: the button that triggers the action animates and turns into a full-width new page. We tried something similar with the product quick view nugget.

The final result is powered by a combination of CSS transition and transformations, jQuery and Velocity.

Creating the structure

The HTML structure is quite basic: a .cd-section element is used to wrap the section content, the action button (.cd-modal-action) and the modal window (.cd-modal).

The .cd-modal-action contains the .btn button, which is used to trigger the action, and the .cd-modal-bg, which is used as modal background.  The modal content is wrapped in the .cd-modal-content element and placed inside the

<section class="cd-section">
   <!-- section content here -->
   <div class="cd-modal-action">
      <a href="#0" class="btn" data-type="modal-trigger">Fire Modal Window</a>
      <span class="cd-modal-bg"></span>

   <div class="cd-modal">
      <div class="cd-modal-content">
         <!-- modal content here -->

   <a href="#0" class="cd-modal-close">Close</a>

Adding style

We used the .cd-modal-bg element as modal window background: initially it is in absolute position and placed right behind the .btn action button, with a visibility: hidden.
When user clicks the action button, the .btn button is morphed into a circle (using the class .to-circle), while the .cd-modal-bg becomes visible and is scaled up to cover the entire viewport. The scale value depends on the viewport size, and is evaluated (and assigned) using Javascript.

.cd-modal-action {
  position: relative;
.cd-modal-action .btn {
  width: 12.5em;
  height: 4em;
  background-color: #123758;
  border-radius: 5em;
  transition: color 0.2s 0.3s, width 0.3s 0s;
.cd-modal-action {
  width: 4em;
  color: transparent;
  transition: color 0.2s 0s, width 0.3s 0.2s;
.cd-modal-action .cd-modal-bg {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-2em);
  width: 4em;
  height: 4em;
  background-color: #123758;
  border-radius: 50%;
  opacity: 0;
  visibility: hidden;
  transition: visibility 0s 0.5s;
.cd-modal-action {
  opacity: 1;
  visibility: visible;

At the end of the scale-up animation, the modal window visibility is changed (using the .modal-is-visible class) to reveal its content.

Events handling

We used jQuery to evaluate those parameters which are not accessible through CSS: the scale value assigned to the .cd-modal-bg, and its left and top position.

For example, this is how we evaluate the scale value:

var btnRadius = $('.cd-modal-bg').width()/2,
left = $('.cd-modal-bg').offset().left + btnRadius, top = $('.cd-modal-bg').offset().top + btnRadius - $(window).scrollTop(), scale = scaleValue(top, left, btnRadius, $(window).height(), $(window).width()); function scaleValue( topValue, leftValue, radiusValue, windowW, windowH) { var maxDistHor = ( leftValue > windowW/2) ? leftValue : (windowW - leftValue), maxDistVert = ( topValue > windowH/2) ? topValue : (windowH - topValue); return Math.ceil(Math.sqrt( Math.pow(maxDistHor, 2) + Math.pow(maxDistVert, 2) )/radiusValue); }

Join our newsletter

Get our monthly recap with the latest CodyHouse news