WHAT BREAKING INTERFACES TAUGHT ME ABOUT BUILDINg BETTER INTERFACES

@HAKIMEL

1

2

Hover MENUS

👆😑

Timeout?

const button = document.querySelector( '.button' ).getBBox();
const menu = document.querySelector( '.menu' ).getBBox();

document.querySelector( 'path' ).setAttribute( 'd', `
  M ${button.x} ${button.y}
  Q ${menu.x} ${button.y},
    ${menu.x} ${menu.y}
  v ${menu.height}
  Q ${menu.x} ${button.y + button.height},
    ${button.x} ${button.y + button.height}
  h ${button.width}
  v ${-button.height}
  z` );
<svg width="300" height="200">
  <rect class="button" fill="#ddd" y="85" width="100" height="30" />
  <rect class="menu" fill="#ddd" x="140" width="120" height="200" />
  <path fill="#00ff00" />
</svg>
svg  { pointer-events: none; }

path { pointer-events: auto; }

Scroll
Shadows

BINARY

DYNAMIC

<div class="wrapper">
  <ul class="content">
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    ...
  </ul>
</div>
.wrapper {
  position: relative;
  width: min-content;
}

.content {
  overflow: auto;
  width: 200px;
  height: 300px;
}
.wrapper:before,
.wrapper:after {
  content: '';
  position: absolute;
  height: 10%;
  width: 100%;
}

.wrapper:before {
  top: 0;
  background: linear-gradient(to bottom, rgba(0,0,0,0.4), transparent);
  opacity: var(--scroll-progress, 0);
}

.wrapper:after {
  bottom: 0;
  background: linear-gradient(to top, rgba(0,0,0,0.4), transparent);
  opacity: calc(1 - var(--scroll-progress, 0));
}
const wrapper = document.querySelector( '.wrapper' );
const content = document.querySelector( '.content' );

content.addEventListener( 'scroll', event => {
  let scrollRange = content.scrollHeight - content.clientHeight;
  let scrollProgress = content.scrollTop / scrollRange;
  wrapper.style.setProperty( '--scroll-progress', scrollProgress );
} );

scrollHeight

scrollTop

clientHeight

Transform Anchors

🤬

😦

🥳

hakim.se

@hakimel

Thanks!