Make inline div fill vertical space - html

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.

Related

Bootstrap grid layout: force specific cells to always be in the same row

Using Bootstrap Grid Layout to show various forms. Cells are assigned width (e.g. 3 of 12 columns) and all of it is configurable. The problem is Label and Field width are supposed to be configured separately. E.g. labelA is width 2, fieldA is width 4, labelB is width 2, fieldB is width 4. This way user will see "2 column" layout: labelA-fieldA-labelB-fieldB.
However there's a problem if user decides to set label and field width to some other value, for example to span all row. User sets label B width to 4 and field B width to 8 expecting it to take whole row. However, in this case he'll get labelA-fieldA-labelB-[empty space for 2 columns] on the first row and fieldB on the second row. Obviously the intended solution would to have labelA-fieldA-[empty space for 6 columns], then labelB-fieldB on the next row. Again, this is all configurable so I need solution for all cases.
A perfect solution would be to have some way to force those cells (label and field) to be non-breakable. Can't find the way to do that.
Another way would be to create a container component with width=label.width+field.width. But then I'll have problems with setting label and field width inside of those containers because I can only set label/field width relative to direct parent and I need to set width relative to the parent's parent. I've heard there are ways to change number of columns in component on render and it'd work if I set number of columns to label.width+field.width. But as far as I understand it's a dirty solution.
The code is in React and this is what's generated for each label and field. InpComp may be any component, doesn't matter in the end. labelWidth and fieldWidth are set by configuration.
const labelWidth = this.getLabelWidthFromConfiguration();
const fieldWidth = this.getFieldWidthFromConfiguration();
return (
<div className={'component-container'}>
<div className={'col-md-${labelWidth}'}><b>{this.field.attributes.label}</b></div>
<div className={'col-md-${fieldWidth}'}>
<InpComp />
</div>
</div>);
What can I do to this code so that those label and field always end up on the same row?
what about an if-statement? ;)
you can do something like this:
if (lableWidth + fieldWidth !== 6) {
fieldWidth = 12 - lableWitdh;
}
This solution only works for one case (LA+FA = LB+FB = 6). You could set a condition for each case by your own using if/else or switch-case.
Like Troyer said, we're not here to show ideas or do your work, we are here to fix code problems. Next time you should try to solve your Problem by your own until you get in stuck and then provide your Code.

How to make 2 different tables having different number of rows to be of same height

I have 2 different tables. Both the tables varies in the number of rows it have. I need both the tables to be displayed of the same height..
I want the 2nd table rows to be adjusted in such a way that it too expands to the same height as 1st table.
use
$("#div2").height($("#div1").height());
for load the correct height on the second div
and on the second table add
style="height: 100%"
demo
First of all you need to see witch one of those tables have a bigger height and after that you should make the other one like it.
Considering that both of your tables have a class called for example mytable, the script you need to load after the document is ready is this:
var heights = $(".mytable").map(function() {
return $(this).height();
}).get(),
maxHeight = Math.max.apply(null, heights);
$(".mytable").height(maxHeight);
Use bootstrap classes
row class and col class.
You can go check this sample

Infinite upward scroll with defined bottom in AS3

I am trying to make a display that takes an input number and displays that number centered vertically on a strip along with the numbers above and below it, appropriately spaced. That much works - my problem is with getting it to bottom out at zero. I don't want to have negative numbers or even tick marks below zero.
You can see the file in question here: http://www.fastswf.com/r58wGg0
In that file, the left is what the final version will look like (masked - giving the illusion that it is moving infinitely) and the right is unmasked, showing the actual movement of the movieclip and text boxes. The input number is based on mouse position so slowly move your mouse around to see the action.
And here is my code.
var labelSpacing = 500;
var tickSpacing = 18;
function updatePosition(currentValue){
tape.y = ((currentValue/100)%5)*tickSpacing;
current.y = (((currentValue/100)%5)*tickSpacing)+170.85;
plus1.y = (((currentValue/100)%5)*tickSpacing)+82.85;
minus1.y = (((currentValue/100)%5)*tickSpacing)+259.9;
current.text = (Math.floor(currentValue/labelSpacing)*labelSpacing).toString();
plus1.text = (Math.floor(currentValue/labelSpacing)*labelSpacing+labelSpacing).toString();
minus1.text = (Math.floor(currentValue/labelSpacing)*labelSpacing-labelSpacing).toString();
}
Is there a way to modify this so that it changes its behaviour near zero so that it displays correctly?
Hmm, normally such indicators do allow displaying values below zero. But, for your purpose, you can use a limited currentValue to use in your calculations, but preserve the old value in case you need to display something else based on actual currentValue too.
function updatePosition(currentValue:Number):void {
var cappedValue:Number=currentValue;
cappedValue=Math.max(cappedValue,1.0*labelSpacing);
// experiment with this constant ^^^ to achieve desired result in production
tape.y = ((cappedValue/100)%5)*tickSpacing;
// and use cappedValue in place of currentValue in calculations
// rest of code
}

Make HTML table cell's content fit - without wrapping?

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.

How to divide a large text into multiple chunks, all with the same max-height?

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);
}