Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transform Scale Causing Gaps/Lines

Tags:

css

transform

I'm building a website currently and am experiencing issues with transform: scale. I've got a button, and when a user hovers over it, two things happen:

  1. A background "sweeps" in diagonally
  2. The button label colour changes
  3. The button grows slightly

I have got this working, and it looks really nice, but after implementing point 3, I'm seeing a weird gap to the left hand side when the button grows.

Here is my code: click for demo

HTML

<a href="#" class="button">Hover</a>

CSS

body {
    text-align: center;
    padding-top: 10%;
}

.button {
    display: inline-block;
    text-transform: uppercase;
    font-size: 1.1em;
    font-weight: 600;
    background: transparent;
    transition: all ease .25s;
    border: 3px solid green;
    color: green;
    position: relative;
    overflow: hidden;
    z-index: 2;
    font-family: sans-serif;
    padding: 20px 35px;
    text-decoration: none;
}

.button:before {
    content: ' ';
    transition: all ease-out .25s;
    width: 200%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: 0 0;
    z-index: -1;
    transform: skewX(-45deg) translateX(-100%);
    background: green;
}

.button:hover:before {
    transform: translateX(0);
}

.button:hover {
  color: white;
  transform: scale(1.1);
}

And here's a screenshot of the gap I'm seeing. This issue occurs in Chrome and Safari (I haven't tested Firefox or IE as I can't download them at work).

Screenshot of weird gap

like image 393
user373688 Avatar asked Nov 09 '16 09:11

user373688


People also ask

How does CSS scale work?

The scale property in CSS resizes an element's width and height in proportion. So, if we have an element that's 100 pixels square, scaling it up by a value of 2 doubles the dimensions to 200 pixels square. Similarly, a scale value of . 5 decreases the dimensions in half, resulting in 50 pixels square.

What is needed to help determine the scale of an element?

A way to just get the scale values might be to remove any transforms, measure the computed width/height of the element and then add them back and measure again. Then divide new/old values.

How to scale up an element in CSS?

scale() The scale() CSS function defines a transformation that resizes an element on the 2D plane. Because the amount of scaling is defined by a vector, it can resize the horizontal and vertical dimensions at different scales. Its result is a <transform-function> data type.

What is transform CSS?

The transform CSS property lets you rotate, scale, skew, or translate an element. It modifies the coordinate space of the CSS visual formatting model.


1 Answers

It "only" appears in Chrome but not Firefox (edit: worse in Edge: first it's on the left then on bottom...). Not sure if a rounding error or something else is the cause of that gap, but I find that replacing border by a box-shadow improves the rendering.
There's still a gap that can be seen near the end of the transition but finally disappears so I added 2 box-shadows on :hover: the new one is inset and fills the gap between "border/box-shadow" and content box faster.

Codepen: http://codepen.io/PhilippeVay/pen/oYjZzK?editors=0100

body {
    text-align: center;
    padding-top: 10%;
}

.button {
    display: inline-block;
    text-transform: uppercase;
    font-size: 1.1em;
    font-weight: 600;
    background: transparent;
    transition: all ease .25s;
    box-shadow: 0 0 0 3px green; /* replaces border which caused a gap in Chr, not Fx */
    color: green;
    position: relative;
    overflow: hidden;
    z-index: 2;
    font-family: sans-serif;
    padding: 19px 34px;
    text-decoration: none;
}

.button:before {
    content: ' ';
    transition: transform ease-out .25s;
    width: 200%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: 0 0;
    z-index: -1;
    transform: skewX(-45deg) translateX(-100%);
    background: green;
}

.button:hover:before {
    transform: translateX(0);
}

.button:hover {
  color: white;
  box-shadow: 0 0 0 3px green, inset 0 0 0 1px green; /* improves end of transition in Chrome */
  transform: scale(1.1);
}
<a href="#" class="button">Hover</a>

EDIT: playing with the size of the transitioned :pseudo

.button:before {
  content: ' ';
  transition: all ease-out .25s;
  width: calc(200% + 6px);
  height: calc(100% + 6px);
  position: absolute;
  top: -3px;
  left: -3px;
  transform-origin: 0 3px;
  z-index: -1;
  transform: skewX(-45deg) translateX(-100%);
  background: green;
}

to take into account the border but that doesn't change anything because of overflow: hidden.

So here's my third try: by adding a container (or having the A element as a container) and keeping the border on the child element, it makes that gap disappear (overflow is around the border).

Codepen: http://codepen.io/PhilippeVay/pen/ZBbKWd

body {
    text-align: center;
    padding-top: 10%;
}
a {
  display: inline-block;
  overflow: hidden;
    background: transparent;
    transition: all ease .25s;
    color: green;
    position: relative;
    z-index: 2;
    font-family: sans-serif;
    text-decoration: none;
}
a > span {
    display: inline-block;
    text-transform: uppercase;
    font-size: 1.1em;
    font-weight: 600;
    border: 3px solid green;
    padding: 20px 35px;
}

a:before {
    content: ' ';
    transition: all ease-out .25s;
    width: 200%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    transform-origin: 0 0;
    z-index: -1;
    transform: skewX(-45deg) translateX(-100%);
    background: green;
}

a:hover:before {
    transform: translateX(0);
}

a:hover {
  color: white;
  transform: scale(1.1);
}
<a href="#" class="button"><span class="bd">Hover</span></a>

Fx transitions till the end flawlessly... and "corrects" the width by adding 2px on the right. But it's already visible in your jsbin so it's another story (and less annoying I guess as user will have clicked by then imho)

like image 87
FelipeAls Avatar answered Nov 15 '22 05:11

FelipeAls