Is there an easy way, or existing library, which will shrink the content of a div if it overflows it's parent? I am envisioning something like Powerpoint / Keynote, where text in the main box shrinks in size automatically, when the content gets to big (so not just re-formatting, but the fonts and pictures get smaller to fit in the div).
I feel this should be simple to do, using CSS 'scale', but I am surprised I can't find someone else who has done it, so I wonder if there is an issue I am not thinking of?
Something like this? I set up a quick test that calculates the ratio of child to parent boxes and sets an appropriate scale to make the widths match:
var one = $('.one');
var two = $('.two');
if (two.width() > one.width()) {
two.css({
'transform': 'scale(' + one.width() / two.width() + ')',
'transform-origin': '0 0'
});
}
Related
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
I'm rendering a JointJS diagram in a div with visibility hidden. When I set the visibility to visible the shapes in the diagram are massive.
I can see in the code that each node is being scaled by calling:
box = this.node.getBBox()
But this is returning an empty object (presumably because the node is hidden). The width/height are then defaulted to zero. Later on the node is being scaled as follows:
scalable.attr('transform', 'scale(' + (size.width / (scalableBbox.width || 1)) + ',' + (size.height / (scalableBbox.height || 1)) + ')');
Since the returned scalableBbox has width 0 the result of (size.width / (scalableBbox.width || 1)) is the width and the node is therefore scaled to its width * width / 1. The same happens for the height.
This seems wrong!
Is there any way to render a JointJS diagram in an invisible div or is there a way to redraw the diagram once the div becomes visible?
You can remove the scalable class from your element shape to avoid this issue.
The scale feature is only used during resize: documentation
You can define your own shape without scalable element: tutorial
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.
This is my situation :
I'm currently in the process of finalizing a rather... huge web application (PHP with CodeIgniter, MySQL, Javascript+Ajax+Jquery and using various Javascript libraries - e.g. dataTables)
The issue :
Let's say we've got a table, fixed-width.
The first column is also fixed-width. (Let's say at 200px)
When the table is populated :
If the contents of the first column occupy less than 200px space, it's ok.
If the contents exceed those 200px then the content is wrapped, thus creating a "double line" effect and higher rows than I'd wished.
Hint :
"Shrinking" a very very very long line to something like very very very ... is what I'm thinking. Is something like that even possible? Server-side?
How would you approach that? (preferably in an elegant way - 'coz, yep, I admit that I have a few solutions in mind, none of which seems... user-friendly... lol)
I think doing a string-truncation is impossible serverside, if you are not using a monospace font so that the same number of characters always has the same width. What you could do is a client-side string-truncation:
(Nice code at Calculate text width with JavaScript):
CSS:
#testing-div
{
position: absolute;
visibility: hidden;
height: auto;
width: auto;
}
JS:
var test = document.getElementById("testing-div");
test.style.fontSize = fontSize;
var height = (test.clientHeight + 1) + "px";
var width = (test.clientWidth + 1) + "px";
You can loop through the entire length of the string, and keep adding a character to the body of #testing-div, calculating the width, and checking if it fits. Make sure you add the ... if the string is too long.
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;
}