Updated using flex
This might help you out.
With flex you can change the order of elements and by doing so, you can set the "text div" before the "svg", make all position relative and make them flow naturally.
Some css need the "!important" on its value to override the inline styles.
Update 2 Code/demo updated to show how to prefix css properties for Safari
FIDDLE demo
#barcontainer > div > svg,
#barcontainer > div > div,
#barcontainer > div > div > span {
position: relative !important;
}
#barcontainer > div {
height: auto !important;
}
#barcontainer > div > svg {
top: -20px !important;
}
#barcontainer > div {
-webkit-display: flex;
display: flex;
-webkit-flex-flow: column;
flex-flow: column;
}
#barcontainer > div > svg {
-webkit-order: 2;
order: 2;
}
#barcontainer > div > div {
-webkit-order: 1;
order: 1;
}
You can also use 1 or more media queries to control at which screen sizes the above should kick in.
@media screen and (max-width: 600px) {
//flex css 1
}
@media screen and (max-width: 800px) {
//flex css 2
}
Update 3 using javascript
If you can't/don't want flex here is a simple "swapper" which switch the svg and the text element.
Note: You can use flex and have a fallback for older browsers where a script like this kicks in
FIDDLE demo - JS version
function swapSibling(node1, node2) {
node1.parentNode.replaceChild(node1, node2);
node1.parentNode.insertBefore(node2, node1);
}
window.onload = function() {
var parent = document.getElementById("barcontainer").children[0];
var svg = parent.children[0];
var text = parent.children[1];
swapSibling(svg, text);
}
Note: If you need to support IE8 read best way to get child nodes
Update 4 using zoom
If the content just need to get "smaller", one more approach one can take is actually to "zoom" the barcontainer. This keep the existing ratio and layout and makes all content smaller (or bigger), still, when need to "squeeze" to much, text normally gets difficult to read.