Embedded SVG (with fallback) without using jQuery - css

I need a way to 1) embed an SVG with a PNG fallback, and 2) use CSS in an external stylesheet to style colors on certain parts of the SVG while 3) without using jQuery.
Background:
At work we link to the same resources on our servers across multiple websites, so this way if we have an update to the resource we don't have to individually update it on 20 sites. An external stylesheet is used so we can make the resource (in this case the SVG) mimic the theme of whatever website we place it on.
My Solution:
I originally did it with jQuery but then was told by my boss that we need a plain JS solution since he doesn't want to have to load jQuery on some of the old sites we have (this sounds silly to me, but I'm not the boss).
My original solution used:
http://www.noupe.com/tutorial/svg-clickable-71346.html (solution 3a.) for the SVG fallback, and
How to change color of SVG image using CSS (jQuery SVG image replacement)? for embedding an SVG.
<a href="link-to-another-page" >
<img class="svg" src="awesome.svg" alt="An awesome SVG" width="186" height="235" onerror="this.removeAttribute('onerror'); this.src='not-as-awesome.png'" />
</a>
<!--followed by the jQuery code in item #2-->
It works great, but uses jQuery. I am a JS beginner, so trying to convert the jQuery code over to regular JS has proved too confusing for me.
Any suggestions would be helpful, but like I said, this needs to:
Be clickable
Not use jQuery
Allow for SVG styling in an external stylesheet

I would suggest you remove your <img/> tag completely and use some tag with background image instead
for example you could use some your link instead:
<style>
.logo {
display: inline-block;
width: 400px;
height: 200px;
background-color: #some-color;
background-image: url('url.png');
background-image: url('url.svg'); //browsers that not support svg should ignore it completely and .png background would be applied and modern browsers would reassign background image
}
</style>
<a class="logo" href=""></a>
another method would be to embed svg directly since it's no problem in html5:
<style>
​svg {
background: #f7f7f7;
border: 1px solid #efefef;
}
​.logo {
display:inline-block;
width: 400px;
height: 200px;
background: yellow url('some iamge url here');
}​
</style>
<a class="logo" href="">
<svg xmlns="http://www.w3.org/2000/svg"
version="1.1" baseProfile="full"
width="100%" height="100%" viewBox="0 0 700 400">
<rect x="100" y="100" width="500" height="200" fill="white" stroke="black" stroke-width="20px"/>
</svg>
</a>​
the good thing is that html5 has no issues applying display: block to link elements i think there shouldn't be any with inline-block and since you wanted to wrap your logo with a link tag it should be perfect solution even ie7 has no problems applying display: block with link elements like with any other inline elements. I prefer the first method since it has better browser support you can check it embed inline SVG and SVG as background image
P.S
style tags have no place within your html but i think everyone knows it:)
and if you don't know how to use inline svg just open inkscape it has xml editor and there you can just copy your svg and paste it within html.

SVGeezy is just what you are looking for:
https://github.com/benhowdle89/svgeezy
it's a js file that's just a few lines that deals with bitmap fallbacks in pure javascript.

Related

Is it possible to adapt a font size responsively to the width of its parent class [duplicate]

This question already has answers here:
how to set font size based on container size? [duplicate]
(10 answers)
Closed 6 years ago.
This has been asked before but the solution didn't work for me somehow so I am looking for a valid one
I have an event announcement block on the website I'm building but the client wants the event date to fill the entire width of the container.
It goes well for just one event date but off course if some other date pops up it gets on 2 rows which I expected but I dont know how to make this responsive. Any idea's?
If you don't need text wrap in the scaled text, you can use SVG for it (IE9+, so totally acceptable):
<div class="element" style="width: 30%">
<svg class="scale" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<text x="50" y="50" text-anchor="middle">Test</text>
</svg>
</div>
<div class="element" style="width: 60%">
<svg class="scaled" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<text x="50" y="50" text-anchor="middle">Test</text>
</svg>
</div>
With this CSS:
.element {
position: relative;
display: inline-block;
border: 1px solid red;
}
.scaled {
width: 100%;
}
https://jsfiddle.net/93bLu80k/1/
You may encounter problems with vertical scaling of the SVG in some versions of Safari and Internet Explorer (I don't remember which versions exactly). I have this code in some of my projects with scaled SVGs for Safari:
svg {
// hack to make safari use the correct height of svg
// https://bugs.webkit.org/show_bug.cgi?id=82489
max-height: 100%;
}
And this SASS mixin for Internet Explorer, for which you must know the aspect ratio of your SVG in advance, which is usually not a problem:
#mixin aspect-ratio($ratio) {
.ie & {
padding-bottom: 100% * $ratio - 0.02;
height: 1px;
overflow: visible;
box-sizing: content-box;
}
}
(You can translate this mixin to another preprocessor or simply use a hard coded $ratio in a normal CSS class.)
I had similar issue when working on countdowns:
http://demos.artbees.net/jupiter5/shortcodes/countdowns-milestones/
The approach I used is usage of element queries: http://elementqueries.com/
It solves the problem of width relativity scope. Our components are used by customers and they choose number of columns that it will occupy in the grid. In such unpredictable situations it is your best choice. Also if you want to encapsulate your component end make it more reusable.

