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.
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 have a webpage generated by a php script which reads text files stored on the server and presents the results in a form of columns which are divs with the following css properties:
width:auto;
min-width:500px;
display:inline-block;
vertical-align:top;
height:auto;
margin:.5%
The best thing about this design is that if there's enough horizontal space the user will see two or sometimes even three or more columns on the screen while at the same time if the user's device is very narrow the columns will rearrange themselves so that each column takes 100% of the available width (this is of course achieved with the use of media queries).
However there is one problem with this design: the amount of content in each column is not constant across all columns therefore if there are two or more columns displayed in one line then any column in that line shorter than the tallest column in the line will have empty space directly below it even if there are other columns below it.
Example of the problem: http://jsfiddle.net/zyrv30a6/
So I am wondering if it is possible to retain the advantages of the above design and make the columns fill the available vertical space above them.
I thought I could solve this problem by creating two super columns which would contain the individual columns however this solution would create several problems: users with wide screens would be forced to view two columns per line, while at the same time to preserve the single column view for the mobile devices the old design would have to be kept around which would double the size of the HTML code.
I should also mention that the ordering of the columns from left to right and top to bottom is important and can't be sacrificed to solve this problem.
Does adding
float: left
to the column class solve this?
This one was fun to work with. Thanks for asking this question. I can't fathom any way to do that with pure css. But I came up with a jquery solution, if you're interested:
$(document).ready(function() {
var oneColumnDisplayed = $('.column').first().offset().left === $('.column').eq(1).offset().left;
var twoColumnsDisplayed = $('.column').eq(1).offset().left > $('.column').eq(2).offset().left;
var threeColumnsDisplayed = !oneColumnDisplayed && !twoColumnsDisplayed; // assumes that three is the absolute maximum amount of columns.
var colWidth = 250; // change depending on the expected width of all columns
$('.column').each(function(index, column) {
// If the display is two columns wide and this one is not in the top row.
if (twoColumnsDisplayed && index > 1)
{
// set this column just below the column above it.
var columnAbove = $('.column').eq(index - 2);
var colAboveHeight = $(columnAbove).outerHeight();
var colAboveBottom = $(columnAbove).offset().top + colAboveHeight;
var diff = $(column).offset().top - colAboveBottom - 10; // 10 assuming a margin of 5px on each side of the columns
$(column).css('top', '-' + diff + 'px');
}
// If the display is three columns wide and this one is not in the top row.
if (threeColumnsDisplayed && index > 2)
{
// set this column just below the column above it.
var columnAbove = $('.column').eq(index - 3);
var colAboveHeight = $(columnAbove).outerHeight();
var colAboveBottom = $(columnAbove).offset().top + colAboveHeight;
var diff = $(column).offset().top - colAboveBottom - 10; // 10 assuming a margin of 5px on each side of the columns
$(column).css('top', '-' + diff + 'px');
}
});
});
I also had to add position: relative to the .column class and changed the margin to 5px. Here's a fiddle.
NOTE: In all practicality, you would probably want to throw this into a function and make sure it gets called on window resize as well, otherwise everything goes crazy when you resize the browser.
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'
});
}
CSS3's column-module allows you to divide your text into a multiple columns. Either by
1) specifying the column-height property (all columns will have the same author-defined height, the column count is dynamic)
or,
2) specifying the column-count property (all columns have the same computer-generated height, the number of columns is defined by the author).
What I would like to have is option 1, but instead of having the columns next to each-other I'd like to have them underneath each other. This way they wouldn't really be columns, but more like rows with a defined height.
This way the text will be divided into pages of all the same height. (Like when you print out a webpage.)
Any ideas on how to achieve this? ( My project only requires webkit-support. )
The column module won't do that. You would be better off declaring a class on a div with the a declared height. If you're looking for dynamic columns, you may need to do some programming via js or php.
By the way, I did play with the following idea which sort of works:
Use a multi-column DIV to split the text into different same-height chunks.
Copy the multi-column DIV X times, where X = number of generated columns.
On each DIV, only show one column. (by using overflow: hidden and a width)
Position the columns so they are underneath each-other.
This works, but is VERY slow as you can imagine.
Perhaps there's a way to show the same multi-column DIV multiple times with different view-ports, without copying the whole DOM tree?
JS seems like the way to go. Check out this jQuery function from the Filament Group. Masonry might be of interest too.
// make columns equal height
function equalHeight(group) {
tallest = 0;
group.each(function() {
thisHeight = $(this).height();
if(thisHeight > tallest) {
tallest = thisHeight;
}
});
group.height(tallest);
}
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;
}