Reputation: 335
I'm trying to figure out a way to center vertically my SVG Tag.
Basically, here is a simplified SVG code i'm trying to center :
<svg height="272" style="background-color:transparent;margin-left: auto; margin-right: auto;" width="130" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g style="font-size: 0.7em;" transform="scale(1 1) rotate(0) translate(0 270)">
<g id="1" style="font-size: 0.7em;">
<image height="32" width="32" x="49" xlink:href="../../images/JOB.GIF" y="-270"/>
</g>
</g>
</svg>
I have no trouble putting it in the middle (horizontally speaking) of the page, however i'd like it to be vertically centered as well.
I can add wrappers, but i'd like to know a generic way of doing this, not depending on the SVG size nor the window size.
I have tried multiple ways, but nothing worked.
Thanks,
Upvotes: 18
Views: 41132
Reputation: 1379
I updated this answer as current browser have a lot better solution for that.
How wise man said, first year you learn html and css, for another few years you learn advanced javascript and after five years you finally learn how to vertically center div.
to vertically/horizontally align anything in css you can use two main ways:
Absolute
<div class="outside">
<div class="inside">Whatever</div>
</div>
and css:
.outside{
position:relative;
}
.inside{
position:absolute;
top:50%;
bottom:50%;
transform:translate(-50%, -50%);
}
the only issue with that is that element doesn't generate the height.
Flexbox
Flexbox has now pretty good support so why not to use it. https://caniuse.com/#feat=flexbox
Using flexbox your item doesn't need to be absolute so it will generate the height. code:
<div class="outside">
<div>Whatever</div>
</div>
and css:
.outside{
display: flex;
align-items: center;
justify-content: center;
}
Old answer:
you have height and width so u can use margin : auto auto;
or put it in div with
position:absolute ;
left:50% ;
margin-left: -(half of width of image)px;
top:50% ;
margin-top: -(half of height of image)px;
the second one will be better if u will be doing some stuff with it (javascript animation or something)
I didn't check it but maybe u can use second option for svg (without outer div) too
Upvotes: 25
Reputation: 71
You could try using flexbox.
Simple HTML:
<div class="outside">
<svg />
</div>
CSS:
.outside {
display: flex;
align-items: center; /* vertical alignment */
justify-content: center; /* horizontal alignment */
}
HTML with your sample:
<div class="outside">
<svg height="272" style="background-color:transparent;margin-left: auto; margin-right: auto;" width="130" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g style="font-size: 0.7em;" transform="scale(1 1) rotate(0) translate(0 270)">
<g id="1" style="font-size: 0.7em;">
<image height="32" width="32" x="49" xlink:href="../../images/JOB.GIF" y="-270"/>
</g>
</g>
</svg>
</div>
Upvotes: 1
Reputation: 1932
If you provide your svg
element with a viewBox
attribute and set it's width
& height
attributes to 100%
then all should be well (in most browsers..)
$(document).ready(function(){
$(".panel-left").resizable({handleSelector: ".splitter",containment: "parent"});
});
#ctr
{
position: absolute;
border: 1px solid #131313;
top: 5%;
left: 5%;
bottom: 5%;
right: 5%;
display: flex;
flex-direction: row;
}
#ctr svg
{
height: 100%;
width: 100%;
}
.panel-left
{
flex: 0 0 auto;
padding: 10px;
width: 50px;
min-height: 50px;
min-width: 50px;
max-width: 80%;
max-height: 100%;
white-space: nowrap;
background: #131313;
color: white;
}
.splitter
{
flex: 0 0 auto;
width: 18px;
}
.panel-right
{
flex: 1 1 auto;
padding: 10px;
min-width: 20px;
background: #eee;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<div style="visibility:hidden; position:absolute; width:0">
<svg>
<g id="my-funky-svg-defs">
<defs>
<radialGradient id="gradient" cx="25%" cy="25%" r="100%" fx="40%" fy="40%">
<stop offset= "0%" stop-color="hsla(313, 80%, 80%, 1)"/>
<stop offset= "40%" stop-color="hsla(313, 100%, 65%, 1)"/>
<stop offset="110%" stop-color="hsla(313, 100%, 50%, 0.7)"/>
</radialGradient>
</defs>
<title>smarteee</title>
<circle class="face" cx="200" cy="200" r="195" fill="url(#gradient)" />
<ellipse class="eye eye-left" cx="140" cy="150" rx="10" ry="40" fill="#131313"/>
<ellipse class="eye eye-right" cx="260" cy="150" rx="10" ry="40" fill="#131313"/>
<path class="smile" d="M120,280 Q200,330 280,280" stroke-width="10" stroke="#131313" fill="none" stroke-linecap="round"/>
</g>
</svg>
</div>
<div id=ctr>
<div class="panel-left">
<svg viewBox="0 0 400 400"><use xlink:href="#my-funky-svg-defs"></use></svg>
</div>
<div class="splitter">
</div>
<div class="panel-right">
<svg viewBox="0 0 400 400"><use xlink:href="#my-funky-svg-defs"></use></svg>
</div>
</div>
&here's a corresponding jsfiddle to play with
NB: there is also the preserveAspectRatio
attribute that works in conjunction with the viewBox
settings. eg: preserveAspectRatio="xMidYMid meet"
Upvotes: 1
Reputation: 39
It's Simple!
HTML:
<div class="a">
<div class="b">
<div class="c">
<!-- Your SVG Here -->
</div>
</div>
</div>
CSS:
<style>
.a {
display: table;
position: absolute;
height: 100%;
width: 100%;
}
.b {
display: table-cell;
vertical-align: middle;
}
.c {
margin-left: auto;
margin-right: auto;
height: /* Your size in px, else it will expand to your screen size!*/
width: /* Your size in px, else it will expand to your screen size!*/
}
</style>
Upvotes: 3
Reputation: 335
I've finally used some JS code to do so.
I was using the solution from here : Best way to center a <div> on a page vertically and horizontally?
Which is :
div {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
top:0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
But the problem is that if the SVG is bigger than the window size, it gets cropped.
Here is the JS code i've used in onLoad
:
var heightDiff = window.innerHeight - svg.height.baseVal.value;
var widthDiff = window.innerWidth - svg.width.baseVal.value;
if (heightDiff > 0)
svg.style.marginTop = svg.style.marginBottom = heightDiff / 2;
if (widthDiff > 0)
svg.style.marginLeft = svg.style.marginRight = widthDiff / 2;
Upvotes: -2