How to use an SVG logo in a web application?

My web application is only required to support modern browsers (IE starting at 10). But it has to be fully responsive, so it should look good on all possible display sizes and resolutions.
It has the standard logo in the upper left corner, which is linked to the start page. I want to use an SVG logo, which should look good at any resolution. At first, I had the logo in a normal <img> tag, with height and width specified in css.
<a href="#Url.Action("Index", "Home")" id="Home">
<img id="logo" src="~/Content/images/mitoLogo.svg" />
</a>
#logo {
height: 3em;
width: 9em;
margin: 0.3em 1.5em 0.3em 0.2em;
}
Sadly, IE cannot work with that and clips the logo instead of stretching it to the given size. So I looked around and found this suggestion for placing an SVG image in a page. What I have now is
<div id="logo">
<a href="#Url.Action("Index", "Home")" id="Home">
<object height="100%" width="100%"
data="~/Content/images/mitoLogo.svg" type="image/svg+xml">
</object>
</a>
</div>
This displays the image properly in both IE and Firefox (haven't tried other browsers yet), but the link only works in IE. Neither in IE nor in Firefox does the cursor change to a clicking hand, and FF with AdBlockPlus shows a "block" suggestion on hover, possibly because this is an object tag.
Is there a way to display the SVG image correctly everywhere, while preserving its link function? I'm not limited to css, but can do radical changes to the markup, if needed, and I can also change the SVG source.
I played with your initial code a bit and got it working... it seems that you need to only set the width as a percentage and it will scale the height appropriately.
#logo {
width: 25%;
}
Try changing the percentage and adjusting the result window size in the JSFiddle Demo
I tested it in IE10 (+ IE9 in the emulator) and Chrome and it worked exactly as expected.

CSS Sprite is squashing rather than cropping

So I am trying to make some images into a sprite. I thought I understood pretty well what I was doing, but then instead of getting 6 different images, I get 1 squashed image 6 times.
Here is my code
img.sprite
{
width:100px;
height:100px;
background-image:url(myimage.jpg) 0 0;
}
img.sprite2
{
width:100px;
height:100px;
background-image:url(myimage.jpg) -100px 0;
}
</style>
</head>
<body>
<img class="sprite" src="myimage.jpg" width="1" height="1" />
<img class="sprite2" src="myimage.jpg" width="1" height="1" />
When I post this, my image is just squashed so I have 6 images of my sprite being resized and distorted, when I want it to give me a resized image of only a portion. It is not cropping for some reason.
Your are combining background images with inline images, this will not work. The background image is for use on things such as divs and other page elements.
also in your css you have the position coordinates within the 'background-image' property, this will not work either, it either needs to be in the generic 'background' css property or the specific 'background-position' one. see http://www.w3schools.com/cssref/css3_pr_background.asp
if you need to use it on inline images try this technique using css clip http://css-tricks.com/css-sprites-with-inline-images/

CSS sprite displaying all images

