How to make div take all the height available? - javascript

I have this HTML:
<div>
<span></span>
<textarea></textarea>
</div>
The Span can take up one or more lines (depends on the text it has and size of the Div). I want the Textarea to take all of the height left in div.
Please no jQuery.
https://jsfiddle.net/ntme8Lt4/

The CSS/style tag for that would just be max-height:100%; and width:100%;
This would hold the div's size constant if it is set to a percentage of its parent container or a constant value like 900px.
Since the size of span is not known, just leave it unspecified so it auto-sizes to content.

There's a circular issue here - the height of the div is (normally) determined by the size of its components. You need something to break the circle and determine the height of either the div or the text area.

You can use offsetHeight to get the heights of the different elements, and from there it is just a calculation of the container - span element to find the remaining.
document.querySelector('textarea').style.height = (document.querySelector('div').offsetHeight-document.querySelector('span').offsetHeight)+'px'
http://jsfiddle.net/rhbritton/4eck8dua/1/

If you're just wanting to use pure CSS and without the needs of tables etc you could try this approach.
HTML:
<div>
<span>
Hello<br>
Hello<br>
Hello
</span>
<textarea></textarea>
</div>
CSS:
div {
width: 400px;
height: 300px;
overflow: hidden;
border: 1px solid red;
}
span {
width: 100%;
display: block;
background-color: red;
}
textarea {
width: 100%;
height: 100%;
background-color: blue;
}
JSFiddle
Let me know if this works for you.

You can use clientWidth and clientHeight if your willing to use pure JS:
Here is the fiddle
function test()
{
var div = document.getElementById("testDiv");
var span = document.getElementById("testSpan");
var textArea = document.getElementById("testTextArea");
var height = div.clientHeight - span.clientHeight;
textArea.style.height = (height - 5) + "px";
textArea.style.width = (div.clientWidth - 5) + "px";
}
test();
Reference

you can use flex
div
{
display: flex;
flex-direction: column; /*layout top to bottom*/
height: 300px;
width: 400px;
border: 1px solid red;
}
span
{
display: block;
background-color: red;
}
textarea
{
background-color: blue;
height: 100%;
width: 100%;
flex-grow: 1; /*take up remaining space in flex container*/
}
}
https://jsfiddle.net/ntme8Lt4/13/

Thanks to the "possible duplicate" I came up with this solution:
<div>
<span>Hello<br>World</span>
<b><textarea></textarea></b>
</div>
div
{
height: 300px;
width: 400px;
border: 1px solid red;
display: table;
}
span
{
display: block;
background-color: red;
}
b
{
height: 100%;
width: 100%;
display: table-row;
}
textarea
{
height: 100%;
width: 100%;
background-color: blue;
}
https://jsfiddle.net/c42go079/

Related

Is there a way to resize grid boxes?

I have a react app where I'm creating about a million grid boxes, all the boxes ought to fit into the immediate screen (I want each box to be tiny asf). I'm using js to calculate each box's height and width in relation to the number of boxes.
var numOfBoxes = 1000 // this number can change anytime
var [height, width] = `${100/numberOfBoxes}%`
I created the grid using a CSS I found on StackOverflow
#root {
width: 100vw;
height: 100vh
}
// I tried to use vh and vw to make the #root element fit the initial screen
.square-container {
display: flex;
height: 100%;
width: 100%;
flex-wrap: wrap;
}
.square {
position: relative;
flex-basis: calc(25% - 10px);
margin: 5px;
border: 1px solid;
box-sizing: border-box;
}
.square::before {
content: '';
display: block;
padding-top: 100%;
}
.square .content {
position: absolute;
top: 0; left: 0;
height: 100%;
width: 100%;
}
But the squares remain the same size when I try to increase or decrease numOfBoxes. I tried changing the height and width from the DevTools but to no avail.
It looks like this if I render 100 boxes or 1000
Can someone point me in the right direction?
You can add a CSS variable to the root element, use it as part of the grid class, and then update it with setProperty.
// Using a setTimeout for this demo, but you would
// be adding this to your render method I expect
function changeWidth(width, count = 1) {
document.documentElement.style.setProperty('--square-width', `${width}px`);
if (count < 5) setTimeout(changeWidth, 2000, width +=5, ++count)
}
changeWidth(5);
:root {
--square-width: 10px
}
.container {
display: grid;
grid-template-columns: repeat(3, var(--square-width));
grid-gap: 5px;
}
.container div {
background-color: red;
aspect-ratio: 1;
}
<div class="container">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

