user753531
user753531

Reputation:

Smoothening CSS transition

Based on a few examples here and there I made one o those search elements in which there's only the icon visible and the text field slides to the right when hovering either the icon or its parent element:

 @import URL( 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css' );

:root {
  --darker-gray: 22, 22, 22;      /** #191919 */
  --mid-gray: 89, 89, 89;       /** #595959 */
}

header .top {
  background-color: rgba( var( --darker-gray ) );

  -webkit-box-shadow: 0 3px 5px -2px #0D0D0D;
          box-shadow: 0 3px 5px -2px #0D0D0D;

  color: rgba( var( --light-text ) );
  padding: 2.5rem;
  position: fixed;
  top: 0;
  width: 100%;
}

.wrapper input {
  background: transparent;
  border: none;
  color: rgba( var( --mid-gray ) );
  cursor: pointer;
  display: inline-block;
  font-size: 2rem;
  height: 3.75rem;
  left: 2.5rem;
  outline: none;
  position: absolute;
  top: 0;
  transition: all .5s;
  width: 0;
  z-index: 3;
}

  .wrapper svg {
    cursor: pointer;
    margin-top: -1.5rem;
    position: relative;
    top: -1px;
  }

  .wrapper:hover input,
  .wrapper:focus input,
  .wrapper:focus-within input {
    border-bottom: 1px solid rgba( var( --mid-gray ) );
    cursor: text;
    width: 24rem;
    z-index: 1;
  }

    .wrapper:hover svg,
    .wrapper:focus svg,
    .wrapper:focus-within svg {
      left: 22rem;
    }

.icon.search {
  fill: rgba(var(--mid-gray));
  height: 2.25rem;
  width: 2.25rem;
}
<header>

  <div class="top">

    <div class="d-flex justify-content-between">
      
      <div class="wrapper">
        <input placeholder="search" type="text" />
        <svg class="icon search button">
          <path d="M9.516 14.016q1.875 0 3.188-1.313t1.313-3.188-1.313-3.188-3.188-1.313-3.188 1.313-1.313 3.188 1.313 3.188 3.188 1.313zM15.516 14.016l4.969 4.969-1.5 1.5-4.969-4.969v-0.797l-0.281-0.281q-1.781 1.547-4.219 1.547-2.719 0-4.617-1.875t-1.898-4.594 1.898-4.617 4.617-1.898 4.594 1.898 1.875 4.617q0 0.984-0.469 2.227t-1.078 1.992l0.281 0.281h0.797z"/>
        </svg>
      </div>
      
    </div>
  </div>
  
</header>

There's some misalignment on the icon but, for some reason, it's just here

Worked nicely but it was too blunt. So I've added a transition transition: all .5s; and it worked perfectly... on the opening. When the text field gets hidden, the grey line goes first, then the placeholder text and finally the SVG icon.

Also, after I've added the transition, on page load the text box flickers for a moment. After a few tests I've found out the culprit is the all defined in the transition tule that's, as expected, is also affecting the background-color required to make the text field transparent.

How could I make it smoother, showing/hiding everything at the same time without this flickering?

Upvotes: 0

Views: 51

Answers (1)

G-Cyrillus
G-Cyrillus

Reputation: 106048

if you also add a transition on SVG and its left coordonates, does it look better to you ?

Also, transition can be set only on a single or more properties alike :

transition: width .5s, z-index 0.5s; to occur only on width and z-index.

@import URL( 'https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.min.css' );

:root {
  --darker-gray: 22, 22, 22;      /** #191919 */
  --mid-gray: 89, 89, 89;       /** #595959 */
}

header .top {
  background-color: rgba( var( --darker-gray ) );

  -webkit-box-shadow: 0 3px 5px -2px #0D0D0D;
          box-shadow: 0 3px 5px -2px #0D0D0D;

  color: rgba( var( --light-text ) );
  padding: 2.5rem;
  position: fixed;
  top: 0;
  width: 100%;
}

.wrapper input {
  background: transparent;
  border: none;
  color: rgba( var( --mid-gray ) );
  cursor: pointer;
  display: inline-block;
  font-size: 2rem;
  height: 3.75rem;
  left: 2.5rem;
  outline: none;
  position: absolute;
  top: 0;
  transition: width .5s, z-index 0.5s;
  width: 0;
  z-index: 3;
}

  .wrapper svg {
    cursor: pointer;
    margin-top: -1.5rem;
    position: relative;
    top: -1px;
    left:0;
    transition:left .5s;
  }

  .wrapper:hover input,
  .wrapper:focus input,
  .wrapper:focus-within input {
    border-bottom: 1px solid rgba( var( --mid-gray ) );
    cursor: text;
    width: 24rem;
    z-index: 1;
  }

    .wrapper:hover svg,
    .wrapper:focus svg,
    .wrapper:focus-within svg {
      left: 22rem;
    }

.icon.search {
  fill: rgba(var(--mid-gray));
  height: 2.25rem;
  width: 2.25rem;
}
<header>

  <div class="top">

    <div class="d-flex justify-content-between">
      
      <div class="wrapper">
        <input placeholder="search" type="text" />
        <svg class="icon search button">
          <path d="M9.516 14.016q1.875 0 3.188-1.313t1.313-3.188-1.313-3.188-3.188-1.313-3.188 1.313-1.313 3.188 1.313 3.188 3.188 1.313zM15.516 14.016l4.969 4.969-1.5 1.5-4.969-4.969v-0.797l-0.281-0.281q-1.781 1.547-4.219 1.547-2.719 0-4.617-1.875t-1.898-4.594 1.898-4.617 4.617-1.898 4.594 1.898 1.875 4.617q0 0.984-0.469 2.227t-1.078 1.992l0.281 0.281h0.797z"/>
        </svg>
      </div>
      
    </div>
  </div>
  
</header>

Upvotes: 0

Related Questions