Summer Sale! All accounts are 50% off this week.

Leff7's avatar
Level 4

CSS - Animation with clip path circle

I am using material web components and I would like to make a search field that opens on click with animation, that would have the effect shown on this page at small screen sizes. I have made a toolbar with the search icon that I show on small screens and that on clicking reveals the search input field that takes the whole width of the toolbar.

Html:

<header class="mdc-toolbar mdc-toolbar--fixed toolbar-light">
  <div class="mdc-toolbar__row">
    <section class="menu mdc-toolbar__section mdc-toolbar__section--align-start">
      <a href="#" class="material-icons mdc-toolbar__menu-icon">menu</a>
      <span class="mdc-toolbar__title">Title</span>
    </section>
    <section class="mdc-toolbar__section">
      <form action="/search" method="get">
        <div class="mdc-text-field mdc-text-field--box mdc-text-field--with-leading-icon autocomplete-search-field">
          <i class="material-icons mdc-text-field__icon" tabindex="0">search</i>
          <input name="q"
                 type="text"
                 class="mdc-text-field__input search-input-js aa-input-search"
                 placeholder="Search for players and videos ..."
                 aria-label="Full-Width Text Field">
        </div>
      </form>
    </section>
    <section class="mdc-toolbar__section mdc-toolbar__section--align-end" role="toolbar">
      <a href="#" id="search-input-icon" class="material-icons mdc-toolbar__icon" aria-label="Download" alt="Download">search</a>
      <a href="#" class="material-icons mdc-toolbar__icon" aria-label="Auth" alt="Auth">more_vert</a>
    </section>
  </div>
</header>

<!-- hidden initially, shown on clicking the search icon -->
<header class="search-field-phone mdc-toolbar mdc-toolbar--fixed toolbar-light">
  <div class="mdc-toolbar__row">
    <form action="/search" method="get">
      <div class="mdc-text-field mdc-text-field--box mdc-text-field--with-leading-icon autocomplete-search-field">
        <i class="material-icons mdc-text-field__icon" tabindex="0">arrow_back</i>
        <input name="q"
                type="text"
                class="mdc-text-field__input search-input-js aa-input-search"
                placeholder="Search for players and videos ..."
                aria-label="Full-Width Text Field"
                autofocus>
      </div>
    </form>
  </div>
</header>

CSS:

#search-input-icon {
    display: none;
}

@media only screen and (max-width: 782px) {
    #search-input-icon {
      display: block;
    }
}

.search-field-phone {
  visibility: hidden;
}

With js, I just change the classes and visibility of the search field. I am removing the class search-field-phone the heade, that has this property:

  clip-path: circle(0%);
  visibility: hidden;

And adding the class search-field-phone-open that sets the visibility to visible and has the animation:

@keyframes open {
from {
    clip-path: circle(0 at calc(100% - 20%) 50%);
  }
  to {
    clip-path: circle(150% at calc(100% - 20%) 50%);
  }
}

And on clicking the close button I am changing the class to search-field-phone-close that has the animation:

@keyframes close {
  from {
    clip-path: circle(150% at calc(100% - 20%) 50%);
  }
  to {
    clip-path: circle(0 at calc(100% - 20%) 50%);
    visibility: hidden;
  }
}

JS:

let openIcon = document.querySelector('#search-input-open');
let closeIcon = document.querySelector('#search-input-close');
let inputField = document.querySelector('.search-field-phone');
openIcon.addEventListener('click', () => {
    inputField.classList.add('search-field-phone-open');
    inputField.classList.remove('search-field-phone-close', 'search-field-phone');
});
closeIcon.addEventListener('click', () => {
    inputField.classList.add('search-field-phone-close');
    inputField.classList.remove('search-field-phone-open');
});

And this is the css:

.search-field-phone {
  clip-path: circle(0%);
  visibility: hidden;
  .mdc-text-field {
    clip-path: circle(0%);
  }
}

@mixin search-animated-open {
  -webkit-animation: open 2s forwards;
  animation: open 2s forwards;
}

@mixin search-animated-close {
  -webkit-animation: close 2s forwards;
  animation: close 2s forwards;
}

.search-field-phone-open,  {
  visibility: visible;
  overflow: hidden;
  @include search-animated-open;

  .mdc-text-field {
    @include search-animated-open;
  }
}

.search-field-phone-close,  {
  overflow: hidden;
  @include search-animated-close;

  .mdc-text-field {
    @include search-animated-close;
  }
}

@keyframes open {
  from {
    clip-path: circle(0 at calc(100% - 20%) 50%);
  }
  to {
    clip-path: circle(150% at calc(100% - 20%) 50%);
  }
}
@keyframes close {
  from {
    clip-path: circle(150% at calc(100% - 20%) 50%);
  }
  to {
    clip-path: circle(0 at calc(100% - 20%) 50%);
    visibility: hidden;
  }
}

But, I am not sure how can I make it close and open as a proper circle from and to the search icon? This is what I get now:

enter image description here

0 likes
0 replies

Please or to participate in this conversation.