Three divs side by side causing problems

So, what I ultimately want to achieve is this:
https://s17.postimg.org/7zkpt511r/imgdivs.png
what I have so far:
<style type="text/css">
.wrapper{
height: 100%;
width: 100%;
}
.left{
float: left;
background: silver;
height: 100%;
}
.right{
background: silver;
float: right;
height: 100%;
}
canvas{
position: absolute;
height: 100%;
}
</style>
<div class = "wrapper">
<div class = "left"></div>
<canvas id="canvas"></canvas>
<div class = "right">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
var WIDTH = 200; //could be anything, comes from previous calculations
$('#canvas').css("width", WIDTH);
$('#canvas').css("left", (window.innerWidth - WIDTH) / 2);
$('.left').css("width", (window.innerWidth - WIDTH) / 2);
$('.right').css("width", (window.innerWidth - WIDTH) / 2);
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, WIDTH, window.innerHeight);
</script>
So a little explanation, the canvas in the middle is dynamic in it's width(calculated with javascript) and pre-decided with it's height(100%), it is placed in the middle of the page, and the two divs to it's sides should stretch accordingly and equally and fill the rest of the page. I have many problems in my code; the divs sometimes overflow one below another, the canvas for some reason doesn't fillStyle it's whole dimension and so on.
I am afraid to try to do it in flexbox since old browsers do not support it properly, and I need all browsers support. Thank you for your time.
To get the div height to work you need to add this to your css
html {
height: 100%;
}
body {
min-height: 100%;
}
Dont use position:absolute's it is not a good pratice for layouts
You can consider using display:flex for the same and consider using viewport width and height vw/vh
When you give your div width 100% and height 100% nothing gets effected to make it work you have to set html,body{width:100%,height:100%} which is not a good practice ,instead you can use vw/vh
check this snippet
.wrapper {
height: 100vh;
border: 1px solid black;
display: flex;
width: 100vw;
}
.left {
border-right: 1px solid;
background: silver;
height: 100%;
width: 20%;
}
.right {
background: silver;
width: 30%;
height: 100%;
border-left: 1px solid;
}
canvas {
width: 60%;
height: 100%;
}
<div class="wrapper">
<div class="left"></div>
<canvas id="canvas"></canvas>
<div class="right">
</div>
Solution without display:flex
.wrapper {
height: 100vh;
border: 1px solid black;
position: relative;
width: 100vw;
}
.left {
border-right: 1px solid;
background: silver;
height: 100%;
width: 20%;
position: absolute;
left: 0;
}
.right {
background: silver;
width: 30%;
height: 100%;
border-left: 1px solid;
float: right;
}
canvas {
width: 60%;
height: 100%;
}
<div class="wrapper">
<div class="left"></div>
<canvas id="canvas"></canvas>
<div class="right">
</div>
Hope it helps
CSS:
body {
margin:0;
height:100vh;
}
.wrapper{
display:table;
height: 100%;
width: 100%;
background-color:pink;
}
.left{
display:table-cell;
background-color: gray;
height: 100%;
}
.right{
background-color: blue;
display:table-cell;
height: 100%;
}
canvas{
display:table-cell;
height: 100%;
}
JS:
var WIDTH = 234; //could be anything, comes from previous calculations
$('#canvas').css("width", WIDTH+'px');
$('.left').css("width", (window.innerWidth - WIDTH) / 2+'px');
$('.right').css("width", (window.innerWidth - WIDTH) / 2+'px');
var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(0, 0, canvas.width, canvas.height);
DEMO: https://jsfiddle.net/zd75wq2e/4/
So, basically, you was close. I've removed absolute positioning and floats, and i've rather used css table. I hope it has good support in older browsers, too. And, yes, as mentioned in comment, fill problem is solved in last line of js.
I've been trying in this jsfiddle and I get a working solution. I added a float:left; to the wrapper and I removed all the height: 100%; because they're ignored by the browser. I just set the height according to the window element using JS.
I removed as well the position: absolute; on the canvas because is not needed to do what you need. Anyway if you need it for other purposes, my suggestion is then insert the canvas inside a div class="center" (for example) and apply the position absolute to the canvas inside that div.
Finally I added as well a $(document).ready(function(){ ... }); to ensure the JS code is executed when the page is completely loaded.
EDIT: The divs calculation is made using width: calc(50% - canvasWidth/2);,this way it is working as well when you resize the window. But I thing the most important thing is working using WIDTH is producing your error, but getting the $("#canvas").outerWidth() is working fine...

