Dynamic widths inside two left floated columns - html

Imagine the site:
[list][ iframe ]
both columns must be set next to each other, and has variable widths. I saw many solution, for example this: http://www.sitepoint.com/forums/showthread.php?615554-Floating-100-of-Remaining-Width but thats not the case. I dont have fixed widths, nor dynamics - the left column must be as thin as its content, and the iframe must fill all the remaining space.
jQuery is enabled to use for this case. In addition, how to detect, if the width of list changed?
http://jsfiddle.net/trgC3/

<table style="width:100%;">
<tr>
<td style="border:1px solid black;width:100px;height:10px;"></td>
<td style="border:1px solid black;height:10px;"></td>
</tr>
</table>
<br /><br />
<div class="lineContainer">
<div class="left"></div>
<div class="right"></div>
</div>
.lineContainer {
overflow: hidden; /* clear the float */
border: 1px solid #000
}
.lineContainer div {
height: 10px
}
.left {
width: 100px;
float: left;
border-right: 1px solid #000
}

try using display: table-cell
http://jsfiddle.net/YRTM9/
<div class='table-div'>
<div class='left'>
hello!
</div>
<div class='right'>
<iframe src='http://www.stackoverflow.com'>
</iframe>
</div>
</div>
with following CSS
.table-div {
display: table;
width: 100%;
}
.left {
display: table-cell;
vertical-align: top;
}
.right {
display: table-cell;
width: 100%;
}
.right iframe {
width: 100%;
}

I'm on board with those who think about table, but I'd rather add width: 100% only for column with iframe. Here is the spec
For each column, determine a maximum and minimum column width from the
cells that span only that column. The minimum is that required by the
cell with the largest minimum cell width (or the column 'width',
whichever is larger). The maximum is that required by the cell with
the largest maximum cell width (or the column 'width', whichever is
larger).
see demo
but if you need iframe to keep ratio, you'll have to wrap it div and use some hack

Related

floating two div tags that equal 100% width moves second div to new line [duplicate]

This question already has answers here:
CSS: Width in percentage and Borders
(5 answers)
Closed 5 years ago.
Newbie to everything.
I have two div tags, the first has a width of 80% and the second a width of 20%. 80%+20%=100% but the second div moves to the next line.
The objective is to use the whole line without moving to the second.
<!DOCTYPE html>
<html>
<head>
<style>
.border {
border-style: dotted;
}
</style>
</head>
<body>
<div class="border" style="width: 80%;">thing</div>
<div class="border" style="width: 20%; float: left;">other thing</div>
</body>
</html>
Try this:
css code:
.table_formate {
display:flex;
width:100%
}
.border {
border:1px solid #ddd;
}
HTML:
<div class="table_formate">
<div class="border" style="width: 80%; float: left; background: #dd0d0d;">thing</div>
<div class="border" style="width: 20%; float: left; background: #4abdac;">other thing</div>
</div>
jsfiddle link
You need to consider your border with your width. The border adds to the width making the width value increase. You would have to reduce the width size for this to be possible
.border {
border-style: dotted;
}
<div class="border" style="width: 80%; float: left; background: #dd0d0d;">thing</div>
<div class="border" style="width: 20%; float: left; background: #4abdac;">other thing</div><br>
<div style="width: 80%; float: left; background: #dd0d0d;">thing</div>
<div style="width: 20%; float: left; background: #4abdac;">other thing</div><br>
<div class="border" style="width: 79%; float: left; background: #dd0d0d;">thing</div>
<div class="border" style="width: 19%; float: left; background: #4abdac;">other thing</div>
Try,
<div class="border" style="width: 80%; float: left;">thing</div>
<div class="border" style="width: 20%; float: left;">other thing</div>
You can use box-sizing:border-box; to keep border in the count of the width of element :
See below snippet
.border {
border-style: dotted;
}
* { box-sizing: border-box; -webkit-box-sizing: border-box; }
<div class="border" style="width: 80%; float: left; background: #dd0d0d;">thing</div>
<div class="border" style="width: 20%; float: left; background: #4abdac;">other thing</div><br>
What you have to keep in mind is that block level elements, such as your div, always extend to the left and right edge of the page. When you set a width, you are setting the width of the content, not the block context as it's called. To do what you wish, you would need to float, or otherwise reposition, the first div so it does not occcupy the full width.
Also keep in mind that border is outside the width of content. And you must keep in mind padding and margin. Margin is added to the body on almost all graphical browsers, though this doesn't play into your problem.
So, your width is set to 80% and 20% of the parent element. The parent element is the body so we're OK here but you have a border. That border makes the total width of your content extend beyond the body by 2px; one px for each side of the div elements.
If you remove the borders and float the first div, you will accomplish what you want.
As an alternative, you can leave the borders in and make one or both of your div elements slightly smaller to accommodate the border.
To answer your question in a comment:
div { width: calc(80% - 2px); }
Note the "2px" as it's one px for each side of the div element. Maintain the spaces in the formula for this to work.
EDIT: Just noticed that the width of "dotted" as a border is larger than 1px. You'll need to set the minus value in the formula to accommodate whatever the width of the border is.

