Is there a way to resize grid boxes? - javascript

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>

Related

How to move fixed div by scroll amount?

I've seen others use overflow-y:scroll to make a div move with scroll almost like a scrollbar, however my fixed css configuration doesn't let that work.
I just have a div.
<div class="scrollBar"></div>
.scrollBar {
width: 2px;
height: 45px;
background: white;
margin-left: 46%;
overflow-y: scroll;
position: fixed;
}
I've now tried to animate the div moving up or down with the scroll event using jquery/Tweenlite, however this isn't eloquent/effective.
var multi = event.deltaY >= 0 ? 1 : -1;
var change = (multi * 10).toString + "px";
TweenLite.to($('.scrollBar'), 1, {
"margin-top": change
});
How can I do this either via css or jquery?
css/html for the frame that houses the scroll bar:
<div class="frame">
<div id="rightCol">
<p>[</p>
<div class="scrollBar">
</div>
<p>]</p>
.frame {
display: grid;
width: 100vw;
height: 100vh;
grid-template-areas:
"leftCol topBar rightCol"
"leftCol center rightCol"
"leftCol bottomCol rightCol";
grid-template-rows: 10% 80% 10%;
grid-template-columns: 10% 80% 10%;
padding: 3.2rem;
z-index: 10000;
}

How to set element to grow horizontally instead of breaking to a new line?

I'm facing problem with breaking the line on website. What do I mean?
HTML code
<main class="clearfix">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</main>
<button>Add</button>
With such HTML code I'd like to have:
fixed height on main element (for example 80vh)
fixed height for all the elements first and third 40vh + second 80vh
fixed width for first and third element 50vw
fluid width for second element - but this is main problem - second element has to be in the same place and grow horizontally (to create scroll on the bottom of the site)
Please find my codepen
I've added button that'll add pixels to second element - but it destroys my website.
I'm not sure if flexbox is better than floats.
I'll appreciate any tip.
Here is the snippet:
let counter = 0;
document.querySelector("button").addEventListener("click", function() {
document.querySelector(".second").style.width = `calc(50% + ${counter}px)`;
console.log(counter);
counter++;
});
* {
padding: 0;
margin: 0;
}
main {
max-height: 80vh;
}
.first,
.third {
height: 40vh;
width: 50vw;
background-color: black;
float: left;
}
.third {
background-color: red;
}
.second {
height: 80vh;
width: 50%;
float: right;
background-color: blue;
}
.clearfix::after {
content: "";
display: table;
clear: both;
}
<main class="clearfix">
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</main>
<button>Add</button>
I would suggest you to go with position properties. Since you have a little difference between the order of your DOM element and their visual representation, like 1,2,3 in the DOM, but visually it's more like 1,3,2.
However, in such situation float is your enemy. I'm not 100% sure about flex, AFAIK flex would keep all the elements inside the parent element and prevent the scrolling.
If you go with absolute positioning, (since you already have the heights and widths defined)
Apply:
position: relative to the main element, it will be the base point of the child elements if they are set to absolute.
overflow-x: scroll to the main element. it will allow you to scroll horizontally when you increase the width of your second element.
position: absolute on .first, .second, .third, as you have the height and width defined, now set their position accordingly, check the snippet, you'll get it.
Finally you're good to add more value to your width of the target element.
Tip: always keep a consistency in your css units, for example, if used vh / vw use this for similar elements at least, or if px / em / rem is used, try to use the same accordingly.
Check the snippet in full page mode
let counter = 0;
document.querySelector("button").addEventListener("click", function() {
document.querySelector(".second").style.width = `calc(50vw + ${counter}vw)`;
document.querySelector("#added").textContent = counter;
counter++;
});
* {
padding: 0;
margin: 0;
}
main {
overflow-x: scroll;
position: relative;
min-height: 80vh;
}
.first,
.third {
height: 40vh;
width: 50vw;
background-color: black;
position: absolute;
left: 0;
top: 0;
}
.third {
background-color: red;
top: 40vh;
}
.second {
height: 80vh;
width: 50vw;
background-color: blue;
position: absolute;
left: 50vw;
top: 0;
}
button {
margin: 30px 5px;
border: 1px solid #cecece;
padding: 5px 10px;
}
<main>
<div class="first"></div>
<div class="second"></div>
<div class="third"></div>
</main>
<button>Add</button>
<p><span id="added">0</span>vw Added to blue div's width</p>