Resize child div element to fit in parent div on window resize

I have a div element (shown with red border in the image below), which I want to be able to fit in its parent div when the window is resized and not fall into the next line (the parent is the one with the green border).
I want the red div to have a starting width: 949px (in my current screen) in order to fit the entire space available as shown in the image, but be resizable, so that it doesn't fall into the next line if width: 949px is to much to fit.
In essence, I want it at all costs to cover the area it covers in the image even if in a narrower screen that means it will be like 10px wide.
How can I achieve this? Any solution using CSS, JavaScript or jQuery will be gladly accepted.
The image:
CSS:
#parent {
text-align: center;
width: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: inline-block;
}
#child1-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
display: inline-block;
}
#child2-row2 {
text-align: left;
vertical-align: middle;
width: 288px;
position: relative;
margin: 0 25px 0 25px;
display: inline-block;
}
#child3-row2 {/* The one with the red border */
vertical-align: middle;
height: 452px;
width: 949px;
overflow: hidden;
position: relative;
display: inline-block;
}
You can use flexbox to do this by using the flex-grow property.
HTML :
<div id="main">
<div id="box1">1</div>
<div id="box2">2</div>
<div id="box3">3</div>
</div>
CSS :
#main {
display: flex;
flex-flow: row;
width:100%;
min-height:50px;
}
#box1{
background-color:red;
width:100px;
}
#box2{
background-color:blue;
width:100px;
}
#box3{
background-color:green;
flex-grow: 1;
}
Here is a working JSFiddle
You can use css calc function for this. Support for calc seems to be quite good now.
As you have mentioned, the left side divs are of fixed width, say 120px each. Also suppose the margin between them is 30px. So, the total width left for your red div is 100% - (2*120 + 2*30)px i.e. (100% - 300px ).
#red-div
{
width: calc(100% - 300px);
}
Add % width or you can do following :
$(window).resize(function() {
var window_width = $(window).width();
var w1_width = $('.div1').width(); // The first element width
var w2_width = $('.div2').width(); // The second element width
var main_div_width = window_width - (w1_width+w2_width+gutter[i.e margin between all 3 elements]);
$('.main_div_width').css('width', main_div_width);
});

Why inner element width doesn't increase when dynamic content is added to outer container

