Sam Loya
Sam Loya

Reputation: 85

SVG line animation 2

How to change the heigh of this SVG to 24px and get it work correctly on :hover?

HTML:

<div class="sv_btn">
  <svg width="100" height="100">
    <line class="top" x1="0" y1="0" x2="600" y2="0" />
    <line class="left" x1="0" y1="100" x2="0" y2="-200" />
    <line class="bottom" x1="100" y1="100" x2="-200" y2="100" />
    <line class="right" x1="100" y1="0" x2="100" y2="600" />
  </svg>
</div>

CSS:

.sv_btn {
  position: relative;
  width: 100px;
  height: 100px;
  margin: 200px;
}    
.sv_btn svg {
  position: absolute;
  top: 0;
  left: 0;
}
.sv_btn line {
  stroke-width: 5;
  stroke: #000;
  fill: none;
  stroke-dasharray: 100px;
  transition: transform .6s;
}
.sv_btn:hover svg line.top {
  transform: translateX(-200px);
}
.sv_btn:hover svg line.bottom {
  transform: translateX(200px);
}
.sv_btn:hover svg line.left {
  transform: translateY(200px);
}
.sv_btn:hover svg line.right {
  transform: translateY(-200px);
}

Demo: http://codepen.io/anon/pen/KdPEvr

Upvotes: 0

Views: 844

Answers (1)

Paul LeBeau
Paul LeBeau

Reputation: 101956

The simplest way is to change the first line of your SVG as follows:

 <svg width="100%" height="100%" viewBox="0 0 100 100">

Then the SVG will scale to the size of your <div>. So all you then need to do is style the div to 24px:

.sv_btn {
  position: relative;
  width: 24px;
  height: 24px;
  margin: 200px;
}

.sv_btn {
  position: relative;
  width: 24px;
  height: 24px;
  margin: 200px;
}

.sv_btn .text {
  width: 100%;
  height: 100%;
  text-align: center;
  position: absolute;
  display: flex;
  justify-content: center;
  flex-direction: column;
  font-size: 16px;
  color: whitesmoke;
}

.sv_btn svg {
  position: absolute;
  top: 0;
  left: 0;
}

.sv_btn line {
  stroke-width: 5;
  stroke: #000;
  fill: none;
  stroke-dasharray: 100px;
  transition: transform .6s;
}

.sv_btn:hover svg line.top {
  transform: translateX(-200px);
}

.sv_btn:hover svg line.bottom {
  transform: translateX(200px);
}

.sv_btn:hover svg line.left {
  transform: translateY(200px);
}

.sv_btn:hover svg line.right {
  transform: translateY(-200px);
}
<div class="sv_btn">
  <svg width="100%" height="100%" viewBox="0 0 100 100">
    <line class="top" x1="0" y1="0" x2="600" y2="0" />
    <line class="left" x1="0" y1="100" x2="0" y2="-200" />
    <line class="bottom" x1="100" y1="100" x2="-200" y2="100" />
    <line class="right" x1="100" y1="0" x2="100" y2="600" />
  </svg>
</div>

Update

To change just the height to 24px, and have it squeeze to fit, add preserveAspectRatio="none". In addition, you probably want to add vector-effect="non-scaling-stroke" to the paths, so that the stroke widths of the lines don't get squeezed also.

  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none" vector-effect="non-scaling-stroke">

.sv_btn {
  position: relative;
  width: 100px;
  height: 24px;
  margin: 200px;
}

.sv_btn .text {
  width: 100%;
  height: 100%;
  text-align: center;
  position: absolute;
  display: flex;
  justify-content: center;
  flex-direction: column;
  font-size: 16px;
  color: whitesmoke;
}

.sv_btn svg {
  position: absolute;
  top: 0;
  left: 0;
}

.sv_btn line {
  stroke-width: 5;
  stroke: #000;
  fill: none;
  stroke-dasharray: 100px;
  transition: transform .6s;
}

.sv_btn:hover svg line.top {
  transform: translateX(-200px);
}

.sv_btn:hover svg line.bottom {
  transform: translateX(200px);
}

.sv_btn:hover svg line.left {
  transform: translateY(200px);
}

.sv_btn:hover svg line.right {
  transform: translateY(-200px);
}
<div class="sv_btn">
  <svg width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
    <line class="top" x1="0" y1="0" x2="600" y2="0" vector-effect="non-scaling-stroke" />
    <line class="left" x1="0" y1="100" x2="0" y2="-200" vector-effect="non-scaling-stroke" />
    <line class="bottom" x1="100" y1="100" x2="-200" y2="100" vector-effect="non-scaling-stroke" />
    <line class="right" x1="100" y1="0" x2="100" y2="600" vector-effect="non-scaling-stroke" />
  </svg>
</div>

However that stretchy scale will affect the line widths, meaning the verticcal lines are now fatter than the horizontal ones.

Update 2

If you don't want to use the rescale approach, you can change the SVG by manually resizing the vertical sides of the rectangle, and rejigging some of the CSS.

.sv_btn {
  position: relative;
  width: 100px;
  height: 24px;
  margin: 200px;
}

.sv_btn .text {
  width: 100%;
  height: 100%;
  text-align: center;
  position: absolute;
  display: flex;
  justify-content: center;
  flex-direction: column;
  font-size: 16px;
  color: whitesmoke;
}

.sv_btn svg {
  position: absolute;
  top: 0;
  left: 0;
}

.sv_btn line {
  stroke-width: 5;
  stroke: #000;
  fill: none;
  transition: transform .6s;
}

.sv_btn svg line.top,
.sv_btn:hover svg line.bottom {
  stroke-dasharray: 100px;
}

.sv_btn:hover svg line.top {
  transform: translateX(-200px);
}

.sv_btn:hover svg line.bottom {
  transform: translateX(200px);
}

.sv_btn svg line.left,
.sv_btn svg line.right {
  stroke-dasharray: 24px;
}

.sv_btn:hover svg line.left {
  stroke-dasharray: 24px;
  transform: translateY(48px);
}

.sv_btn:hover svg line.right {
  stroke-dasharray: 24px;
  transform: translateY(-48px);
}
<div class="sv_btn">
  <svg width="100" height="24">
    <line class="top" x1="0" y1="0" x2="600" y2="0" />
    <line class="left" x1="0" y1="24" x2="0" y2="-48" />
    <line class="bottom" x1="100" y1="24" x2="-200" y2="24" />
    <line class="right" x1="100" y1="0" x2="100" y2="144" />
  </svg>
</div>

Upvotes: 1

Related Questions