<button class="iastate22-button" data-micromodal-trigger="modal-1">Modal Trigger<span class="arrow"></span></div>

<div class="iastate22-modal" id="modal-1" aria-hidden="false">
  <div class="iastate22-modal__overlay" tabindex="-1" data-micromodal-close>
    <div class="iastate22-modal__container iastate22-modal__container-with-media" id="modal-1-content" role="dialog" aria-modal="true" aria-labelledby="modal-1-title">
      <button class="iastate22-modal__close" aria-label="Close modal" data-micromodal-close><i class="fa-light fa-xmark" aria-hidden="true"></i></button>
<div class="iastate22-modal__media">
    <img src="../../img/Component-Modal-Square-Image_FPO.jpg" alt="" loading="lazy" width="400" height="400">
</div>
<div class="iastate22-modal__content">
    <h2 class="iastate22-modal__title" id="modal-1-title">Modal Title Lorem Ipsum Dolor Sit Amet</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.</p>
    <div class="iastate22-modal__content-cta">
        <a href="#" class="iastate22-button">Button Label Lorem</a>
    </div>
</div>
</div>
</div>
</div>
<button class="iastate22-button" data-micromodal-trigger="{{ id }}">Modal Trigger<span class="arrow"></span></div>

<div class="iastate22-modal" id="{{ id }}" aria-hidden="false">
  <div class="iastate22-modal__overlay" tabindex="-1" data-micromodal-close>
    <div class="iastate22-modal__container{% if image %} iastate22-modal__container-with-media{% endif %}" id="{{ id }}-content" role="dialog" aria-modal="true" aria-labelledby="{{ id }}-title">
      <button class="iastate22-modal__close" aria-label="Close modal" data-micromodal-close><i class="fa-light fa-xmark" aria-hidden="true"></i></button>
      {% if image %}
      <div class="iastate22-modal__media">
        <img src="{{ image|path }}" alt="" loading="lazy" width="400" height="400">
      </div>
      {% endif %}
      <div class="iastate22-modal__content">
        <h2 class="iastate22-modal__title" id="{{ id }}-title">{{ title }}</h2>
        {{ content|raw }}
        <div class="iastate22-modal__content-cta">
          {{ call_to_action|raw }}
        </div>
      </div>
    </div>
  </div>
</div>
{
  "id": "modal-1",
  "image": "../../img/Component-Modal-Square-Image_FPO.jpg",
  "title": "Modal Title Lorem Ipsum Dolor Sit Amet",
  "content": "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.</p>",
  "call_to_action": "<a href=\"#\" class=\"iastate22-button\">Button Label Lorem</a>"
}
  • Content:
    .iastate22-modal {
      display: none;
    
      &.is-open {
        display: block;
        position: relative;
        z-index: 11;
      }
    }
    
    .iastate22-modal__overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      display: flex;
      justify-content: center;
      align-items: center;
      background: rgba($white, 0.9);
    }
    
    .iastate22-modal__container {
      background-color: $white;
      max-width: rem(414);
      width: 80%;
      max-height: 90vh;
      box-shadow: rem(9) rem(9) rem(20) rgba($black, 0.2);
      overflow-y: auto;
      position: relative;
      padding: rem(45);
      @include media-breakpoint-up(md) {
        max-width: rem(844);
        width: 90%;
        max-height: 100vh;
        padding: 0;
      }
      @include media-breakpoint-up(lg) {
        width: 100%;
      }
      &.iastate22-modal__container-with-media {
        @include media-breakpoint-up(md) {
          display: flex;
          align-items: flex-start;
          flex-wrap: wrap;
        }
      }
    }
    
    .iastate22-modal__header {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }
    
    .iastate22-modal__content {
      padding: rem(20) 0 0 0;
      @include media-breakpoint-up(md) {
        flex: 0 1 auto;
        width: 100%;
        padding: rem(45) rem(75) rem(45) rem(54);
      }
      .iastate22-modal__container-with-media & {
        @include media-breakpoint-up(md) {
          width: 64%;
        }
      }
      .iastate22-modal__content-cta {
        margin-top: rem(20);
      }
    }
    
    .iastate22-modal__title {
      margin: 0 0 rem(10) 0;
      padding: 0;
      font-family: $typeface-sans-serif;
      font-size: rem(21);
      line-height: (30 / 21);
      font-weight: 700;
    }
    
    .iastate22-modal__close {
      background: transparent;
      z-index: 1;
      width: rem(44);
      height: rem(44);
      position: absolute;
      top: rem(2);
      right: rem(2);
      padding: 0;
      border: none;
      cursor: pointer;
      &:hover {
        .fa-xmark {
          color: $iastate-maroon;
        }
      }
      .fa-xmark {
        pointer-events: none;
        font-size: rem(25);
        color: $iastate-red;
        transition: 0.2s color ease-in-out;
        @include media-breakpoint-up(md) {
          font-size: rem(30);
        }
      }
    }
    
    .iastate22-modal__media {
      @extend %responsive-img;
      @include media-breakpoint-up(md) {
        flex: 0 1 auto;
        width: 36%;
      }
      &:before {
        padding-top: 100%;
      }
    }
    
    .iastate22-modal__content-form {
      margin-top: rem(20);
      @include media-breakpoint-up(md) {
        display: flex;
        align-items: flex-end;
      }
      label {
        margin-bottom: 0;
        padding-right: rem(10);
        @include media-breakpoint-up(md) {
          flex: 1 1 auto;
        }
        .label-text {
          margin-bottom: rem(3);
        }
        input {
          width: 100%;
        }
      }
      button[type="submit"] {
        @extend %iastate22-button;
        margin-bottom: 0;
        @include media-breakpoint-up(md) {
          flex: 0 0 auto;
        }
      }
    }
    
  • URL: /components/raw/modal/_modal.scss
  • Filesystem Path: src/components/modal/_modal.scss
  • Size: 2.7 KB

Modal

This is a custom component (the class has been prefaced with .iastate22-[classname]).

  • This uses a 3rd-party library (which is lightweight and very accessible) called Micromodal.js
  • There are two variants, the default modal contains an optional image, with headline, raw html and a raw html call to action section, and --with-form with also contains an optional image, with headline, raw html and a small form with an input and submit button. The type of input field and button is configurable.
  • The image field is optional in both variants
  • This uses a data-attribute of [data-micromodal-trigger] on the modal trigger and requires a corresponding id on the modal
  • The examples here use the .iastate22-button but any element can be used to trigger the modal
  • The custom styles are imported into the index.scss file as @import "../components/modal/modal";
  • The .ts file for the javascript is imported into the index.ts file as import Modal from "./components/modal"; and called as Modal.init();