When I add dynamic content to .innerright. Why doesn't the width of .a increase dynamically. What should I do it to make sure .a takes width of .innerright container dynamically. I use javascript code to add the content dynamically.
var list = '';
for (var i = 0; i < 100; i++) {
list = list + i + 's';
}
$('.innerright').append(list);
.outer {
width: 500px;
height: 200px;
background-color: red;
}
.innerleft {
width: 20%;
float: left;
height: 100%;
background-color: yellow;
}
.innerright {
width: 80%;
height: 100%;
float: left;
background-color: green;
overflow: scroll;
}
.a {
height: 20px;
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="outer">
<div class='innerleft'>
</div>
<div class='innerright'>
<div class="a">
</div>
</div>
</div>
It's because you set a calculated width on the container element and specifically tell the container to deal with overflowing content by adding a scroll bar.
As far the css is concerned the element is always at it's calculated width and the extra content just expands into the overflow area rather than affecting the container's width.
I'm not sure this is fixable in css alone while maintaining the overflow property to scroll. Everything is doing as it should, the elements are taking the widths they should take and that is being maintained throughout dynamic content editing - overflow is not part of width.
You could use the javascript scrollWidth value and use that to dynamically edit the width of the .a element.
See the fiddle here
The important bit is:
$('.a').width($('.innerright')[0].scrollWidth);
which gets the scroll width of the .innerright element, that includes the width and the overflow and uses that to set the width of the .a element, which also now goes into the overflow area.
And of course, you'll need to call and recall this after you add any dynamic content!
NB, the [0] means get the first element in the array of DOM nodes returned by the JQuery call.
As others pointed out, block elements don't grow, they overflow. You're CSS makes that overflow scrollable. In order to acheive your goal, wrap the content (<a> and text) in an inline-block element, which will grow, and now you're <a> will receive it's parent (grown) width, and the <div> will still have scrollable overflow:
var list = '';
for (var i = 0; i < 100; i++) {
list = list + i + 's';
}
$('.contentspan').append(list);
.outer {
width: 500px;
height: 200px;
background-color: red;
}
.innerleft {
width: 20%;
float: left;
height: 100%;
background-color: yellow;
}
.innerright {
width: 80%;
height: 100%;
float: left;
background-color: green;
overflow: scroll;
}
.a {
height: 20px;
border: 1px solid red;
}
.contentspan {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="outer">
<div class='innerleft'>
</div>
<div class='innerright'>
<span class='contentspan'>
<div class="a">
</div>
</span>
</div>
</div>
By the way, this has nothing to do with dynamic content or JS. If the text was inlined in the HTML you'd get the exact same results.

Emulating a fixed sidebar template issues

am trying to emulate this theme:
http://themetrust.com/demos/ink/?project=the-city-of-samba
But instead make the blog post always remain centered in the right hand side (space outside of the fixed sidebar) and have the blog post be of a % width.
I currently have this set up on my site, but am using a percentage based sidebar which looks awful.
Here is a JSfiddle recreating in basic terms the theme from above:
http://jsfiddle.net/Uyv6w/4/
All i am after is to make that grey inner div always remain centered inside the red content div.
Incase JSFiddle goes down and for future ref:
HTML:
<div id="container">
<div id="sidebar"></div>
<div id="content">
<div id="inner"></div>
</div
</div>
CSS:
* {
margin: 0; padding: 0;
}
html, body {
width: 100%;
height: 100%;
background-color: #333;
}
#container {
height: 100%;
width: 100%;
}
#sidebar {
height: 100%;
width: 100px;
background-color: #9b59b6;
position: fixed;
}
#content {
width: 100%;
background-color: #f00;
}
#inner {
width: 60%;
margin-left: 150px;
background-color: #888;
height: 1000px;
}
Thanks.
There are just 2 properties to change in ordre to make this work the way you want :
#content {
/* width: 100%; */
margin-left: 100px; /* the width of you sidebar.
Since #content is a div, a block-level element
, its width will be automatically 100%
, minus the margins */
background-color: #f00;
}
#inner {
width: 60%;
/* margin-left: 150px; */
margin-left: auto;
margin-right: auto; /* having margin-left & right set to auto will center your div.
you could also use "margin: 0 auto" */
background-color: #888;
height: 1000px;
}
I have updated you JSFiddle example here : http://jsfiddle.net/Uyv6w/5/
http://jsbin.com/requv/1/edit
if you set body, html (and the container) to height 100%, it will not be able to to scroll.
the height should be more then 100%.

Categories

Resources