0

I'm trying to scale font sizes to create a fish eye lens effect on hover.

Using CSS to increase the font size with transition causes a jitter effect.

Using transform scale creates an undesirable effect where the left hand side of the text moves over to the left a little before scaling up.

I've created a pen to illustrate the 2 effects side by side. Ideally, I'd like the effect on the left with the smoothness of the right

https://codepen.io/sygad1/pen/QMWqXy

Any ideas to achieve this?

Cheers

HTML

  <ul class="fish-eye-text-size">
    <li>Font size scaling</li>
    <li>Menu item one</li>
    <li>Menu item two</li>
    <li>Menu item three</li>
    <li>Menu item four</li>
    <li>Menu item five</li>
    <li>Menu item six</li>
    <li>Menu item seven</li>
    <li>Menu item eight</li>
    <li>Menu item nine</li>
    <li>Menu item ten</li>
  </ul>

  <ul class="fish-eye-scaling">
    <li>CSS scaling</li>
    <li>Menu item one</li>
    <li>Menu item two</li>
    <li>Menu item three</li>
    <li>Menu item four</li>
    <li>Menu item five</li>
    <li>Menu item six</li>
    <li>Menu item seven</li>
    <li>Menu item eight</li>
    <li>Menu item nine</li>
    <li>Menu item ten</li>
  </ul>

SCSS

//Text size
.mediumText {
  font-size:1.4rem;
}
.largeText {
  font-size:1.7rem;
}



// CSS Scaling
.mediumScale {
  transform: scale(1.3);
  transform-origin: 0% 50%;
}
.largeScale {
  transform: scale(1.5);
  transform-origin: 0% 50%;
}




ul {
  margin:0 auto;
  padding:0;
  list-style:none;
  width:250px;
  overflow:hidden;
  float:left;
  margin:20px;
  background:#e1e1e1;

  li {
    cursor: pointer;
    transition:all 0.4s;
    height:30px;
    position:relative;
    padding:10px;
    will-change: transform;
  } 

}

JS

// Font size
$(".fish-eye-text-size li").on("mouseenter", function() {
  $(this).addClass("largeText");
  $(this).next().addClass("mediumText");
  $(this).prev().addClass("mediumText");
});

$(".fish-eye-text-size li").on("mouseleave", function() {
  $(this).removeClass("largeText");
  $(this).next().removeClass("mediumText");
  $(this).prev().removeClass("mediumText");
});

// CSS Scaling
$(".fish-eye-scaling li").on("mouseenter", function() {
  $(this).addClass("largeScale");
  $(this).next().addClass("mediumScale");
  $(this).prev().addClass("mediumScale");
});

$(".fish-eye-scaling li").on("mouseleave", function() {
  $(this).removeClass("largeScale");
  $(this).next().removeClass("mediumScale");
  $(this).prev().removeClass("mediumScale");
});
sygad1
  • 1,392
  • 3
  • 12
  • 19

1 Answers1

0

In your second example, the transform origin implicitly changes on hover from default 50% 50% to 0% 50%, hence the jittering. You should set transform-origin: 10px 50%; (10px instead of 0 because we aim to fix the position of first letter, not the padding outer edge, so we set the transform origin to the inner edge of the padding area) to the default state of li and remove it from .mediumScale/.largeScale classes.

Ilya Streltsyn
  • 13,076
  • 2
  • 37
  • 57