SVG button affects external div display - html

I am trying to implement the
http://demosthenes.info/blog/760/Create-A-Responsive-Imagemap-With-SVG
to my needs
The problem is that I want the button Ive created to change the style of a div outside the figure tag. I can not find a way to do that.
All I need is by hovering over the .my-1 button, to display the .y1 div
Here is the code so far.
<style type="text/css">
#burj-imagemap {
overflow: hidden;
padding-bottom: 75%;
vertical-align: middle;
width: 100%;
}
#burj-imagemap svg {
display: inline-block;
left: 0;
position: absolute;
top: 0;
}
.my-1:hover {background:#fff; z-index:100; opacity:0.3; filter: alpha(opacity=30); border:1px solid #000;
}
.my-1 {cursor: pointer;}
.y1 {
display: none;
}
.my-1:hover .y1 {
display: block;
background-color: #F00;
height: 250px;
width: 250px;
z-index:1000;
}
</style>
<figure id="burj-imagemap">
<svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 1200 808" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1">
<image xlink:href="http://demosthenes.info/assets/images/burj-khalifa.jpg" height="808" width="1200">
</image>
<a class="my-1" >
<g>
<defs>
<polygon id="SVGID_1_" points="322,131 62,240 79,346 274,250 412,405 501,250"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible"/>
</clipPath>
<g clip-path="url(#SVGID_2_)">
<image overflow="visible" width="1200" height="808" xlink:href="http://demosthenes.info/assets/images/burj-khalifa.jpg" transform="matrix(1 0 0 1 -33.5 -301)">
</image>
</g>
</g></a>
</svg>
</figure>
<div class="y1">Hi!</div>
any ideas?

You could include an event handler in the svg like this..
<g clip-path="url(#SVGID_2_)" onmouseover="document.getElementById('y1').style['display'] = 'inline';">
<div id="y1" class="y1">Hi!</div>
fiddle here http://jsfiddle.net/9mDur/

Related

Stretching one of the three svg in width in a block

I need to stretching one of the three svg in a block. So, first and last svg must be always 100px width and second svg should be 100px, 200px, 1000px, but they must be closed to each other without between space.
HTML
<div class="container">
<svg viewBox="0 0 100 100">
<rect class="st0" width="100px" height="100px"/>
</svg>
<svg viewBox="0 0 500 100" preserveAspectRatio="none">
<rect class="st1" width="500px" height="100px"/>
</svg>
<svg viewBox="0 0 100 100">
<rect class="st2" width="100px" height="100px"/>
</svg>
</div>
CSS
svg {
width: 100px;
height: 100px;
}
svg rect.st2 {
fill: red;
}
svg rect.st1 {
fill: green;
width: 500px;
}
svg rect.st0 {
fill: blue;
}
.container {
display: flex;
}
JSFIDDLE
As the container is flex, you can just add flex-grow:1; to the svg you want to grow:
svg {
width: 100px;
height: 100px;
}
svg rect.st2 {
fill: red;
}
svg rect.st1 {
fill: green;
}
svg rect.st0 {
fill: blue;
}
.container {
display: flex;
}
.container svg:nth-child(2) {flex-grow:1;}
<div class="container">
<svg viewBox="0 0 100 100">
<rect class="st0" width="100px" height="100px"/>
</svg>
<svg viewBox="0 0 500 100" preserveAspectRatio="none">
<rect class="st1" width="500px" height="100px"/>
</svg>
<svg viewBox="0 0 100 100">
<rect class="st2" width="100px" height="100px"/>
</svg>
</div>
If you are wanting set widths of 100, 200 and 1000, then you will need to use media queries and define when you want those widths to be used
Here is some alternative static solution i dont know it helps or not but yes you can control individual svg by css.
.container {
display: flex;
align-items:center;
}
svg {
width: 100%;
height: 100px;
}
svg:nth-child(2) {
width: 1000px;
}
svg rect.st2 {
fill: red;
}
svg rect.st1 {
fill: green;
width: 2000px;
}
svg rect.st0 {
fill: blue;
}
JSFIDDLE

