how to justify child divs with variable width inside parent div with fixed width.I want to justify child divs not only on single line but inside the whole parent container. Parent and Child elements are dynamically generated.
<div class="parent">
<div class="child">1.2345</div>
<div class="child">1:223345</div>
<div class="child">1:23421225</div>
<div class="child">1:2345</div>
<div class="child">1:235</div>
<div class="child">1:2345</div>
.
.
.
30 Child elements
</div>
CSS
.parent{
width:450px;
text-align:justify;
}
.child{
float: left;
margin: 2px;
}
output is something like this
UPDATED
Now i have set width to each child divs depending on its text length.
.parent{
width:250px;
text-align:justify;
border: 1px solid #ddd;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.child{
margin: 2px;
}
<div class="parent">
<div class="child">1.2345</div>
<div class="child">1:2345</div>
<div class="child">1:2345</div>
<div class="child">1:2345</div>
<div class="child">1:2345</div>
<div class="child">1:2345</div>
. . . 30 Child elements
</div>
demo add 30 +
Once all of your child divs have been added to the DOM, you could get the element with the greatest width and then set the width of each of the other divs.
var childDivs = [].slice.call(document.querySelectorAll("div.child"));
var maxWidth = Math.max.apply(null, childDivs.map(function(ele){
return ele.offsetWidth;
}));
for(var i = 0; i < childDivs.length; i++){
childDivs[i].style.width = maxWidth + "px";
}
CSS Flex box can do the job but you must ensure browser compatibility.
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
Also, there are a few concepts to understand before using flexbox. In the end, it can solve many CSS layout problems.
Ohterwise, you may need to use javascript to dynamically resize your elements.
Related
I have this code and the child's height is changing but the parent's height remains the same. I want a CSS code to make the parent's height the same as the child
<div class = "parent">
<div class="child">
</div>
</div
Note: using your HTML
if you add the CSS
<style>
.parent, .child {
width: 120px; height: 100px;
}
</style>
<div class = "parent">
<div class="child">
</div>
</div
both child and parent would have the same width and height of: 120, by 100. Change these values to suite what you need.
if you add this additional CSS lines:
.parent { border: 1px solid red; }
.child { border: 1px solid blue }
this will draw your border - in different colours, so you can see easily what is happening - you can remove this after
I have a <div class="row"> which will contain dynamically generated buttons (basically I need boxes)
I need the parent div to be of fixed size but need its contents to resize (to fit everything in one row) automatically based on number of buttons inserted.
Consider the following layout:
All of the solutions I have tried need fixed width or the boxes get plotted in new line.
My last option would be using ng-style and setting the width to 100/number of boxes. I need some other solution.
One of the things I have tried so far:
.wrap {
width:80%;
margin:0 auto;
}
.wrap div {
width:23%;
padding-bottom:23%;
margin:1%;
float:left;
background:gold;
}
<div class="wrap">
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
Use flexbox
div {
display: flex;
}
button {
flex: 1 1;
}
<div>
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
</div>
Ex. with your code.
.wrap {
width: 80%;
margin: 0 auto;
display: flex;
}
.wrap div {
flex: 1 1;
padding-bottom: 23%;
background: gold;
border: 1px solid;
}
<div class="wrap">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Just using flexbox won't cut it. If you need the box to maintain the square shapes on adding more boxes, you need to use a bit of javascript as well.
What are we doing?
We're adding more boxes and changing their height by maintaing an iterative variable(i) which checks how many boxes are present and divides the height according to the width. Since, the width is fixed if 3 boxes are present, the height should be equal to width of each item present.
You can implement a function which counts the number of boxes on load and resizes the flex container height according to it to have the boxes keep the square dimension.
var flex = document.getElementById("container");
var box = document.getElementById("box1");
var i=1;
function add() {
i++;
var cln = box.cloneNode(true);
cln.removeAttribute("id");
flex.appendChild(cln);
flex.style.height=(flex.clientWidth/i) + 'px';
}
.flexc {
display: flex;
width: 400px;
height:400px;
}
.box {
flex: 1;
border-radius: 20px;
background: olive;
margin:1px;
}
<button id="add" onclick="add()">Add more boxes</button>
<div class="flexc" id="container">
<div class="box" id="box1"></div>
</div>
My problem is that I want the flexbox with variable range width, and all works well, but not on the last row. I want the same dimension for all children even where the row is not full of children (the last row).
#products-list {
position:relative;
display: flex;
flex-flow: row wrap;
width:100%;
}
#products-list .product {
min-width:150px;
max-width:250px;
margin:10px 10px 20px 10px;
flex:1;
}
I created a dynamic situation in jsFiddle
My flex divs can shrink until 150px and grow up to 250px, but all must be with the same size (and obviously I want a CSS solution, with JS I know the way).
Unfortunately, in the current iteration of flexbox (Level 1), there is no clean way to solve the last-row alignment problem. It's a common problem.
It would be useful to have a flex property along the lines of:
last-row
last-column
only-child-in-a-row
alone-in-a-column
This problem does appear to be a high priority for Flexbox Level 2:
CSS Working Group Wiki - Specification Issues and Planning
https://lists.w3.org/Archives/Public/www-style/2015Jan/0150.html
Although this behavior is difficult to achieve in flexbox, it's simple and easy in CSS Grid Layout:
Equal width flex items even after they wrap
In case Grid is not an option, here's a list of similar questions containing various flexbox hacks:
Properly sizing and aligning the flex item(s) on the last row
Flex-box: Align last row to grid
Flexbox wrap - different alignment for last row
How can a flex item keep the same dimensions when it is forced to a new row?
Selector for an element alone in a row?
Aligning elements in last flexbox row
How can I allow flex-items to grow while keeping the same size?
Left-align last row of flexbox using space-between and margins
Inconsistent margin between flex items on last row
How to keep wrapped flex-items the same width as the elements on the previous row?
How to align left last row/line in multiple line flexbox
Last children of grid get giant gutter cause of flexbox space-between
Managing justify-content: space-between on last row
Flexbox space between behavior combined with wrap
Possible to use CSS Flexbox to stretch elements on every row while maintaining consistent widths?
As a quick and dirty solution one can use:
.my-flex-child:last-child/*.product:last-child*/ {
flex-grow: 100;/*Or any number big enough*/
}
You could try using grid instead of flexbox here:
#products-list {
display: grid;
grid-gap: 5px;
grid-template-columns: repeat(auto-fit, minmax(100px, 250px)); //grid automagic
justify-content: start; //start left
}
Fiddle link
There is a great solution that works always.
add a div with class product (The same class for other items that are under flex) and add a style for this div:height:0px;
you need to add as many dives that are possible to be in one row.
<div class="product" style="height:0px">
as many that can be in one row.
That's all. Works always.
If all your rows have the same number of items, you can use :nth-last-child. For example, if all the rows have 3 items, you can do something like this to remove the margin of the last 3 items:
.container{
display: flex;
flex-wrap: wrap;
background: yellow;
}
.item{
width: calc((100% - 2*10px)/3);
height: 50px;
background: blue;
color: white;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
/* last item of each row */
.item:nth-child(3n){
margin-right: 0;
font-size: 150%;
}
/* last 3 items */
.item:nth-last-child(-n+3){
margin-bottom: 0;
background: green;
}
<div class="container">
<div class="item" >1</div>
<div class="item" >2</div>
<div class="item" >3</div>
<div class="item" >4</div>
<div class="item" >5</div>
<div class="item" >6</div>
<div class="item" >7</div>
</div>
A simple trick adds a flexible space to fill the rest of the last row:
#products-list{
display:flex;
flex-flow: row wrap;
justify-content:space-between;
}
#products-list::after {
content: "";
flex: auto;
flex-basis: 200px;/*your item width*/
flex-grow: 0;
}
But you shouldn't use margins on items then. Rather wrap them into containers with padding.
I used this workaround, even if it's not very elegant and it doesn't use the power of Flexbox.
It can be carried out on the following conditions:
All the items have the same width
The items have a fixed width
You use SCSS/SASS (can be avoided though)
If this is the case, you can use the following snippet:
$itemWidth: 400px;
$itemMargin: 10px;
html, body {
margin: 0;
padding: 0;
}
.flex-container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 0 auto;
border: solid 1px blue;
}
#for $i from 1 through 10 {
#media only screen and (min-width: $i * $itemWidth + 2 * $i * $itemMargin) {
.flex-container {
width: $i * $itemWidth + 2 * $i * $itemMargin;
}
}
}
.item {
flex: 0 0 $itemWidth;
height: 100px;
margin: $itemMargin;
background: red;
}
<div class="flex-container">
<div class="item"></div>
<div class="item" style="flex: 500 0 200px"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
Here I have created an example on codepen which also implements margin.
The second and the third conditions can be avoided respectively using css variables (if you decided to provide support for it) and compiling the above scss snippet.
Well, it's true, we could do it also before flexbox, but display: flex can be still essential for a responsive design.
I was facing this same issue where I wanted to have a variable number of items in a resizable container.
I wanted to use all of the horizontal space, but have all of the flex items at the same size.
I ultimately came up with a javascript approach that dynamically added padding spacers as the container was resized.
function padLastFormRow() {
let topList = [];
let nSpacersToAdd = 0;
$('#flexContainer').find('.formSpacer').remove();
$('#flexContainer').find('.formItem').each(function(i, formItem) {
topList.push($(formItem).position().top);
});
let allRowLengths = getFlexLineLengths(topList);
let firstRowLength = allRowLengths[0];
let lastRowLength = allRowLengths[((allRowLengths.length) - 1)];
if (lastRowLength < firstRowLength) {
nSpacersToAdd = firstRowLength - lastRowLength ;
}
for (var i = 1; i <= nSpacersToAdd; i ++) {
$('#flexContainer').append(formSpacerItem);
}
}
Please see my Fiddle:
http://jsfiddle.net/Harold_Buchman/z5r3ogye/11/
I was having a similar challenge with menu rows. I wanted more spacing on the top of the second row of menu items.
The use of flex-box's row-gap worked well.
https://developer.mozilla.org/en-US/docs/Web/CSS/row-gap
.menu {
display: flex;
flex-wrap: wrap;
row-gap: 10px;
}
This added a margin-top type effect to menu items were wrapped to the second line.
If all your rows have the same number of items, you can use :nth-last-child. For example, if all the rows have 3 items, you can do something like this:
.container{
display: flex;
flex-wrap: wrap;
background: yellow;
}
.item{
width: calc((100% - 2*10px)/3);
height: 50px;
background: blue;
color: white;
margin-right: 10px;
margin-bottom: 10px;
padding: 5px;
box-sizing: border-box;
}
// last item of each row
.item:nth-child(3n){
margin-right: 0;
background: green;
}
// last 3 items
.item:nth-last-child(-n+3){
margin-bottom: 0;
font-size: 150%;
}
<div class="container">
<div class="item" >1</div>
<div class="item" >2</div>
<div class="item" >3</div>
<div class="item" >4</div>
<div class="item" >5</div>
<div class="item" >6</div>
<div class="item" >7</div>
</div>
I'm working on a project that uses several divs of the same class, each containing a single child element that might be an image or an iframe, of unspecified height. I'd like the container div to be exactly the height of its child element, but the default height is 3px taller than the child.
I've got a JSfiddle demonstrating the problem at http://jsfiddle.net/52me041n/2/.
HTML:
<div class="outside">
<img class="inside" id="pic" src="https://images.duckduckgo.com/iu/?u=http%3A%2F%2Fblogs.cisco.com%2Fwp-content%2Fuploads%2Fclouds.png&f=1" height="200px"/>
</div>
<br/>
<div class="outside">
<iframe class="inside" width="420" height="315" src="//www.youtube.com/embed/VwTnyRHEZSQ" frameborder="0" allowfullscreen></iframe>
</div>
CSS:
.outside{
background-color: red;
}
I'd like to know whether it's possible to set the div to the proper height with just CSS, and if not, how to right it with JS.
Updated the fiddle. http://jsfiddle.net/52me041n/3/
Use -
img, iframe {
display: block;
}
You need to set the display property to block for children inside the parent div. As a practice, I always also set margins and pads to 0 too. fiddle here
.outside > * {
margin: 0;
padding: 0;
display: block;
}
Images are not on the same baseline as text.
add
vertical-align:bottom;
to your img css
fiddle
For "I'd like to know whether it's possible to set the div to the proper height with just CSS, and if not, how to right it with JS." <== Yes,
<div id="cntr"> </div>
css :
#cntr { width : 100px; height : 100px; overflow : hidden; } /* overflow may have other values also like hidden, auto, scroll
*/
Try this code. Fiddle
.outside
{
background-color: red;
display: block;
}
.outside img, iframe {
float: left;
}
I have a element, which is absolute positioned and has a fixed height.
This element has a lot of child elements, which could change their contents, and in consequence their height.
The problem is that the container element doesn't auto expand to fit its children (because of it's fixed height and absolute position).
How can I can resize the main container to match its children height?
Assuming you can change the css, this can be done fairly simply in css. Instead of setting height simply set min-height and your element should expand thusly.
min-height
Optionally if you did want to/need to do it in jQuery something like the following would work:
html:
<div id='container'>
<div class='child'>Content</div>
<div class='child'>Content</div>
<div class='child'>Content</div>
<div class='child'>Content</div>
</div>
CSS:
.child{
height: 40px;
background-color: red;
}
#container{
height: 120px;
background-color: gray;
padding: 5px;
}
javascript:
var childHeight = 0
$('.child').each( function() {
childHeight = childHeight + $(this).height();
})
$('#container').height(childHeight);
Working example:
http://jsfiddle.net/EcZZL/1/