-
  var items = [
    { title: 'X-rays', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-xrays.png' },
    { title: 'Worms', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-worms.png' },
    { title: 'Aurora', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-aurora.png' },
    { title: 'Angus', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-angus.png' },
    { title: 'Huitzi', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-huitzi.png' },
    { title: 'Dalí', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-dali.png' },
    { title: 'The Bride', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-bride.png' },
    { title: 'The Man', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-man.png' },
    { title: 'D', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-d.png' },
    { title: 'V', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-v.png' },
    { title: 'V II', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-v2.png' },
    { title: 'V III', src: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/i-v3.png' }
  ];

h1.intro [CSS+JS] clip hover effect

ul.items
  each item in items
    li.item
      figure.figure
        img.figure__img(src=item.src, title=item.title)
        .figure__mask
        figcaption.figure__figcaption= item.title

blockquote.info
  | inspired from #[a(href="https://codepen.io/noeldelgado/") Noel Delgado]'s Pen #[a(href="https://codepen.io/noeldelgado/pen/PZJGLx/") SVG clip-path Hover Effect].
View Compiled
$text-color: #f5f5f5;
$mask-bgc: #3b3e46;
$mask-size: 800px;
$hole-size: 300px;
$img-size: 300px 200px;

@import "https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600";

.items {
  max-width: 1200px;
  margin: 0 auto;
  padding-left: 0;
  font-family: 'Source Sans Pro', sans-serif;
  font-weight: 900;
  text-transform: uppercase;
  font-size: 14px;
  letter-spacing: 1px;
}

.item {
  display: inline-block;
}

.figure {
  position: relative;
  width: nth($img-size, 1);
  height: nth($img-size, 2);
  overflow: hidden;
  margin: 5px;

  // fake border-radius for fixing (overflow: hidden + transform) bug
  &::after {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    border-radius: 3px;
    box-shadow: 0 0 0 5px #2f3238;
    pointer-events: none;
  }
}

.figure__img {
  width: nth($img-size, 1);
  height: nth($img-size, 2);
  transform: scale(1.1);
  transition: transform .3s;
  pointer-events: none;

  .item:hover & {
    transform: scale(1);
  }
}

.figure__figcaption {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  transform: translateY(-50%);
  opacity: .2;
  pointer-events: none;
  transition: opacity .15s;

  .item:hover & {
    opacity: 1;
  }
}

.figure__mask {
  position: absolute;
  top: - $mask-size / 2;
  left: - $mask-size / 2;
  width: $mask-size;
  height: $mask-size;
  color: $mask-bgc;
  border-radius: 50%;
  box-shadow: inset 0 0 0 400px;
  transition: box-shadow .3s;
  pointer-events: none;

  .item:hover & {
    box-shadow: inset 0 0 0 ($mask-size - $hole-size)*.5;
  }
}

// reset style

*,
*::before,
*::after {
  box-sizing: border-box;
}

body {
  position: relative;
  margin: 0;
  min-height: 100vh;
  padding-top: 1px;
  padding-bottom: 5rem;
  text-align: center;
  background-color: #2f3238;
  color: $text-color;
}

.intro {
  width: 80%;
  max-width: 30rem;
  padding-bottom: 1rem;
  margin: .5em auto 1em;
  text-transform: capitalize;
  border-bottom: 1px dashed rgba($text-color, .3);

  small {
    display: block;
    opacity: .5;
    font-style: italic;
    text-transform: none;
  }
}

.info {
  position: absolute;
  bottom: 0;
  right: 0;
  margin: 1em;
  font-size: .9em;
  font-style: italic;
  font-family: serif;
  text-align: right;
  opacity: .5;

  a {
    color: inherit;
  }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  border: 0;
}
View Compiled
let items = document.getElementsByClassName('item');
let masks = document.getElementsByClassName('figure__mask');

let calcTouchPos = ($pos, $item, $i) => {
  let rect = $item.rect;
  let x = ~~Math.min(Math.max($pos.clientX - rect.left, 0), 300);
  let y = ~~Math.min(Math.max($pos.clientY - rect.top, 0), 200);
  masks[$i].style.transform = `translate(${x}px, ${y}px)`;
};

let isSupportTouch = 'ontouchstart' in window;

[].forEach.call(items, (item, i) => {
  item.addEventListener('mousemove', (e) => {
    masks[i].style.transform = `translate(${e.offsetX}px, ${e.offsetY}px)`;
  }, false);

  if (isSupportTouch) {
    item.addEventListener('touchstart', (e) => {
      let pos = e.targetTouches[0];
      let target = document.elementFromPoint(pos.clientX, pos.clientY);
      item.rect = target.getBoundingClientRect();
    });

    item.addEventListener('touchmove', (e) => {
      e.preventDefault();
      calcTouchPos(e.targetTouches[0], item, i);
    });
  }
});
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.