HTML 3 columns header

I'm trying to make fixed header that is splited in 3 parts on horizontal. The central part have 1000px width, other 2 parts have equal sizes with auto width. Also the left part have an image with an edge glued to the central part. I have tried a couple of solutions, however i accomplished this only by using tables. Can anyone help me with this?
You can make that using divs, displayed as table-cell.
HTML:
<div class="header">
<div class="l">l</div>
<div class="m">m</div>
<div class="r">r</div>
</div>
CSS:
.header {
display: table;
width: 100%;
table-layout: fixed;
}
.header > div {
display: table-cell;
}
.l {
background: lightblue;
}
.m {
background: lightgreen;
width: 500px;
}
.r {
background: lightblue;
}
Also check the demo.
I would restrict the use of tables to tabular data. Based on your description, I think this will work for you. What you are doing is setting a fixed width to your middle column and setting the width of the end columns to 50% and then setting a negative margin on each to half of the width of the center column. The CSS could be a little more efficient.
http://jsfiddle.net/CLRxq/1/
HTML
<div class="wrapper">
<div class="left">Add Image here</div>
<div class="center"> </div>
<div class="right"> </div>
</div>
CSS
.wrapper {
overflow: hidden;
}
.center {
float: left;
width: 1000px;
background: red;
}
.right {
float: right;
width: 50%;
background: green;
margin-right: -500px;
}
.left {
float: left;
width: 50%;
background: blue;
margin-left: -500px;
text-align: right;
}
You can do it with tables or divs, it's up do you, though, for flexibility and consistency I recommend doing it on divs.
Table:
<table width="1200" height="100">
<tbody>
<tr>
<td></td>
<td width="1000"></td>
<td></td>
</tr>
</tbody>
</table>
Div:
Go here, the center div is the big one, side div are the others, don't remove the clear div, it is only a float fix for the html. Just change the CSS accordingly to what you want.
http://jsfiddle.net/EsQak/

Make two columns the same height regardless of content