Increase the height of all elements when one element increases (equal height columns)

I want all 100% height elements to expand when the size of the body expands.
In the example pressing the button will add a red div - the two columns adjacent should stretch to account for this. In the end all columns should reach the bottom completely, one with blue then red, the other two just blue.
I'm looking into flex, and it doesn't seem like this would work, but any suggestions are appreciated.
In any case best solution is CSS, but if this is impossible pure JS is also fine.
span = document.getElementsByTagName("span")[0];
function addelem() {
span.appendChild(document.createElement('div'));
};
html, body{
height: 100%;
}
span {
display: inline-block;
background-color: blue;
width: 30px;
height: 100%;
vertical-align: top;
}
div {
background-color: red;
width: 30px;
height: 30px;
}
<span><span></span></span>
<span></span>
<span><button onclick="return addelem()">+</button></span>
This is what I expect the frame to look like at the bottom after button is pressed and scrolled down:
EDIT
I changed the snippet so the button appends the div to an existing child and causes overflow, as per the comments below suggest.
An initial setting of a flex container is align-items: stretch. This means that flex items will expand to cover the full length of the container along the cross axis.
In a container with flex-direction: row, the cross axis is vertical, so items will expand to full height.
In your demo code, the divs (red) are being added as children of a span column (blue). These divs are being added to the end, forcing the column to grow.
In a row-direction flex container, with no heights specified that would override align-items: stretch, the other columns will follow suit.
span = document.getElementsByTagName("span")[0];
function addelem() {
span.appendChild(document.createElement('div'));
};
body {
display: flex;
min-height: 100vh;
}
body > span {
width: 30px;
margin-right: 5px;
background-color: blue;
display: flex;
flex-direction: column;
}
body > span:first-child span {
flex: 0 0 100vh;
}
div {
background-color: red;
width: 30px;
height: 30px;
}
button {
margin-bottom: auto;
}
<span><span></span></span>
<span></span>
<span><button onclick="return addelem()">+</button></span>
You should use Flexbox twice, once in the outer container, and once in the container containing the appended child elements.
Here is your modified code:
span = document.getElementsByTagName("span")[0];
function addelem() {
span.appendChild(document.createElement('div'));
};
html, body{
height: 100%;
/* new */
display: flex;
}
/* new */
body > span{margin-right: 4px;}
span {
/*display: inline-block;*/
background-color: blue;
width: 30px;
height: 100%;
vertical-align: top;
/* new */
display: flex;
flex-flow: column;
align-items: flex-end;
}
div {
background-color: red;
width: 30px;
height: 30px;
/* new */
flex: 1 0 auto;
}
<span><span></span></span>
<span></span>
<span><button onclick="return addelem()">+</button></span>

How to make div take all the height available?

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/

Proportionately increasing columns width

let's say I have number of columns of different width e.g.:
| 100 | 200 | 55 | 450 | empty space
And now I need to adjust the width of every column the way that the entire row fits in its container, and takes 100%.
I could of course set .row { max-width: 100% } and set the widest column to 100%, but I want to make it the way so every column takes available space proportionally. Any ideas?
You can use both display: table and display: table-cell.
As an example:
* {
box-sizing: border-box;
}
html, body {
width: 100%;
}
div {
width: 100%;
min-width: 100;
display: table;
}
div > div {
min-width: auto;
width: auto;
display: table-cell;
border-right: 1px solid #000;
text-align: center;
}
div > div:first-of-type {
border-left: 1px solid #000;
}
<div>
<div>ABCDE</div>
<div>FG</div>
<div>HIJKLM</div>
<div>N</div>
<div>OPQ</div>
<div>RSTUVWX</div>
<div>YZ</div>
</div>
Demo
You can also use percentages in your widths defining. (If you know the proportion of every element.)
div {
float: left;
}
#container {
width: 100%;
}
#e1 {
width: 30%;
}
#e2 {
width: 50%;
}
#e3 {
width: 20%;
}
<div id="container">
<div id="e1">XX</div>
<div id="e2">XX</div>
<div id="e3">XX</div>
</div>
Make sure your box-sizing is set correctly in CSS (box-sizing: border-box;), otherwise paddings and borders will overflow the width. :)

Categories

Resources