Go to homepage

Projects /

Morphing Modal Window

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

Morphing Modal Window
Check our new component library →

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 div.cd-modal.

<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 .btn.to-circle {
  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 .cd-modal-bg.is-visible {
  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); }

Level up your CSS skills

Each month we email a 1-minute CSS tutorial to 20K developers

Awesome! We just sent you a confirmation link by email

Error - please try again or contact us

Your email address is already subscribed

Project duplicated

Project created

Globals imported

There was an error while trying to export your project. Please try again or contact us.