I have a basic grid system, really basic, which puts to 'cells' side by side in a fluid 'row'. I want the two cells to always match their height so they are equal. So if one has more content than the other, the other expands to match the height of the cell with more content.
<div class="row">
<div class="cell1">
<div class="inner">
<h2>Cell 1</h2>
<p>Regardless of content, can I make Cell 1 and Cell 2 the same height so the borders are level?</p>
</div>
</div>
<div class="cell2">
<div class="inner">
<h2>Cell 2</h2>
</div>
</div>
</div>
Demo of the problem here: http://jsfiddle.net/QDBff/
If you absolutly must avoid using TABLEs, you can style your divs to behave like tables with
display: table;
display: table-row;
display: table-cell;
You can look at the markup/css and results in this fiddle: http://jsfiddle.net/aeinbu/QDBff/35/
I made it work here with the use of jQuery: http://jsfiddle.net/QDBff/10/
$(document).ready(function() {
var height1 = $('.cell1 > .inner').height();
var height2 = $('.cell2 > .inner').height();
if (height1 < height2) {
$('.cell1 > .inner').height(height2);
} else {
$('.cell2 > .inner').height(height1);
}
});
<table><tr><td>Cel 1</td><td>Cel 2</td></tr></table>
I've checked your fiddle and I think it may be fixed by adding a min-height of 270px (for ex. only).
I am not a jsfiddle user, but look at my screen shot below...
Note:
You just have to tweak your min-height to fit your needs. Tweak is necessary whenever the text size increases or decreases.
But, if your content is dynamic, this is not a permanent solution.
Add a large padding bottom and an equal negative margin bottom to your cells and stick overflow: hidden onto your row.
.cell {
width: 50%;
background: #eee;
float: left;
margin-bottom: -1000px;
padding-bottom: 1000px;
}
.cell:nth-child(odd) { background: #ddd; }
.row { overflow: hidden; }
.row:after {
content: "";
clear: both;
display: table;
}
Example here:
http://jsfiddle.net/Q9U6g/1/
you can achieve this by using
display: table
and
display: table-cell
I have modified your jsfiddle - http://jsfiddle.net/Raver0124/QDBff/36/
Also another jsfiddle that i created previously - http://jsfiddle.net/jBMBR/6/
Change the border from Inner class to Cell1 and Cell2 classes. Then give fixed height to the Cell1 and Cell2 classes.
.cell1 {
width: 45%;
margin-right: 1%;
float: left;
border: 1px solid #CCC;
height:400px;
}
.cell2 {
width: 45%;
margin-left: 1%;
float: left;
border: 1px solid #CCC;
height:400px;
}
Here is the fiddle
http://jsfiddle.net/QDBff/31/

CSS: Force textarea to ocuppy all available area

I'm working on a form with an horizontal layout:
<div id="container">
<label for="ta">description</label>
<textarea id="ta" name="ta" cols="50" rows="10"></textarea>
</div>
The problem is that what I want is the textarea take up all available space that the label leaves in the same line. If I try with width=100% it jumps to the next line:
div * {
vertical-align: middle;
}
textarea {
width: 100%;
height: 300px;
}
Any idea to implement it without assign a fixed space to each tag?
Like this? http://jsfiddle.net/4QbMr/
<div id="container">
<label for="ta">description</label>
<div class="twrap"><textarea id="ta" name="ta" cols="50" rows="10"></textarea></div>
</div>
label {
float: left
}
.twrap {
overflow: hidden;
padding: 0 4px 0 12px
}
textarea {
width: 100%;
height: 300px;
}
For table-like behaviour with CSS, display: table is your friend:
#container {
display: table;
width: 100%;
}
#container label, #container textarea {
display: table-cell;
vertical-align: top;
}
#container textarea {
width: 100%;
height: 300px;
}
Note that if you specify cols and rows attributes, they will override your CSS.
http://jsfiddle.net/N9hvU/27/
I think this is the behavior you're looking for. Even though I prefer to use divs/spans for element positioning; tables have the unique behavior (from my experience; don't know if this is in w3 specs or not) of not letting items go onto the next row; regardless of how big they become.
So, by setting the table row width to 100 percent, and the width of the cell w/the text area to 100%, the text area will consume any width available.
<div id="container">
<table>
<tr style="width:100%;">
<td>
<label for="ta">description</label>
</td>
<td style="width:100%;">
<textarea id="ta" name="ta"></textarea>
</td>
</tr>
</table>
</div>
You need to specify width for label.
like
label{ width: 20%; } textarea{ width:80%; }
I would instead put text for the label in the div and textarea in a different div and float both divs (and specify widths for both as well).
use a percentage less than 100% and leave out the cols in the textarea.try this http://jsfiddle.net/bingjie2680/Bw4MR/
update: try this: http://jsfiddle.net/bingjie2680/Bw4MR/3/ you need to use table to accomplish this job.

