I would like to display an svg image inside a block of fixed size. I would like to show the image undistorted and as large as possible within the block. My problem is that the image is supplied by the user, so I do not know its dimensions. Is there any way to do this with CSS only?
No you cannot do this using CSS only. The attributes that tell the browser how to scale an SVG to fill its parent container are defined in the SVG itself. There are four attributes in particular that control the scaling:
width
height
viewBox
preserveAspectRatio
The first two can be overridden with CSS, but the last two cannot. If you have no control over the SVG, then you can't guarantee that it has a viewBox or preserveAspectRatio.
You could, however, manipulate the viewBox and preserveAspectRatio attributes with Javascript.
Related
I have a problem with sizing of SVG image when I use fragments.
When I set background-size: cover the image does not covers available space in the container.
Here is a demo.
Is it possible to use SVG fragments and be able to use contain and cover in background-size with proper behaviour?
The issue is that you're not specifying the width and height of the parent SVG. Chrome has a bug that requires height and width to be specified for fragments to handle img related CSS techniques, not sure what the source of the info was but CSS Tricks documented it here. I think the height and width only needs to be specified in the parent SVG where the use tag is.
You can see here that setting the height and width for the svg tag in sprite.svg gives uniform behavior between both versions.
https://codesandbox.io/s/svg-fragment-background-position-problem-i75l3?fontsize=14&hidenavigation=1&theme=dark
I have a nice background SVG image from inkscape which marks the transition from one text section to the next. I want that background image to scale up or down to the full width of the text section. For reasons of responsivity, that size depends on the browser width. However, I want that background image to have a fixed height of 20px.
What does not work:
background-size: cover;
That does not work for me because it will cut the image off at the right instead of scaling it down, okay.
background-size: contain
That does not work for me because it will always scale the image down in x and y direction simultaneously. As a result, the image always retains its original x-y-ratio, okay.
combining cover and contain
That is not possible for syntactical reasons, okay.
background-size: 100% 20px;
or background-size: auto 20px
That does not work, even though I would have expected it to. I tried it with a PNG and it worked. But with the SVG, the width is being adjusted correctly and the height is then also being adjusted so that the image does retain its original ration, which I do not want it to. However, I wish to use an SVG because it's a relatively simple image and I want it in the best resolution on all devices, including the really big screens, without using a huge PNG image.
As the problem seems to be SVG-specific, I opened the SVG in a text editor and inserted into the tag the attribute and value preserveAspectRatio="none". As it did still not work I also tried removing the width and height and viewBox specifications in the SVG tag. No success.
So I tried around and found a possibility:
in Inkscape or in a text editor, set the following viewBox according to the size of your image – so if your image is 100*20px set it like this: viewBox="0 0 100 20"
in a text editor, add preserveAspectRatio="none" to the SVG tag
also, in the SVG tag set the height and width in percents: width="100%" height="100%"
in the CSS markup, then simply use background-size: 100% 20px;
With these steps it is possible to scale the background SVG using CSS in the same way that one would scale any bitmap image.
SVG vectors are rendered differently than static images. They are traced live on the browser. This is what makes them great for web use as they can scale in size without losing quality. Because of this css is unable to alter the rendering in a way that would distort it. If using svg is a strict requirement and assuming you expect dynamic widths then you could split it in multiple sections and have them distributed horizontally giving you the effect you are looking for if your width is static then just edit it on any online svg editor or Illustrator.
FYI this might be a duplicate question:
How does one make a SVG background that stretches rather than tiles?
I'd like to create a scale with stars\flowers\whatever that will enable me to graphically present a fraction, in case of average grade (say 4.35). Is there a way to partially fill an empty non-rectangular image using CSS?
TIA, Matanya
If you are okay with using a div instead of an img for the image, you could set the image as a background in the div element, and calculate the width of the div, depending on how much of the image you want to show.
The calculation would have to be done through JavaScript, or server-side and then added inline on the div element, though.
Is the background-position css property used to indicated where in the element should the image be displayed (like this) or what part of the image should be displayed (like when using sprites) ?
In my instance i have a div of let's say 300px width, i want the image to be shown in the right part of that element so normally i just added a center right to my background declaration, though now my image is a spirit so how can i control the coordinate of the image that i want to display ?
Seems to me that this background property act in 2 different way.. Am i missing something ?
If the place where you want to put element of the sprite is larger then the element then you need to put white space (trasnparent) around it. And you can't use keywords like center, you need to use pixels, because you will center whole sprite and not your element.
Using sprites is like using window where background is larger then background image so you need to position the window (actually you position the background).
If your container is larger than the background sprite image part you want to display then the other part of image will also be displayed. Better use Sprite cow to generate sprite it will give you the css for different parts of sprite image
http://www.spritecow.com/
I am using the awesome compass style to generate sprites for my style sheets. I can generate sprites and use them as backgrounds, which is all working fine.
The problem is that previously I have used background-position to position my backgrounds within an element.
For example here's one:
background: left bottom url('../images/bottom-bg.png) no-repeat;
The height of the containing element is variable, and this places the background on the bottom and works beautifully.
However, if I switch to compass sprites and use #extend .system-bottom-bg;, the background-position property is used to grab the appropriate position of the image from the sprite map.
In such a case, how can I use css sprites and still be able to position the background on the bottom of an element?
Upon further research, it seems that due to the limitations of background-position, this is not possible. A decent list of shortfalls with CSS sprites is outlined here: http://www.onderhond.com/blog/work/css-sprites-pros-and-cons.
As background-position is used to to define the position an image occupies in a sprite sheet, we can't use it to define how that portion of the sprite sheet will appear on the page. The article linked above offers some solutions that may be implemented in the future.
One possible solution is to put the image as the last item in the sprite sheet, and then insert a huge amount of space between this image and the previous image. Obviously this is not a very neat solution, but given that compass does not allow us to set the position of images within a sprite sheet, this is not possible anyway.
My solution was to change my markup so that setting background-position: left bottom is not required, and I can just set the sprite image as the background image.