Reputation: 574
flexbox like this:
display: flex;
flex-flow: row wrap;
and grid like this:
display: grid;
grid-template-columns: repeat(auto-fill, 20px);
dynamically arrange items, and the counts of rows and columns are not fixed.
I'm not sure it's one problem or two, as there may be different solutions for flexbox and grid. For now I ask in a time anyway.
How can I get the count of rows and columns? And further get item by row index and column index?
See https://jsfiddle.net/w2L8oumw/16/ as an example. Drag the frame border to make the width of the result window change, such that counts of rows and columns change, too.
My idea is to iterate all items and decide their row index and column index according to their position, on initializing, item changing and resizing.
Upvotes: 8
Views: 6888
Reputation: 493
The questions is al little bit older but in case anybody needs this:
If you are working with CSS-Grid you don't need so much calculation. You can get the current template settings e.g. with
getComputedStyle(container).getPropertyValue("grid-template-rows")
in modern Browsers this returns the actual values, not the values from your css, so you get a string like
250px 250px 250px
you can than calculate the current number of rows by splitting the string and counting the elements in the resulting array.
This might work in older IEs as well, I did not test it.
Upvotes: 7
Reputation: 1530
We need to calculate and find, please find below function function setrIdcId(containerId)
. Now I am calling on the button click. You can call when you required. (on the scroll or resize). Fiddle updated
var GetItemOfContainer = function (container, rIdx, cIdx) {
// solution code here
}
function setrIdcId(containerId){
_el = document.getElementById(containerId);
_boxes = _el.children;
var colCnt = Math.floor((_el.offsetWidth)/50); //Number of Column; 50:box width
var rowCnt = Math.ceil(_boxes.length/colCnt); //Number of Rows
for(var i = 0; i < _boxes.length; i++) {
var cIdx = Math.floor(i / colCnt); // X
var rIdx = Math.floor(i % colCnt); // Y
_boxes[i].innerHTML = cIdx +":"+ rIdx; // Print //
}
}
#flexbox{
display:flex;
flex-flow: row wrap;
height:30vh;
width:30vw;
background:black;
padding:5px;
margin:5px;
}
#flexbox > div{
height:40px;
width:40px;
background:purple;
margin:5px;
}
#grid{
display:grid;
grid-template-columns: repeat(auto-fill, 40px);
grid-gap: 10px;
height:30vh;
width:30vw;
background:black;
padding:5px;
margin:5px;
}
#grid > div{
height:40px;
/*width:40px;*/
background:purple;
}
<div id="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<button onClick="setrIdcId('grid')" type="button">Call
</button>
Upvotes: 0
Reputation: 2534
One sample solution for calculating the columns is given below for flexbox
, for row
and grid
you have to do similar calculation for row.
You may need to add or remove some calculation.
var getComputedValue = function (container, cssProp) {
return parseInt(window.getComputedStyle(container, null).getPropertyValue(cssProp).split('px')[0]);
};
var calcColms = function() {
var container = document.getElementById("flexbox");
var parentWidth = getComputedValue(container,"width");
var parentPaddingLeft = getComputedValue(container,"padding-left");
var parentPaddingRight = getComputedValue(container,"padding-Right");
var child = container.firstElementChild;
var childWidth = getComputedValue(child,"width");
var childMarginLeft = getComputedValue(child,"margin-left");
var childMarginRight = getComputedValue(child,"margin-right");
var parentWidthNoPadding = parentWidth - parentPaddingLeft - parentPaddingRight;
var childWidthWithMargin = childWidth + childMarginLeft + childMarginRight;
parentWidthNoPadding = parentWidthNoPadding + childMarginLeft + childMarginRight;
var noCols = parseInt(parentWidthNoPadding / childWidthWithMargin);
console.log(noCols);
}
window.onload = function () {
calcColms();
};
window.onresize = function () {
calcColms();
};
#flexbox{
display:flex;
flex-flow: row wrap;
height:30vh;
width:30vw;
background:black;
padding:5px;
margin:5px;
}
#flexbox > div{
height:40px;
width:40px;
background:purple;
margin:5px;
}
#grid{
display:grid;
grid-template-columns: repeat(auto-fill, 40px);
grid-gap: 10px;
height:30vh;
width:30vw;
background:black;
padding:5px;
margin:5px;
}
#grid > div{
height:40px;
/*width:40px;*/
background:purple;
}
<div id="flexbox">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<div id="grid">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Upvotes: 0