Expand a div to fill the remaining width

I want a two-column div layout, where each one can have variable width e.g.
div {
float: left;
}
.second {
background: #ccc;
}
<div>Tree</div>
<div class="second">View</div>
I want the 'view' div to expand to the whole width available after 'tree' div has filled needed space.
Currently, my 'view' div is resized to content it contains
It will also be good if both divs take up the whole height.
Not duplicate disclaimer:
Expand div to max width when float:left is set
because there the left one has a fixed width.
Help with div - make div fit the remaining width
because I need two columns both aligned to left
The solution to this is actually very easy, but not at all obvious. You have to trigger something called a "block formatting context" (BFC), which interacts with floats in a specific way.
Just take that second div, remove the float, and give it overflow:hidden instead. Any overflow value other than visible makes the block it's set on become a BFC. BFCs don't allow descendant floats to escape them, nor do they allow sibling/ancestor floats to intrude into them. The net effect here is that the floated div will do its thing, then the second div will be an ordinary block, taking up all available width except that occupied by the float.
This should work across all current browsers, though you may have to trigger hasLayout in IE6 and 7. I can't recall.
Demos:
Fixed Left: http://jsfiddle.net/A8zLY/5/
Fixed Right: http://jsfiddle.net/A8zLY/2/
div {
float: left;
}
.second {
background: #ccc;
float: none;
overflow: hidden;
}
<div>Tree</div>
<div class="second">View</div>
I just discovered the magic of flex boxes (display: flex). Try this:
<style>
#box {
display: flex;
}
#b {
flex-grow: 100;
border: 1px solid green;
}
</style>
<div id='box'>
<div id='a'>Tree</div>
<div id='b'>View</div>
</div>
Flex boxes give me the control I've wished css had for 15 years. Its finally here! More info: https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Use the CSS Flexbox flex-grow property to fill the remaining space.
html, body {
height: 100%;
}
body {
display: flex;
}
.second {
flex-grow: 1;
}
<div style="background: #bef;">Tree</div>
<div class="second" style="background: #ff9;">View</div>
This would be a good example of something that's trivial to do with tables and hard (if not impossible, at least in a cross-browser sense) to do with CSS.
If both the columns were fixed width, this would be easy.
If one of the columns was fixed width, this would be slightly harder but entirely doable.
With both columns variable width, IMHO you need to just use a two-column table.
Use calc:
.leftSide {
float: left;
width: 50px;
background-color: green;
}
.rightSide {
float: left;
width: calc(100% - 50px);
background-color: red;
}
<div style="width:200px">
<div class="leftSide">a</div>
<div class="rightSide">b</div>
</div>
The problem with this is that all widths must be explicitly defined, either as a value(px and em work fine), or as a percent of something explicitly defined itself.
Check this solution out
.container {
width: 100%;
height: 200px;
background-color: green;
}
.sidebar {
float: left;
width: 200px;
height: 200px;
background-color: yellow;
}
.content {
background-color: red;
height: 200px;
width: auto;
margin-left: 200px;
}
.item {
width: 25%;
background-color: blue;
float: left;
color: white;
}
.clearfix {
clear: both;
}
<div class="container">
<div class="clearfix"></div>
<div class="sidebar">width: 200px</div>
<div class="content">
<div class="item">25%</div>
<div class="item">25%</div>
<div class="item">25%</div>
<div class="item">25%</div>
</div>
</div>
Here, this might help...
<html>
<head>
<style type="text/css">
div.box {
background: #EEE;
height: 100px;
width: 500px;
}
div.left {
background: #999;
float: left;
height: 100%;
width: auto;
}
div.right {
background: #666;
height: 100%;
}
div.clear {
clear: both;
height: 1px;
overflow: hidden;
font-size: 0pt;
margin-top: -1px;
}
</style>
</head>
<body>
<div class="box">
<div class="left">Tree</div>
<div class="right">View</div>
<div class="clear" />
</div>
</body>
</html>
If the width of the other column is fixed, how about using the calc CSS function working for all common browsers:
width: calc(100% - 20px) /* 20px being the first column's width */
This way the width of the second row will be calculated (i.e. remaining width) and applied responsively.
I don't understand why people are willing to work so hard to find a pure-CSS solution for simple columnar layouts that are SO EASY using the old TABLE tag.
All Browsers still have the table layout logic... Call me a dinosaur perhaps, but I say let it help you.
<table WIDTH=100% border=0 cellspacing=0 cellpadding=2>
<tr>
<td WIDTH="1" NOWRAP bgcolor="#E0E0E0">Tree</td>
<td bgcolor="#F0F0F0">View</td>
</tr>
</table>
Much less risky in terms of cross-browser compatibility too.
<html>
<head>
<style type="text/css">
div.box {
background: #EEE;
height: 100px;
width: 500px;
}
div.left {
background: #999;
float: left;
height: 100%;
width: auto;
}
div.right {
background: #666;
height: 100%;
}
div.clear {
clear: both;
height: 1px;
overflow: hidden;
font-size: 0pt;
margin-top: -1px;
}
</style>
</head>
<body>
<div class="box">
<div class="left">Tree</div>
<div class="right">View</div>
<div class="right">View</div>
<div style="width: <=100% getTreeWidth()100 %>">Tree</div>
<div class="clear" />
</div>
<div class="ColumnWrapper">
<div class="Colum­nOne­Half">Tree</div>
<div class="Colum­nOne­Half">View</div>
</div>
</body>
</html>
You can try CSS Grid Layout.
dl {
display: grid;
grid-template-columns: max-content auto;
}
dt {
grid-column: 1;
}
dd {
grid-column: 2;
margin: 0;
background-color: #ccc;
}
<dl>
<dt>lorem ipsum</dt>
<dd>dolor sit amet</dd>
<dt>carpe</dt>
<dd>diem</dd>
</dl>
flex-grow - This defines the ability for a flex item to grow if necessary. It accepts a unitless value that serves as a proportion. It dictates what amount of the available space inside the flex container the item should take up.
If all items have flex-grow set to 1, the remaining space in the container will be distributed equally to all children. If one of the children has a value of 2, the remaining space would take up twice as much space as the others (or it will try to, at least). See more here
.parent {
display: flex;
}
.child {
flex-grow: 1; // It accepts a unitless value that serves as a proportion
}
.left {
background: red;
}
.right {
background: green;
}
<div class="parent">
<div class="child left">
Left 50%
</div>
<div class="child right">
Right 50%
</div>
</div>
A slightly different implementation,
Two div panels(content+extra), side by side, content panel expands if extra panel is not present.
jsfiddle: http://jsfiddle.net/qLTMf/1722/
You can use W3's CSS library that contains a class called rest that does just that:
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<div class="w3-row">
<div class="w3-col " style="width:150px">
<p>150px</p>
</div>
<div class="w3-rest w3-green">
<p>w3-rest</p>
</div>
</div>
Don't forget to link the CSS library in the page's header:
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
Here's the official demo: W3 School Tryit Editor
Im not sure if this is the answer you are expecting but, why don't you set the width of Tree to 'auto' and width of 'View' to 100% ?
I wrote a javascript function that I call from jQuery $(document).ready(). This will parse all children of the parent div and only update the right most child.
html
...
<div class="stretch">
<div style="padding-left: 5px; padding-right: 5px; display: inline-block;">Some text
</div>
<div class="underline" style="display: inline-block;">Some other text
</div>
</div>
....
javascript
$(document).ready(function(){
stretchDivs();
});
function stretchDivs() {
// loop thru each <div> that has class='stretch'
$("div.stretch").each(function(){
// get the inner width of this <div> that has class='stretch'
var totalW = parseInt($(this).css("width"));
// loop thru each child node
$(this).children().each(function(){
// subtract the margins, borders and padding
totalW -= (parseInt($(this).css("margin-left"))
+ parseInt($(this).css("border-left-width"))
+ parseInt($(this).css("padding-left"))
+ parseInt($(this).css("margin-right"))
+ parseInt($(this).css("border-right-width"))
+ parseInt($(this).css("padding-right")));
// if this is the last child, we can set its width
if ($(this).is(":last-child")) {
$(this).css("width","" + (totalW - 1 /* fudge factor */) + "px");
} else {
// this is not the last child, so subtract its width too
totalW -= parseInt($(this).css("width"));
}
});
});
}
This is fairly easy using flexbox. See the snippet below. I've added a wrapper container to control flow and set a global height. Borders have been added as well to identify the elements. Notice that divs now expand to the full height as well, as required.
Vendor prefixes should be used for flexbox in a real world scenario since is not yet fully supported.
I've developed a free tool to understand and design layouts using flexbox. Check it out here:
http://algid.com/Flex-Designer
.container{
height:180px;
border:3px solid #00f;
display:flex;
align-items:stretch;
}
div {
display:flex;
border:3px solid #0f0;
}
.second {
display:flex;
flex-grow:1;
border:3px solid #f00;
}
<div class="container">
<div>Tree</div>
<div class="second">View</div>
</div>
.btnCont {
display: table-layout;
width: 500px;
}
.txtCont {
display: table-cell;
width: 70%;
max-width: 80%;
min-width: 20%;
}
.subCont {
display: table-cell;
width: 30%;
max-width: 80%;
min-width: 20%;
}
<div class="btnCont">
<div class="txtCont">
Long text that will auto adjust as it grows. The best part is that the width of the container would not go beyond 500px!
</div>
<div class="subCont">
This column as well as the entire container works like a table. Isn't Amazing!!!
</div>
</div>
.container{
display: flex;
align-items: stretch;
}
.resize_overflow {
position: relative;
width: 0;
overflow: hidden;
white-space: nowrap;
word-wrap: normal;
/* text-overflow: ellipsis; When the end of the line dissolves, the ellipsis loses */
}
.second_fix {
float: right;
/* or:
display: flex;
align-self: end;*/
}
/* Dissolve the end of the line at the right edge */
.resize_overflow::after {
content: ""; /* Empty content */
position: absolute; /* Position relative to parent */
right: 0; /* Element position */
top: 0; /* Element position */
width: 40px; /* Gradient width */
height: 100%; /* Parent Height */
background: -moz-linear-gradient(left, rgba(255,255,255, 0.2), #ff 100%);
background: -webkit-linear-gradient(left, rgba(255,255,255, 0.2), #ff 100%);
background: -o-linear-gradient(left, rgba(255,255,255, 0.2), #ff 100%);
background: -ms-linear-gradient(left, rgba(255,255,255, 0.2), #ff 100%);
background: linear-gradient(to right, rgba(255,255,255, 0.2), #ff 100%);
}
<div class="container">
<div class="resize_overflow">Tree</div>
<div class="second_fix">View</div>
</div>
Have a look at the available CSS layout frameworks. I would recommend Simpl or, the slightly more complex, Blueprint framework.
If you are using Simpl (which involves importing just one simpl.css file), you can do this:
<div class="Colum­nOne­Half">Tree</div>
<div class="Colum­nOne­Half">View</div>
, for a 50-50 layout, or :
<div class="Colum­nOne­Quarter">Tree</div>
<div class="Colum­nThreeQuarters">View</div>
, for a 25-75 one.
It's that simple.
If both of the widths are variable length why don't you calculate the width with some scripting or server side?
<div style="width: <=% getTreeWidth() %>">Tree</div>
<div style="width: <=% getViewWidth() %>">View</div>