How to tame SVGs as background-images - html

I have the following goal: I wanted to place a heart within a container -  scaled and positioned.
First I wanted to use an icon font but I've discarded the idea. Second option to load the heart as an image I've discarded too - I have to use the heart a few times on my recent project and I wanted to save http requests. Therefore I wanted to go with the SVG as a background-image option. But the problem is, somehow I am unable to tame that beast. I've built a sample pen to illustrate the issues and parts I don't understand.
The un-base64-encoded optimized SVG looks like that:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 960"><polygon points="756,168.4 593.5,168.4 480,258.3 366.5,168.4 204,168.4 30,349 480,791.6 930,349"/></svg>
The sample code you can find from my codepen.
Basically I have three related questions (normally I prefer to post separate issues but those three questions are basically way too connected therefore I hope it's ok):
The sizing: .heart1 has a width and height of 100% and everything displays fine. If you use suiting px values all is fine too but if you try to enter ems the heart isn't shown anymore. Why?
The green box: .heart1 has a width of 100% but if you drag the browser window bigger the heart only grows to some point and then only the green box keeps on growing. I thought SVGs are more or less able to scale to "infinity"?
The yellow box: My basic goal was to make the heart a bit smaller than the width of the yellow box, center it horizontally within and give the heart some top margin. Width and height of .heart2 are set to 75%. But somehow I am unable to position the heart within the box neither with top, left and/or right properties nor in background:url with "no-repeat center 2em" e.g. . It just doesn't react.

I use a block of code shown below to fit svg in a DIV. It works best in a DIV with the same width/height. As you can see below it uses getBBox() to change its viewBox, plus changes the svg width/height values.
It works cross browser: IE10+/CH31/FF23
var bb=mySVG.getBBox()
var bbw=bb.width
var bbh=bb.height
//--use greater of bbw vs bbh--
if(bbw>=bbh)
var factor=bbw/divWH
else
var factor=bbh/divWH
var vbWH=divWH*factor
var vbX=(bbw-vbWH)/2
var vbY=(bbh-vbWH)/2
//---IE/CH---
if(!isFF)
{
var ViewBox=mySVG.viewBox.baseVal
ViewBox.x=vbX
ViewBox.y=vbY
ViewBox.width=vbWH
ViewBox.height=vbWH
}
else
mySVG.setAttribute("viewBox",vbX+" "+vbY+" "+vbW+" "+vbH)
//--requred for FF/CH---
if(!isIE)
{
mySVG.setAttribute("width","100%")
mySVG.setAttribute("height","100%")
}
else
{
mySVG.removeAttribute("width")
mySVG.removeAttribute("height")
}
The svg is centered both left/right and top/bottom within the DIV, plus maintains its aspect ratio. This should help get you started.

Related

Each background middle img repeated vertically must appear full size to match bottom img

I spent more than 10 hours trying to find a solution to my problem (most answers were on Stack Overflow) but nothing seems to be exactly what I need and I may not be experienced enough to adapt a solution to my own issue.
So, I made a picture where I want text to appear on my website. But only inside that picture (frame). So I cut it in 3 parts and made it tileable.
The 3 images and what it should look like (notice the fact there are transparent parts):
So what I simply did in html/css : I made 4 divs, one for the top part, one for the middle part, one for the bottom part and one for the page content (text or images).
The middle part has a repeat-y. So here is the result when the text is longer than the middle part (242px):
In the above image, there are 2 middle images (the first one and the repeated one, but it's cropped automatically). Depending on the length of the text, it is cut at the wrong location and it messes everything. It must fit perfectly each time, and if it's longer than 242 pixels (height of the top image), it doesn't fit exactly.
I would like the div to show the entire "middle.png" WHEN repeated or to make the div lengths = (242 pixel * amount of "middle.png")
Help me please, if possible with pure CSS/HTML. I know close to nothing in PHP, and even less in JS (and even LESS in Jquery :D).
What you're asking for cannot be done in pure HTML/CSS (as far as I know). You need to have some calculations on the div height, and apply appropriate logic based on that.
Basically you need to check if the div height is divisible by 242. If it is, cool, everyone is happy, if not, then set the height of the div, to be the first next number divisible by 242.
Pure JavaScript
<script>
r(function(){
var div = document.getElementsByClassName('myDiv')[0];
var divHeight = div.offsetHeight;
if (divHeight % 242 != 0) { // checks if height is divisible by 242
div.style.height = ""+(Math.ceil(divHeight / 242) * 242)+"px"; // set height as the next number divisible by 242
}
});
function r(f){/in/.test(document.readyState)?setTimeout('r('+f+')',9):f()}
</script>
WORKING PURE JS EXAMPLE
OR if you're more familiar with jQuery framework it would look something like this:
//First, add the jQuery library
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
Then add the code that does all the work
<script>
$(document).ready(function() {
var div = $('.myDiv');
var divHeight = div.height();
if (divHeight % 242 != 0) { // checks if height is divisible by 242
div.height(Math.ceil(divHeight / 242) * 242); // set height as the first next larger number divisible by 242
}
});
</script>
WORKING JQUERY EXAMPLE

How to get size of an element in physical pixels?

Let's say i have a div that i've defined to be (32px, 32px) in size:
html:
<div id="theBox"></div>
css:
div {
width: 32px;
height: 32px;
background-color: gray;
}
(Live jsFiddle view)
How can i get the actual size of the box in pixels?
You'll note that the box doesn't have to be 32px. It can be larger:
or smaller:
or exactly 32 pixels:
The reason for the differences, of course, is because Chrome and Internet Explorer allow me to zoom.
i would like to know the actual size of the element. Why? No reason; just cause. i'm curious, and i'd like to broaden the limits of human knowledge and understanding.
Or because i need to set the internal resolution of a Canvas element to match the actual size of the canvas element - otherwise the rendered canvas contents will get stretched without my permission:
Although, my reasons for wanting to know the size of an element do not necessarily apply just to a Canvas. i'm asking about a generic div element; and the answer will be used towards canvas, img, video, and anything else i desire.
You would need to detect the zoom level.
Then write a simple arithmetic proportion to calculate the 'actual' size, or the size as it appears to the user.
var zoomLevel,
, actualSize = 32
, viewSize;
function getZoomLevel(){ ... your code here...return zoomLevel;}
function getViewSize(actualSize){
viewSize = actualSize*getZoomLevel();
return viewSize;
}
Then ... call getViewSize() when ready ...
Hopefully the math is clear enuff.
Solving for y (or viewSize):
actualSize/1 = y/zoomLevel
However, you will need to be careful about sub-pixel precision, especially among the notoriously bad length/width determining browsers like IE9. But, as long as all you need is something close, this should work.

CSS3 Transforms -- Alternate Trigger?

Usless Background Info
Hello, all. This is my first post here, but I often come here for help.
I am an amateur web designer and have been in web designing for almost a year now.
The Problem
My question is about CSS3 transforms. I have a small, circular element in the center of my page that transforms successfully when I hover over it. I have a larger circular element that is, by z-index, underneath it. The larger circle also has CSS3 transforms coded in the CSS, but will not transform, or even triggerd when hovered over. Both circles are overlaid, with the smallest on top, to create concentric circles.
My Attempted Solution
One word: Z-index. I have tried putting the larger circle on top, which works fine. The problem with this is that the smaller circle no longer triggers...
The Result I Want
I would like for the circles to remain in their 'concentric' positions and for the larger circle on the outside to transform by :hover. Is it possible to have an 'alternate trigger'? e.g.: in JavaScript, I can trigger an animation by hovering over any element that I specify. Is this possible to do in CSS? Can I hover element (I), and change properties for element (II)? If I cannot do this, how would I go about triggering animations for both circles, by hovering over only one? I am trying to stay with pure CSS/HTML, but I will accept JavaScript answers.
Last Notes
I hope I have provided ample info for a decent answer... Here is a screenshot: http://i.stack.imgur.com/WPj62.png
The circle with the infinity sign is the smaller circle element. The larger circle with the faint border around the screen is the other element.
EDIT:
Something's still not right, please take a look at the full code posted here: http://cssdesk.com/eJ8BH
If I understand your question, it sounds like when you hover over the small circle, you want both the large and small circle to transform, correct?
The easiest way is likely to use javascript for this. If you are using jQuery, it's even easier:
$('.littleCircle')
.hover(function(){
$(this).addClass('myTransformationClass');
$('.biggerCircle').addClass('myTransformationClass');
})
UPDATE: Some further examples based on follow-up feedback.
Here's what I'd do. First, give all 4 related elements a class so you can grab them via jQuery. For the example I use .rolloverSet
// grab all 4 elements and cache them
$rolloverSet = $('.rolloverSet');
// grab the one element that needs to have two classes
$otherElement = $rolloverSet.find('.otherElement');
$rolloverSet
.hover(function(){ // we'll add a hover event to each element in the group
$(this).addClass('myTransformationClass');
$otherElement.addClass('myOtherTransformationClass');
})
.blur(function(){ // remove the classes on mousout
$(this).removeClass('myTransformationClass');
$otherElement.removeClass('myOtherTransformationClass');
})
You do not need jQuery for this. You need to apply :hover on the parent element of the concentric circles and then apply the animation to its immediate children like this: http://jsfiddle.net/nimbu/taqr4/
Things I changed:
Updated to use shorter transitions, animations property
Added moz, o, unprefixed properties
Removed -webkit- from border-radius
Gathered common properties of concentric circles to prevent repetition
Fixed incorrect background-color (#00000000)

Generate rectangle with variable dimensions in CSS with inner gradient background

i have some variables on PHP who gain values from 0 to 100. I want to develop a simple graph system that draw a horizontal rectangle given the number (0, 1 , 50 and soo). Also i want to add some gradient to the background, doing this in php is complicated and i dont want more load in my server, so i know this is possible in css, but im not a css developer. So if any body can help me with this. In this page (http://www.answerbag.com/) you can se how i want the rectangle, in the results of the pool section in the middle of the above page.
that's very simple since you know the width. Since you probably want the full spectrum of the gradient to show, you probably want to resize the gradient image by using a css #score1 { width: 30px } on that <img id="score1" src="blue_gradient.png"> Then later on, you can use one of the many rounder corner methods to add the round corners to it.

Getting Image height before the image loads in HTML

I have a table that is dynamically created using DIVs. Each row of the table has two images. I want to set the height for the div (that represents a particular row) to the height of image that is greater of the two images being displayed in that particular row. The images to displayed will always change, and they are from an external server.
How do I set the height for my div so that I can fit images?
If you are trying to dynamically resize a couple of divs in a row within a table, you maybe better off using a html table instead and having each image within a td tag. This will make tr tag resize accordingly for the image in each cell.
this.img = new Image();
this.img.src = url;
alert(this.img.width);
gives the width while
var img = new Image();
img.src = url;
alert(img.width);
doesnt..
dunno why.
You can:
Not specify the height of the div, and let it expand automatically
Once the image is loaded do:
document.getElementById("myDiv").height = document.getElementById("myImage").height
We'll need a little more info to be very useful. You can get the height & width of an image after the page loads via Javascript (info), then you could resize the height of the div after loading. Otherwise, you're really out of luck since HTML itself doesn't have anything.
If you're using PHP, there's getimagesize(), which you can use if you're building the site dynamically with PHP. There are similar functions for other languages, but we'd need a little more info.
If you want the browser to do layout based on the height of an image, before it fetches the image, you need to send that height to the browser somewhere. This will require something server-side. The fastest thing would be to insert in into the html directly. Slower but more elegant would be to fetch it image by image with <script src=> statements that get instructions from a special bit of javascript-generating cgi. (The speed difference comes from network round trips.)
If you're willing to resize after the data arrives, it's much simpler. Either slap an onload handler on the images or stick them in normal dom (e.g. an actual table, though you can do it with divs and css) and let the layout engine do the work.
This question has been answered in multiple ways, and you asked the additional question "Won't this make the UI look bad?"
The answer to that question is Yes. The best thing for you to do in most cases will be to set the height of your div to something that looks good, then scale the images down to fit. This will make the rendering faster, and the final product will look better and more professional.
But that's just my own opinion, though. I have no empirical data to back that up.
Pre-load them into javascript image objects then just reference the height and width.
Might take some clever devilry to work in all browsers...
function getSize(imgSrc){
var aImg = new Image();
aImg.src = imgSrc;
aHeight = newImg.height;
aWidth = newImg.width;
}