NOTE: This is only an issue in IE.
How can a force the textarea to vertically fill the table-cell div? I have applied height: 100% to all the parent elements, but the textarea still maintains its default height.
Screenshot:
Example of my problem: JSFiddle
Example code:
HTML
<div class="table">
<div class="row">
<div class="col col-sm">
<div class="thumbnail">Thumbnail</div>
</div>
<div class="col col-lg">
<textarea>Text area</textarea>
</div>
</div>
</div>
CSS
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.table {
display: table;
width: 100%;
height: 100%;
}
.row {
display: table-row;
height: 100%;
}
.col {
display: table-cell;
border: 1px dashed #FF0000;
padding: 5px;
vertical-align: top;
height: 100%;
}
.col-sm {
width: 30%;
}
.col-lg {
width: 70%;
}
.thumbnail {
height: 150px;
width: 200px;
border: 1px solid #CCC;
}
textarea {
width: 100%;
height: 100%;
}
According to this article, you'll see that what you're looking to do is impossible using a table-cell construction. Here's a fiddle demonstrating what happens when you remove all the height CSS. Spoiler alert: nothing happens, because none of your height tags have a value.
http://jsfiddle.net/py4gs/14/
Height/width CSS percentages are based off the closest parent with a defined height or width, excluding display: table* elements. In your case above, no such element exists, so none of the height tags have an effect.
I have encased your code in a body tag which has a defined width even though it is still relatively positioned. This is achieved by using an absolute positioning:
body {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
Fiddle: http://jsfiddle.net/py4gs/12/
As you can see, the textarea fills the container now. This is because your table has a height and all the other elements compute their height off of the table height.
Unfortunately, this solution is probably suboptimal for you, since it wouldn't work for multiple rows. There is no CSS-only solution for propagating the CSS computed height as the CSS actual height of a sibling in IE. You will need a height attribute defined on a parent and you can then propagate that down to the child.
There are options though. If it is absolutely necessary that the textarea be the same size of the thumbnail element, and the thumbnail height is indeed variable, then you can hook into a render event on your page (such as $(document).ready()) to grab the computed height and set this as the actual height:
$(document).ready(function() {
// avoid layout thrashing! read then write!
var heights = $('row').map(function(row) { return $(row).height(); });
$('row').each(function(i, el) {
$(el).height(heights[i]);
});
});
However, I'm a fan of non-jquery solutions. Therfore, I think the best solution might be to reconsider your layout. Use what you know about the thumbnail element to set the row height in advance or scale your thumbnail element. For example, if you are embedding a YouTube video as your thumbnail, you can scale the max-height of the iframe to 100% and manually set the row height to, say, 200px. If instead you are embedding an image, you could use CSS to scale the max-height and max-width of your image, which will respect aspect ratio (but is relatively computationally intensive), or you could preprocess your images and scale them to a desired height.
Unfortunately looks like IE doesn't support the CSS resize property, and thus cannot resize the textarea vertically. Might have to use a shim, like the answer here:
https://stackoverflow.com/a/9763121/2612012
EDIT this may or may not work, but you can try this:
$(document).ready(function() {
$('textarea').parent().resize(function() {
var $t = $(this);
$t.find('textarea').height($t.height());
}).resize();
});
jsfiddle
.col {
display: table-cell;
border: 1px dashed #FF0000;
padding: 5px;
vertical-align: top;
height:10px;
}
or you can give fixed height to the parent container (.table) which will automatically give full height to its children if set 100%
jsfiddle
.table {
display: table;
width: 100%;
height: 150px;
}
jsfiddle
<div class="col col-lg">
<div contenteditable='true' class='contenteditable'>Text area</div>
</div>
.contenteditable {
width: 100%;
height: 100%;
}
.contenteditable p{margin-top:0px; margin-bottom:0px;}
Since the size of the textarea is a percentage of the page (which changes responsively), I have coupled jQuery and the HTML rows attribute to create a temporary hack. The ratio is calculated based on what I know about the page size and percentages.
$(window).resize(function(){
var padding = 82;
var ratio = 0.009;
var rows = Math.floor(($('.main-container').width()-padding)*ratio);
$('.text-area').attr('rows',rows);
}).resize();
For those who may not want to use the great but as yet not fully supported css table properties, You can also do this. Should be browser-friendly, but I only tested in FireFox, IE and SlimJet. Multiple rows work fine. I set the text area at 90% for demonstration.
(Not sure what the goal is here - perhaps multiple images on the left and one big textarea - but this should work for that also.)
jsfiddle: https://jsfiddle.net/RationalRabbit/wpsqx8kh/7/
HTML:
<body>
<div class="table">
<div class="row">
<div class="col col-sm">
<div class="thumbnail">Thumbnail</div>
</div>
<div class="col col-lg">
<textarea>Text area</textarea>
</div>
</div>
<div class="row">
<div class="col col-sm">
<div class="thumbnail">Thumbnail 2</div>
</div>
<div class="col col-lg">
<textarea>Text area 2</textarea>
</div>
</div>
</div>
</body>
CSS:
* {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
.table {
width:500px;
height:100%px;
border:1px dashed blue;
}
.row {
height:200px;
}
.col {
float:left;
border:1px dashed #FF0000;
padding:5px;
vertical-align:top;
height:100%;
}
.col-sm {
width:30%;
}
.col-lg {
width:70%;
height:90%;
}
.thumbnail {
height:150px;
width:100%;
border:1px solid green;
}
textarea {
height:100%;
width:100%;
}
The easiest solution for me was to do it like this:
td{
position:relative;
}
textarea{
position:absolute;
top:0;
bottom:0;
left:0;
right:0;
}
Related
JsFiddle: http://jsfiddle.net/techsin/csfvb91u/
(just realized normal div is collapsing ALSO to size of content, is min height completely useless?)
I need two divs, one left, and on right. Left one is 100px wide and stays that way. While, right div expands infinitely and doesn't shrink beyond 400px. Both Divs should be the height of parent. And parent has no exact height but minimum height of 800. So if content of one of these 2 divs were to push the height of div and extend it. Then The height of parent should increase and thus also the height of other div.
I tried using floats. I managed to some extent. However left side which was on float left, its height kept collapsing and didn't follow height:100% rule. It only worked if parent had definite width.
I tried using inline block but then right div won't expand to fillin the available space..
Why in the world css doesn't have fit-content, fill-available, choose what % refers to, choose what to position against, use vector or use pngs to shape div, inset textshadow, etc.
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
try with display:table and display:table-cell for child you will need to give fixed with for the left div
demo - http://jsfiddle.net/z90fma6e/
html,
body {
height: 100%;
}
* {
margin: 0;
padding: 0;
}
.cont {
display: table;
height: 100%;
}
.left,
.right {
height: 100%;
}
.left {
width: 200px;
background: red;
display: block;
}
.right {
width: 100%;
display: table-cell;
background: green;
}
<div class="cont">
<div class="left">fixed
<br/>height adjusts</div>
<div class="right">expands
<br/>height adjusts</div>
</div>
Sounds like your divs are collapsing. Your going to need a clearfix you can add to divs. There are a few ways to do this; however, this option is best.
.clearfix:after {
content: ".";
visibility: hidden;
display: block;
height: 0;
clear: both;
}
Add this clearfix class and css to your divs so they wont collapse.
You can read more about them at cssTricks
perfect use case for CSS flex layout:
<style>
body {
display: flex;
flex-direction: row;
margin: 0;
padding: 0;
}
div:first-child {
width: 200px;
background: red;
}
div:last-child {
flex: 1;
background: blue;
}
</style>
<div></div>
<div></div>
If you wish to support IE8 or earlier I would suggest you to use positioning:
Here's what I came up with
Fiddle : http://jsfiddle.net/csfvb91u/4/
If the content on the right is going out of the container, you can always use margin-right:200px as the right side container is shifted 200px using left:200px. Hope you get what I'm saying... :)
HTML:
<div class="cont">
<div class="a"></div>
<div class="b"></div>
</div>
CSS:
.a {
position:absolute;
width: 200px;
background-color: green;
height: 100%;
}
.b {
width:100%;
position:absolute;
left:200px;
background-color: blue;
height: 100%;
}
.cont {
position:relative;
border:1px solid #333;
min-height:300px;
overflow:hidden;
}
Here i want to use two buttons which cover the entire screen width and the buttons should have equal width. And alo there should not be any space between these buttons.
I tried with the following HTML and CSS codes but i didn't get what i expect;
CSS
#container
{
width:100%
}
#button1
{
width:50%;
}
#button2
{
width:50% 100%;
}
HTML
<div id="container">
<button id="button1">Button1</button>
<button id="button2">Button2</button>
</div>
I tried the code here here the buttons not covering the entire screen size also a small gap is there between these two buttons. How to tackle this issue? Thank you..
Demo: http://jsfiddle.net/abhitalks/XkhwQ/7/
Q1: buttons not covering the entire screen size
The reason(s) are:
The box-model. By default the widths are calculated exclusive of paddings. In order to be safe, you should first set the box-sizing: border-box and reset the paddings and margins.
The container is 100% of what? Better, set the width on parent i.e. body.
You can mitigate this by:
* {
margin: 0; padding: 0; box-sizing: border-box; /* reset */
}
html, body {
width: 100%; /* specify width on parent */
}
.container {
width: 100%
}
button {
width: 50%; /* make the children equal */
}
.
Q2: also a small gap is there between these two buttons
The reason is:
The buttons are intrinsically inline elements and this means the white-space counts.
You can mitigate this in two ways:
Comment out the white-space.
Set the float on buttons.
Example 1 (using comments):
<div class="container">
<button>Button1</button><!--
--><button>Button2</button>
</div>
Example 2 (using floats):
.container > button {
float: left;
}
The demo (http://jsfiddle.net/abhitalks/XkhwQ/7/) covers and illustrates both issues.
.
Both of your buttons should have a width of 50% and be floated to the left or right
#button1, #button2
{
width:50%;
float:left;
}
Use this HTML
<div id="container">
<div class="btn-box"><button id="button1">Button1</button></div>
<div class="btn-box"><button id="button2">Button2</button></div>
<div style="clear:both;"></div>
</div>
& CSS
#container{width:100%}
.btn-box{display:block; width:50%; float:left;}
.btn-box button{display:block; width:100%;}
I think there is a typo on button2 class.
#button2
{
width:50%;
}
Apply float to buttons and make them 50% width:
.container {
width: 100%;
}
#button1,
#button2 {
float: left;
width: 50%;
}
Try This
<style>
.container {
width: 100%;
}
#button1,
#button2 {
float: left;
width: 50%;
background:#dbdbdb;
}
</style>
</head>
<body>
<div class="container">
<div id="button1">First Button Text</div>
<div id="button2">Second Button Text</div>
</div>
</body>
I want to split up the view in four parts. A header at the top, using full page width and fixed height.
The remaining page is split up in two blocks of the same height, the upper of them contains two same-sized blocks next to each other.
What I tried is (without the header):
#wrap {
width: 100%;
height: 100%;
}
#block12 {
width: 100%;
max-height: 49%;
}
#block1,
#block2 {
width: 50%;
height: 100%;
float: left;
overflow-y: scroll;
}
#block3 {
width: 100%;
height: 49%;
overflow: auto;
/*background: blue;*/
}
.clear {
clear: both;
}
<div id="wrap">
<div id="block12">
<div id="block1"></div>
<div id="block2"></div>
<div class="clear"></div>
</div>
<div id="block3"></div>
</div>
Apparently, using a percentage value for the height won't work that way. Why is that so?
add this to you CSS:
html, body
{
height: 100%;
}
working Fiddle
when you say to wrap to be 100%, 100% of what? of its parent (body), so his parent has to have some height.
and the same goes for body, his parent his html. html parent his the viewport..
so, by setting them both to 100%, wrap can also have a percentage height.
also:
the elements have some default padding/margin, that causes them to span a little more then the height you applied to them. (causing a scroll bar)
you can use
*
{
padding: 0;
margin: 0;
}
to disable that.
Look at That Fiddle
When you set a percentage height on an element who's parent elements don't have heights set, the parent elements have a default
height: auto;
You are asking the browser to calculate a height from an undefined value. Since that would equal a null-value, the result is that the browser does nothing with the height of child elements.
Besides using a JavaScript solution you could use this deadly easy table method:
#parent3 {
display: table;
width: 100%;
}
#parent3 .between {
display: table-row;
}
#parent3 .child {
display: table-cell;
}
Preview on http://jsbin.com/IkEqAfi/1
Example 1: Not working
Example 2: Fix height
Example 3: Table method
But: Bare in mind, that the table method only works properly in all modern Browsers and the Internet Explorer 8 and higher. As Fallback you could use JavaScript.
add this to your css:
html, body{height: 100%}
and change the max-height of #block12 to height
Explanation:
Basically #wrap was 100% height (relative measure) but when you use relative measures it looks for its parent element's measure, and it's normally undefined because it's also relative. The only element(s) being able to use a relative heights are body and or html themselves depending on the browser, the rest of the elements need a parent element with absolute height.
But be careful, it's tricky playing around with relative heights, you have to calculate properly your header's height so you can substract it from the other element's percentages.
Percentage in width works but percentage in height will not work unless you specify a specific height for any parent in the dependent loop...
See this :
percentage in height doesn’t work?
The div take the height of its parent, but since it has no content (expecpt for your divs) it will only be as height as its content.
You need to set the height of the body and html:
HTML:
<div class="block12">
<div class="block1">1</div>
<div class="block2">2</div>
</div>
<div class="block3">3</div>
CSS:
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.block12 {
width: 100%;
height: 50%;
background: yellow;
overflow: auto;
}
.block1, .block2 {
width: 50%;
height: 100%;
display: inline-block;
margin-right: -4px;
background: lightgreen;
}
.block2 { background: lightgray }
.block3 {
width: 100%;
height: 50%;
background: lightblue;
}
And a JSFiddle
Basically, the problem lies in block12. for the block1/2 to take up the total height of the block12, it must have a defined height. This stack overflow post explains that in really good detail.
So setting a defined height for block12 will allow you to set a proper height. I have created an example on JSfiddle that will show you the the blocks can be floated next to one another if the block12 div is set to a standard height through out the page.
Here is an example including a header and block3 div with some content in for examples.
#header{
position:absolute;
top:0;
left:0;
width:100%;
height:20%;
}
#block12{
position:absolute;
top:20%;
width:100%;
left:0;
height:40%;
}
#block1,#block2{
float:left;
overflow-y: scroll;
text-align:center;
color:red;
width:50%;
height:100%;
}
#clear{clear:both;}
#block3{
position:absolute;
bottom:0;
color:blue;
height:40%;
}
I want to create three, stacked divs. The top and the bottom ones will be of fixed height, whereas the one in the middle will have a dynamic height that expands to fill the remaining space:
I've tried numerous things, such as setting the height to auto. I do have a solution, but it involves JavaScript (i.e., calculating the remaining height) but I was wondering if there was a pure CSS solution.
There's a CSS solution, but it won't work in older browsers. You need to use the calc "function" that is new to CSS, combined with height: 100%. If you've never used height: 100% before, you know that every parent element of the one you want to be 100% tall must also be set to height:100%. calc can take a percentage value and subtract pixels from it, so you just need to set it to be 100% minus however tall the top and bottom divs are.
Supported by: IE9+, Firefox 4+, Chrome 19+, Safari 6+
http://caniuse.com/calc
HTML
<div id='top'></div>
<div id='mid'></div>
<div id='bot'></div>
CSS
html, body
{
height: 100%;
}
#top, #bot
{
height: 50px;
background: red;
}
#mid
{
height: calc(100% - 100px);
}
FIDDLE: http://jsfiddle.net/jakelauer/9cYUB/
One solution is to do it with position absolute.
The downside of this approach is that if the total height of surrounding is smaller then the sum of the fixed heights the container will not be visible anymore.
Another thing to be noted is that this is probably a bad solution if you want to target mobile devices. It always depends on the exact situation if this solution is suitable.
If i remember right you will only have problems with IE 6 (on desktop) which does not support the top bottom combination for the position absolute.
HTML
<div class="header"></div>
<div class="container"></div>
<div class="footer"></div>
CSS
.header, .container, .footer{
position: absolute;
outline: 1px solid black;
}
.header {
left: 0px;
top: 0px;
right : 0px;
height: 50px;
}
.container {
left: 0px;
top: 50px;
right : 0px;
bottom: 50px;
}
.footer {
left: 0px;
bottom: 0px;
right : 0px;
height: 50px;
}
JSFiddle
You can do it with a HTML table if you need older browser support, or if you need to support IE8+ or higher you could use the CSS table layout.
Here's a jsFiddle using CSS table layout.
HTML
<div>
<div>
<div>Fixed Height</div>
</div>
<div>
<div>
<div>Variable Height</div>
</div>
</div>
<div>
<div>Fixed Height</div>
</div>
</div>
CSS
html, body {
height:100%;
width: 100%;
margin: 0px;
padding: 0px;
text-align: center;
font-size: 20pt;
font-family: Verdana;
}
body > div {
display:table;
width: 100%;
height:100%;
}
body > div > div {
display: table-row;
}
body > div > div > div {
display: table-cell;
vertical-align: middle;
}
body > div > div:nth-child(odd) {
background: grey;
color: #FFF;
height: 100px;
}
body > div > div:nth-child(even) {
height:100%;
width:100%;
}
body > div > div:nth-child(even) >div {
height:100%;
width:100%;
overflow:hidden;
}
If i understand you request you need to use wrap div: http://www.cssstickyfooter.com/using-sticky-footer-code.html
In the following HTML, I want to specify the width of .left only if there is .right div in the .wrapper, otherwise it should take the full width. For example, if there is .right div, then the width of the .left should be 300px, otherwise it should be 500px.
I think this can be done using the css + selector, but if I am not sure how can I apply on the .left.
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
</div>
.wrapper{
width: 500px;
}
.left{
width: 300px;
}
.right{
width: 200px;
}
You can use the :only-child selector
.left:only-child
{
width: 100%;
}
Example
If you don't want to use the :only-child selector you could try the following
.wrapper
{
width: 500px;
min-height: 50px;
}
.left {
overflow: hidden;
min-height: 50px;
border: 1px dashed #f00;
}
.right {
float: right;
width: 200px;
min-height: 50px;
border: 1px dashed #00f;
}
Example
Instead of using CSS for this, why not using the HTML file?
From your question it seems that you have different HMTL files/output. If you add different classes in the HTML files, you can target them directly in CSS:
<div class="wrapper">
<div class="left"></div>
<div class="right"></div>
</div>
and
<div class="wrapper">
<div class="full"></div>
</div>
You CSS would contain something like this:
.wrapper {
width: 500px;
}
.left {
width: 300px;
}
.right {
width: 200px;
}
.full {
/* Whatever is required for full width */
}
Much easier this way! (Assuming you can change the HTML files/output)
I'd go for Veger's solution as well if you control the HTML output.
If not, the + selector only works for the latter element, thus with .left + .right you can change the right div if the left div is present. It doesn't work the other way around.
If you know, you'll always have a left div, you might put the right div into the left div and have it float right with a width of 200px.
There is no way that CSS can detect if an element exists or not, it is only for the presentation of elements.
You can however use javascript to do this. I will show you a jQuery version of it:
You have an element:
<div id="one">
My diiiv.
</div>
And you want to do something if this element exists:
$.fn.exists = function(callback) {
var args = [].slice.call(arguments, 1);
if (this.length) {
callback.call(this, args);
}
return this;
};
This is a function that will determine if an element exists when it's called.
What you can do now is to test if any element exists:
$('div#one').exists(function() {
this.append('<p>I exist!</p>');
});
So if it does, you can augment the DOM in whichever way you want. CSS cannot do this, that's what javascript and its libraries are for :)
http://jsfiddle.net/5Q2Gm/