how to style svg element that is duplicated from the <use /> element

I am using the svg <use /> element to duplicate an icon in multiple places:
<svg class="icon icon-BusinessUnit"><use xlink:href="#icon-BusinessUnit"></use></svg>
I would like to be able to control the size of the icon and the color but I do not know how.
Changing the fill, color, width and height of .icon-BusinessUnit does not change anything.
polygon,
rect {
fill: transparent;
stroke: #fff;
stroke-width: 1;
}
g path {
stroke: #fff;
stroke-opacity: 0.6;
}
.icon {
display: inline-block;
width: 1em;
height: 1em;
stroke-width: 0;
stroke: currentColor;
fill: currentColor;
}
/* ==========================================
Single-colored icons can be modified like so:
.icon-name {
font-size: 32px;
color: red;
}
========================================== */
.icon-Activity {
width: 10.2001953125em;
}
.icon-BusinessUnit {
width: 1.2001953125em;
}
.icon-SublevelBusinessFunction {
width: 0.900390625em;
}
.icon-SublevelBusinessUnit {
width: 0.533203125em;
}
html {
font-size: 62.5%;
overflow-y: scroll;
position: relative;
min-height: 100%;
height: 100%;
}
body {
box-sizing: border-box;
font-family: Helvetica, Arial, sans-serif;
line-height: 1;
background: linear-gradient(#348dc5, #00435d);
}
*,
*:before,
*:after {
box-sizing: border-box !important;
}
ul {
padding: 0;
}
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#000000">
<link rel="shortcut icon" href="/favicon.ico">
<title>D3</title>
<style type="text/css">
/* break points */
/* be consistent with spacing to avoid random pixel adding. */
</style>
</head>
<body cz-shortcut-listen="true">
<div id="root">
<div class="gel-wrap">
<div class="gel-layout">
<div class="gel-layout__item ">
<div style="display: inline-block; position: relative; width: 100%; vertical-align: top; overflow: hidden;"><svg preserveAspectRatio="xMinYMin meet" viewBox="0 0 1300 800"><g class="vx-group vx-cluster" transform="translate(100, 100)"><g class="vx-group" transform="translate(0, 0)"><g class="vx-group" transform="translate(490, 0)"><polygon points="25.98076211353316,-14.999999999999998 25.98076211353316,14.999999999999998 1.83697019872103e-15,30 -25.98076211353316,14.999999999999998 -25.980762113533157,-15.000000000000004 -5.510910596163089e-15,-30"></polygon><svg class="icon icon-BusinessUnit"><use xlink:href="#icon-BusinessUnit"></use></svg></g>
</g>
</g>
</svg>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="http://localhost:8088/static/js/main.js"></script>
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-Activity">
<title>Activity</title>
<path fill="#fff" style="fill: var(--color1, #fff)" d="M0 26c0-3.314 2.686-6 6-6 0.176 0 0.352 0.010 0.524 0.024l6.45-10.75c-0.614-0.942-0.974-2.066-0.974-3.276 0-3.314 2.686-6 6-6s6 2.686 6 6c0 1.208-0.358 2.334-0.974 3.276l6.45 10.75c0.172-0.014 0.348-0.024 0.524-0.024 0.134 0 0.266 0.006 0.396 0.014l4.56 2.604c0.658 0.962 1.044 2.128 1.044 3.382 0 3.314-2.686 6-6 6s-6-2.686-6-6c0-1.208 0.358-2.334 0.974-3.276l-6.45-10.75c-0.172 0.014-0.348 0.024-0.524 0.024s-0.352-0.010-0.524-0.024l-6.45 10.75c0.614 0.942 0.974 2.066 0.974 3.274 0 3.314-2.686 6-6 6-3.314 0.002-6-2.684-6-5.998z"></path>
</symbol>
<symbol id="icon-BusinessUnit">
<title>Business Unit</title>
<path fill="#fff" style="fill: var(--color1, #fff)" d="M9.974 30.871h6.519v-6.666h3.918v6.666h6.519v-29.843h-16.955v29.843zM19.641 4.545h3.918v3.918h-3.918v-3.918zM19.641 10.842h3.918v3.918h-3.918v-3.918zM19.641 17.139h3.918v3.918h-3.918v-3.918zM13.344 4.545h3.918v3.918h-3.918v-3.918zM13.344 10.842h3.918v3.918h-3.918v-3.918zM13.344 17.139h3.918v3.918h-3.918v-3.918zM28.451 3.701h8.452v27.17h-5.935v-6.068h-2.517v-21.102zM33.835 21.936h-0v-3.567h-3.567v3.567h3.567zM33.835 16.203h-0v-3.567h-3.567v3.567h3.567zM33.835 10.47h-0v-3.567h-3.567v3.567h3.567zM0 30.871v-27.17h8.452v21.102h-2.517v6.068h-5.935zM3.068 6.903v3.567h3.567v-3.567h-3.567zM3.068 12.636v3.567h3.567v-3.567h-3.567zM3.068 18.369v3.567h3.567v-3.567h-3.567z"></path>
</symbol>
<symbol id="icon-SublevelBusinessFunction">
<title>Sublevel Business Function</title>
<path fill="#fff" style="fill: var(--color1, #fff)" d="M0.96 29.626h10.401v-9.503h6.252v9.503h10.401v-28.666h-27.053v28.666zM16.384 7.715h6.252v6.252h-6.252v-6.252zM6.337 7.715h6.252v6.252h-6.252v-6.252z"></path>
</symbol>
<symbol id="icon-SublevelBusinessUnit">
<title>Sublevel Business Unit</title>
<path fill="#fff" style="fill: var(--color1, #fff)" d="M0.561 30.314h6.318v-6.46h3.797v6.46h6.318v-28.924h-16.433v28.924zM9.93 4.798h3.797v3.797h-3.797v-3.797zM9.93 10.901h3.797v3.797h-3.797v-3.797zM9.93 17.004h3.797v3.797h-3.797v-3.797zM3.827 4.798h3.797v3.797h-3.797v-3.797zM3.827 10.901h3.797v3.797h-3.797v-3.797zM3.827 17.004h3.797v3.797h-3.797v-3.797z"></path>
</symbol>
</defs>
</svg>
</body>
</html>
Your HTML and SVG structure are quite complex so I have simplified it down to the bare minimum. You had hardcoded the fill as #fff on the PATH which made it difficult to affect the fill color of each copy of the symbol. Perhaps you have a good reason to nest SVGs inside other SVGs but as you can see, it's not necessary to achieve your desired result. (I have removed the POLYGON to further simplify the issue.)
This works, hopefully as you intended:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<style>
.d1{
fill: red;
}
.d2{
fill: green;
}
.d3{
fill: orange;
}
</style>
<symbol id="icon-BusinessUnit">
<path d="M9.974 30.871h6.519v-6.666h3.918v6.666h6.519v-29.843h-16.955v29.843zM19.641 4.545h3.918v3.918h-3.918v-3.918zM19.641 10.842h3.918v3.918h-3.918v-3.918zM19.641 17.139h3.918v3.918h-3.918v-3.918zM13.344 4.545h3.918v3.918h-3.918v-3.918zM13.344 10.842h3.918v3.918h-3.918v-3.918zM13.344 17.139h3.918v3.918h-3.918v-3.918zM28.451 3.701h8.452v27.17h-5.935v-6.068h-2.517v-21.102zM33.835 21.936h-0v-3.567h-3.567v3.567h3.567zM33.835 16.203h-0v-3.567h-3.567v3.567h3.567zM33.835 10.47h-0v-3.567h-3.567v3.567h3.567zM0 30.871v-27.17h8.452v21.102h-2.517v6.068h-5.935zM3.068 6.903v3.567h3.567v-3.567h-3.567zM3.068 12.636v3.567h3.567v-3.567h-3.567zM3.068 18.369v3.567h3.567v-3.567h-3.567z"></path>
</symbol>
</defs>
<use xlink:href="#icon-BusinessUnit" class="d1" transform="translate(0 0) scale(1)"/>
<use xlink:href="#icon-BusinessUnit" class="d2" transform="translate(100 0) scale(1.5)"/>
<use xlink:href="#icon-BusinessUnit" class="d3" transform="translate(200 0) scale(2)"/>
</svg>
In future please just abbreviate the code you're providing so that we can focus on the parts which are relevant to your question. And it's always good to include a Codepen / Fiddle or similar, otherwise people may not take the time to set up one for you. See https://codepen.io/MSCAU/pen/KxybQ.

CSS svg hover animation/transition

im using a svg clip-path as mask for an image.
Now i want an inner border inside it on hover.
So i made a second clip-path for hover but the transition doesnt affect it.
I want the border comming from the sides (reducing zoom/negative scaling).
Here you can see what i want without working animation/transition:
body {
background: #ccc;
}
.clip-svg {
position: relative;
display: block;
height: 400px;
width: 300px;
background-position: center center;
background-size: auto 100%;
clip-path: url(#Emblem);
transition: 0.4s all ease;
}
.clip-svg:hover {
clip-path: url(#Emblem2);
}
<div class="clip-svg" style="background-image: url(https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260)"></div>
<svg width="0" height="0">
<defs>
<clipPath id="Emblem">
<path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/>
</clipPath>
<clipPath id="Emblem2">
<path d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3
c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z"/>
<path d="M151,26C87,26,22,37,22,37s0,145,0,203c0,96,117.6,145,117.6,145S279,336,279,240c0-104,0-203,0-203S226,26,151,26z
M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8
c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9
l3.4,0.5V240z"/>
</clipPath>
</defs>
</svg>
<br/>
Image: https://www.pexels.com/...d-tablet-864994/
Thanks in advance
I would consider two layers each one using a clip-path and I would control the opacity:
body {
background: #ccc;
}
.clip-svg {
position: relative;
display: inline-block;
height: 400px;
width: 300px;
}
.clip-svg::before,
.clip-svg::after {
content: "";
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-position: center center;
background-size: auto 100%;
background-image: var(--i);
transition: 0.8s all ease;
}
.clip-svg::before {
clip-path: url(#Emblem2);
}
.clip-svg::after {
clip-path: url(#Emblem);
}
.clip-svg:hover::after {
opacity:0;
}
<div class="clip-svg" style="--i: url(https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260)"></div>
<svg width="0" height="0">
<defs>
<clipPath id="Emblem">
<path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/>
</clipPath>
<clipPath id="Emblem2">
<path d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3
c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z"/>
<path d="M151,26C87,26,22,37,22,37s0,145,0,203c0,96,117.6,145,117.6,145S279,336,279,240c0-104,0-203,0-203S226,26,151,26z
M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8
c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9
l3.4,0.5V240z"/>
</clipPath>
</defs>
</svg>
I don't see a way to achieve what you want using clip paths on an HTML element. You can only replace one clip path with another in CSS. You can't interpolate between two of them.
However it is fairly easy to do, if you are okay with moving the image into an SVG. Then you can do whatever you want with the inner border.
Note however, with this solution, the inner border is not a clip path, so it doesn't make the image transparent. I don't know if that is important to you or not. It should be possible to do that if you really need it to.
body {
background: #ccc;
}
.clip-svg .emblem2-ref {
transform-origin: 150px 200px;
transform: scale(1.2, 1.2);
transition: 0.4s all ease;
}
.clip-svg:hover .emblem2-ref {
transform: scale(1, 1);
}
#Emblem2 {
fill: #ccc;
}
<!-- Clip path and inner border definitions. Can be included once and used by multiple SVGs -->
<svg width="0" height="0">
<defs>
<clipPath id="Emblem">
<path d="M279,240c0,96-139.4,145-139.4,145S22,336,22,240c0-58,0-203,0-203s65-11,129-11c75,0,128,11,128,11S279,136,279,240z"/>
</clipPath>
<path id="Emblem2"
d="M39,51.6V240c0,72.4,80.9,116.6,101.2,126.5c11-4.5,35.7-15.4,59.8-32.3c18.5-13,33.2-26.8,43.6-41.3
c12.2-17,18.4-34.8,18.4-53V51.3C240.8,48,200.9,43,151,43C106.3,43,59.9,48.7,39,51.6z
M270,240c0,19.9-6.7,39.3-19.9,57.7c-10.9,15.1-26.2,29.7-45.5,43.1c-26.2,18.3-52.8,29.8-63.1,33.8l-1.6,0.6l-1.6-0.8
c-10.4-5-37.2-18.9-61.3-41.3c-30.5-28.4-46-59.7-46-93.2V44.7l3.4-0.5C53.5,41.4,103.1,35,151,35c53.2,0,95.3,5.6,115.6,8.9
l3.4,0.5V240z"/>
</defs>
</svg>
<!-- Will need one of these SVGs for every image you want to display -->
<svg width="300" height="400" class="clip-svg">
<g clip-path="url(#Emblem)">
<image width="300" height="400" preserveAspectRatio="xMidYMid slice"
xlink:href="https://images.pexels.com/photos/864994/pexels-photo-864994.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260"/>
<use class="emblem2-ref" xlink:href="#Emblem2"/>
</g>
</svg>
<br/>
Image: https://www.pexels.com/...d-tablet-864994/

SVG fill on text change on hover

I am attempting to animate an SVG on hover, I want the text to change on hover, I am trying this with pure css. Basically you hover on the circle path, and the text path has a css class called that changes its fill.
Here is a fiddle
HTML:
<div class="holder">
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 170.36 170.36">
<defs>
<style>.cls-1{fill:#fff;}.cls-2,.cls-3,.cls-4{fill:#9b00f4;}.cls-3{font-size:56.54px;}.cls-3,.cls-4{font-family:Raleway-Bold, Raleway;font-weight:700;}.cls-4{font-size:48.97px;}</style>
</defs>
<circle class="circle-1" cx="960.15" cy="540.18" r="83.18" transform="translate(-1008.6 -46.45) rotate(-22.5)"/>
<path class="cls-2" d="M960.15,459A81.18,81.18,0,1,1,879,540.18,81.28,81.28,0,0,1,960.15,459m0-4a85.18,85.18,0,1,0,85.18,85.18A85.18,85.18,0,0,0,960.15,455Z" transform="translate(-874.97 -455)"/>
<text class="cls-3 main-text" transform="translate(73.19 99.05)">1</text>
<text class="cls-4 alt-text" transform="translate(70.67 94.69) rotate(0.08)">2</text>
</svg>
</div>
CSS:
.holder{
width: 300px;
height: 300px;
}
.circle-1{
fill:white;
}
.circle-1:hover{
fill:purple;
}
.main-text{
display: block;
}
.alt-text{
display:none;
}
/* Doesn't work */
.circle-1:hover .main-text{
display:none;
}
.circle-1:hover .alt-text{
display:block;
}
.circle-1 is a not a parent for the text elements but a sibling, so you need to use the sibling selector ~
.holder{
width: 300px;
height: 300px;
}
.circle-1{
fill:white;
}
.circle-1:hover{
fill:purple;
}
.main-text{
display: block;
}
.alt-text{
display:none;
}
.circle-1:hover ~ .main-text{
display:none;
}
.circle-1:hover ~ .alt-text{
display:block;
}
<div class="holder">
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 170.36 170.36">
<defs>
<style>.cls-1{fill:#fff;}.cls-2,.cls-3,.cls-4{fill:#9b00f4;}.cls-3{font-size:56.54px;}.cls-3,.cls-4{font-family:Raleway-Bold, Raleway;font-weight:700;}.cls-4{font-size:48.97px;}</style>
</defs>
<circle class="circle-1" cx="960.15" cy="540.18" r="83.18" transform="translate(-1008.6 -46.45) rotate(-22.5)"/>
<path class="cls-2" d="M960.15,459A81.18,81.18,0,1,1,879,540.18,81.28,81.28,0,0,1,960.15,459m0-4a85.18,85.18,0,1,0,85.18,85.18A85.18,85.18,0,0,0,960.15,455Z" transform="translate(-874.97 -455)"/>
<text class="cls-3 main-text" transform="translate(73.19 99.05)">1</text>
<text class="cls-4 alt-text" transform="translate(70.67 94.69) rotate(0.08)">2</text>
</svg>
</div>

Extra vertical space on SVG

I have a 16x16px SVG with 10px of padding and 1px border and for some reason, the height is 40px instead of 38px, like the width (on my local site, it's actually 36.95x44px). What can I do to eliminate this extra space and achieve a perfect square?
.layout-toggle {
display: inline-block;
padding: 10px;
border: 1px solid grey;
}
.layout-toggle.layout-active {
background-color: black;
}
.layout-toggle.layout-active svg {
fill: white;
width: 1em;
height: 1em;
}
.layout-toggle .layout-icon {
width: 1em;
height: 1em;
vertical-align: middle;
}
<a href="#">
<div class="layout-toggle">
<svg class="layout-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" viewbox="0 0 17 16" style="enable-background:new 0 0 17 16;" xml:space="preserve">
<g>
<g>
<g id="calendar-view-01">
<g>
<g id="Calender-Layout-Icon_no-border-1">
<path d="M0.3,0h4v4h-4V0z M0.3,6h4v4h-4V6z M0.3,12h4v4h-4V12z M6.3,0h4v4h-4V0z M6.3,6h4v4h-4V6z M6.3,12h4v4h-4
V12z M12.3,0h4v4h-4V0L12.3,0z M12.3,6h4v4h-4V6L12.3,6z M12.3,12h4v4h-4V12L12.3,12z" />
</g>
</g>
</g>
</g>
</g>
</svg>
</div>
</a>
http://codepen.io/ourcore/pen/rjLmRM
That is because your <svg> element is displayed inline by default. If you explicitly declare display: block on the element, the height will compute correctly.
When inline display is active, the element will often have "uncontrollable" height due to the fact that:
you cannot explicitly dictate vertical dimensions—be it margin, padding, height—on inline elements, resulting in unpredictable dimensions and
the element's vertical height is influenced by line height inherited from the text node.
.layout-toggle {
display: inline-block;
padding: 10px;
border: 1px solid grey;
}
.layout-toggle.layout-active {
background-color: black;
}
.layout-toggle.layout-active svg {
fill: white;
width: 1em;
height: 1em;
}
.layout-toggle .layout-icon {
display: block; /* Use display: block to force proper height */
width: 1em;
height: 1em;
vertical-align: middle;
}
<a href="#">
<div class="layout-toggle">
<svg class="layout-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16px" viewbox="0 0 17 16" style="enable-background:new 0 0 17 16;" xml:space="preserve">
<g>
<g>
<g id="calendar-view-01">
<g>
<g id="Calender-Layout-Icon_no-border-1">
<path d="M0.3,0h4v4h-4V0z M0.3,6h4v4h-4V6z M0.3,12h4v4h-4V12z M6.3,0h4v4h-4V0z M6.3,6h4v4h-4V6z M6.3,12h4v4h-4
V12z M12.3,0h4v4h-4V0L12.3,0z M12.3,6h4v4h-4V6L12.3,6z M12.3,12h4v4h-4V12L12.3,12z" />
</g>
</g>
</g>
</g>
</g>
</svg>
</div>
</a>