Scale element in X and Y by the same amount of pixels
If the dimensions are unknown, you can't use CSS. In this case, only JavaScript can do that.
To do that in JavaScript, first grab the dimension of the element, and then add or subtract a value dynamically.
Scale element to pixel size
If you have access to the html for the svg, you can remove the svg element's width and height attributes and replace them with a viewBox
attribute of the with the x/y positions set to 0, and the width/height pair set to the values you deleted:
<svg width="300" height="200">
<!-- change to: -->
<svg viewBox="0 0 300 200">
You can then place the svg element inside a sized div and set the css width and height of the svg to 100%:
.svgContainer svg {
width: 100%;
height: 100%;
}
See working snippet to compare effects, I've squeezed the same svg into a smaller div, with and without the viewBox
set.
Note for a dynamic resize, the div container has to resize dynamically, the viewBox
version of the svg set to 100% width and height of the container will take care of itself. If the container Div had been sized by % instead of pixels, it will grow and shrink with the viewport of the browser.
If you can't access the html markup, you could achieve the same by retrieving the width
and height
attributes of the svg using javascript and set a new attribute for the viewBox
.
More about viewBox
: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox
.svgContainer {
width: 100px;
}
.svgContainer svg {
margin: 0;
width: 100%;
height: 100%;
}
<p> 300x200 svg rendered outside of a container:</p>
<svg width="300px" height="200px">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="blue"/>
<rect x="100" y="50" width="100" height="50" fill="yellow"/>
<rect x="30" y="20" width="20" height="35" fill="blue"/>
</svg>
<p> same 300x200 svg rendered inside sized div:</p>
<div class="svgContainer">
<svg width="300px" height="200px">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="blue"/>
<rect x="100" y="50" width="100" height="50" fill="yellow"/>
<rect x="30" y="20" width="20" height="35" fill="blue"/>
</svg>
</div>
<p>svg modified to use viewbox attribute values, inside sized div</p>
<div class="svgContainer">
<svg viewBox="0 0 300 200">
<rect x="0" y="0" width="100%" height="100%" fill="red" stroke="blue"/>
<rect x="100" y="50" width="100" height="50" fill="yellow"/>
<rect x="30" y="20" width="20" height="35" fill="blue"/>
</svg>
</div>
How to convert scaling from SVG units to pixels using scale formula?
I think I get what you are saying, but your formulas don't seem to make sense.
1.1 = 15px -> therefore, the width would be 135px increasing to 150px
and the height would be 120px increasing to 135px
That "15px" seems wrong. 1.1 * 135 = 148.5
, not 150
.
What I think you are asking is how to calculate the scale that would make the width become 150. Is that right?
The scale that will get the width to exactly 150 can be calculated like this:
new_width 150
scale = ----------- = ----- = 1.1111...
old_width 135
So checking that: 135 * 1.1111... = 150.0
.
And the new height using this scale would be: 120 * 1.1111... = 133.333...
CSS Transform with element resizing
The problem I noticed is that when element scales, browser change its pixels ratio, not pixels amount. Element is smaller but it doesn't change its actual pixel size in DOM. Because of that I don't think that CSS-only solution exist.
I put scalable element into container which keeps the same pixel ratio as rest of elements. Using Java Script I simply change container's size. Everything is still based on CSS3 transform: scale. Maybe JS code could be simplier, but now it's all about the idea (just a proof of concept);) Fiddle with two examples: http://jsfiddle.net/qA5Tb/9/
HTML:
<div class="overall-scalable">
<div class="scalable" scalex='0.5' scaley='0.5'>
Nunc et nisi ante. Integer in blandit nisi. Nulla facilisi. Vestibulum vulputate sapien eget mauris elementum sollicitudin. Nullam id lobortis dolor. Nulla vitae nibh vitae sem volutpat pretium. Nunc et nisi ante. Integer in blandit nisi. Nulla facilisi. Vestibulum vulputate sapien eget mauris elementum sollicitudin. Nullam id lobortis dolor. Nulla vitae nibh vitae sem volutpat pretium.
</div>
</div>
CSS:
.overall-scalable {width: 350px; height: 150px; overflow: hidden; -webkit-transition: all 1s;}
.scalable {color: #666; width: 350px; height: 150px; -webkit-transform-origin: top left; -webkit-transition: all 1s;}
JS:
$('button').click(function() {
$('.scalable').each(function(){
rescale($(this));
})
});
function rescale(elem) {
var height = parseInt(elem.css('height'));
var width = parseInt(elem.css('width'));
var scalex = parseFloat(elem.attr('scalex'));
var scaley = parseFloat(elem.attr('scaley'));
if (!elem.hasClass('rescaled')){
var ratioX = scalex;
var ratioY = scaley;
}else{
var ratioX = 1;
var ratioY = 1;
}
elem.toggleClass('rescaled');
elem.css('-webkit-transform', 'scale('+ratioX +', '+ratioY+')');
elem.parent().css('width', parseInt(width*ratioX) + 'px');
elem.parent().css('height', parseInt(height*ratioY) + 'px');
}
Related Topics
How to Imitate the Look of the Outline and Label from Material-Ui's Outlined Textfield
Google Fonts: Define Custom Name in CSS
How to Get Perfect Border Radius on Images in All Browsers
Border-Radius: 50% Not Producing Perfect Circles in Chrome
Stop PHPstorm File Watchers Running Recursively (With Autoprefixer)
Selector for All a Tag Descendants
Element Opacity But Not Border
How to Layer Box-Shadows Using Z-Index
Safari Page-Break-Inside:Avoid Not Working
Style Type="Text/Css" ... What Else Is There
Article Push/Pull Alignment Using Bootstrap 3
What Is the Math Behind -Webkit-Perspective
Css3: Two Transitions with Different Timing Functions (Css3)
Can't Use the Same Animation in Reverse for Class Toggle
What Is Appropriate Ordering of CSS Selector? Eg P.Class or .Class P
IE8 Doesn't Zoom Content When Applying a CSS Zoom Value to a Div
Perfect 100% Width of Parent Container for a Bootstrap Input