I am trying to use 1 single image file containing 4 images and display them using CSS sprite. Somehow, all 4 images are displayed. I was referring to one of the examples in w3schools.
<div id="ViewTypeContainer" style="float: right; margin-top: 10px; margin-right: 10px;">
<img id="calendarView" alt="" src="/Images/ButtonToggle.png" height="1" width="1"/>
<img id="grdView" alt="" src="/Images/ButtonToggle.png" height="1" width="1" />
</div>
CSS:
#ViewTypeContainer img#calendarView {
width:82px;
height:82px;
background: url('/Images/ButtonToggle.png') 0 0;
}
#ViewTypeContainer img#grdView {
width:82px;
height:82px;
background: url('/Images/ButtonToggle.png') -30px 0;
}
My image file is in .png format:
Can anyone spot my mistake? Thanks.
Yeah: your img tags have their src attributes pointing at the sprite image too.
If you want the sprite image to show up with the positioning specified in the CSS, the images need a transparent image in their src attribute.
Working example using your image here (I've used a data-URI for the transparent GIF):
http://jsfiddle.net/7Ns8L/
And here's another example using what might be more semantic HTML (depending on what these controls actually do), i.e. no <img> tags:
http://jsfiddle.net/7Ns8L/1/
Exactly. You're giving a background image to an image. So the IMG tag is displayed as normal size right over the top of your sprite. The concept of sprites is easiest applied if you work with background-position css property. You could either go through the trouble of generating a transparent .png for your IMG tag source (I wouldn't recommend it), or just replace the IMG tag with a div and give the div the same ID and CSS.

How to place an image over another?

How to put an image over another bigger image, like on youtube, a play button is displayed on top of video thumbnail?
Make a semi-transparent PNG graphic with a "Play" symbol and the size you want (e.g. 240x320).
Let's say you named it "overlay.png", and let's say the YouTube-generated thumbnail is at http://img.ytimg.com/abcdefg/0.jpg
Now all you need in your code is this:
<a href="destination_of_your_link">
<img src="overlay.png" width="320" height="240" border="0"
style="background: url(http://img.ytimg.com/abcdefg/0.jpg) center center black;" />
</a>
As long as your target audience is not still using IE6, you should be safe.
I'm not sure that YouTube uses images for this effect, isn't it still the Flash player?
Anyhow, exactly how this is done depends very much on the design you want to achieve. Lets assume that you want to achieve the YouTube style, where you have a thumbnail image and want to overlay a play button image on top. If you want the thumbnail to be an actual <img> tag you will need some extra markup, like this:
<div class="thumb-wrapper">
<img src="mythumbnail.gif" alt="my awesome video" /><span></span>
</div>
The wrapper <div> is required so you can target the img and span correctly, and have dimensions to contain them in. The span is where the overlay image will go.
.thumb-wrapper {
position:relative;
}
.thumbwrapper span {
position:absolute;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
z-index: 100;
background: transparent url(overlay.png) no-repeat;
}
(I haven't actually tested this, if its blatently wrong let me know I'll revise it!)
This assumes a couple of things:
Your thumbnails will always be a fixed size and your overlay image matches that
Your overlay image is a semi-transparent PNG
You could also use the opacity: style to achieve #2. Of course, IE6 will rear it's ugly head and you'll need to use a PNG fix for it if going the transparent image route, or a separate opacity filter if using that method. Both of these are undoubtadly answered elsewhere on Stack Overflow or easily google-able.
If you have other requirements it might be possible to do this without the extra markup, as I said it all depends on what you need exactly. Some requirements may not be possible without JavaScript (which would of course mean you could inject any extra markup with that!).
You will find the solution in the following thread on StackOverflow:
How to draw a graphic over another graphic
Shortly (quoting after Ipsquiggle) :
<div style="position:relative">
<div>
<img url="backgroundimg.png">
</div>
<div style="position:absolute; left:0; top:0;">
<img url="smallgraphic.png">
</div>
</div>
More details why and how it works in the original thread.
If you have good control over image size, we have used the background to various elements - for example, set the background of a table cell to one image and put an img tab inside the cell.
Taking your example of youtube, you could very easily do this with 2 images and 1 img tag and a little bit of CSS of course ;)
<style>
img.youtube {
width:500px; height:500px;
margin:0; padding:0;
background:transparent url(/point/to/your/larger/image.jpg) no-repeat center
}
</style>
<img src="/point/to/youtube/play/image.png" alt="Gotta have alt text ;)" border="0" class="youtube" />
How it works is simple, you have the small youtube image as transparent PNG or GIF and then set the background image as the larger image, this will then give the effect of the smaller image being in the center with no extra markup.

Resources