I have this setup
HTML:
body, html {
margin: 0;
height: 100%;
}
.cont{
border:solid 1px red;
display:inline-block;
}
.left {
float: left;
width: 300px;
height: 30px;
border:solid 1px #000;
}
.big{
width:600px;
}
.right {
border:solid 1px #000;
min-width:200px;
overflow: auto;
height: 30px;
padding-left:5px;
padding-right:10px;
padding-top:3px;
background:green
}
<div class='cont'>
<div class='left'>1</div>
<div class='left'>2</div>
<div class='left big'>3</div>
<div class='left big'>4</div>
<div class='right'>Dynamic Div</div>
</div>
Codepen link for those who prefer that
I need the 'right' div to be placed on the right of div 4. What happens is, if there is leftover space of >=200px after placing the numbered divs, the input text div gets squeezed in there. I don't want that.
Essentially the 'right' div always needs to be on the right of the last numbered div, and filling in the remaining space on the right. If the remaining space is less than 200px, the div should move to the next row.
Each of the numbered divs will have varied widths, although that probably doesn't matter here.
Can I achieve this without jquery?
Thanks.
EDIT: I was able to get this done using flexbox
.cont{
border:solid 1px red;
display:flex;
flex-wrap: wrap;
}
.right {
flex-grow:1;
border:solid 1px #000;
.....
}
Using flex boxes it is possible to get this done.
View it on jsfiddle.
Snippet (updated with width: fit-content):
body, html {
margin: 0;
height: 100%;
}
.cont {
border: solid 1px red;
/*display: inline-block;*/
display: flex; /* added */
flex-wrap: wrap; /* added */
width: -webkit-fit-content; /* chrome 22+, opera 15+, safari 6.1+ */
width: -moz-fit-content; /* firefox 3+ */
width: fit-content; /* default */
}
.left {
border: solid 1px #000;
float: left;
height: 30px;
/*width: 300px;*/
min-width: 300px; /* added */
max-width: 300px; /* added */
box-sizing: border-box; /* added */
}
.big {
/*width: 600px;*/
max-width: 600px; /* added */
min-width: 600px; /* added */
}
.right {
border: solid 1px #000;
min-width: 200px;
overflow: auto;
height: 30px;
padding-left: 5px;
padding-right: 10px;
padding-top: 3px;
background: green;
flex: 1; /* added */
}
<div class='cont'>
<div class='left'>1</div>
<div class='left'>2</div>
<div class='left big'>3</div>
<div class='left big'>4</div>
<div class='right'>Dynamic Div</div>
</div>
You can learn more about flexboxes from these links:
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes
http://www.w3schools.com/css/css3_flexbox.asp
Related
I'm trying to build a tooltip for my items using flexboxes to align content inside them.
Here is a little image of how I imagined it would look:
here is my CSS code attempt of the image above:
.hud-tt-container {
display: flex;
width: 100%;
height: auto;
box-sizing: border-box;
}
.hud-tt-info-container {
width: auto;
height: 64px;
flex-grow: 1;
border: 1px solid yellow;
box-sizing: border-box;
}
.hud-tt-info-block {
width: auto;
height: 32px;
border: 1px solid grey;
box-sizing: border-box;
}
.col-full {
width: 100%;
height: 32px;
float: left;
border: 1px solid gray;
box-sizing: border-box;
}
.col-half {
width: 50%;
height: 32px;
float: left;
border: 1px solid gray;
box-sizing: border-box;
}
.hud-tt-lv-container {
width: 64px;
height: 64px;
flex-grow: 0;
border: 1px solid blue;
box-sizing: border-box;
}
<div class="hud-tooltip f16 fwhite">
<div class="hud-tt-container">
<div class="hud-tt-info-container">
<div class="col-full"></div>
<div class="col-half"></div>
<div class="col-half"></div>
</div>
<div class="hud-tt-lv-container">
<canvas id="Bar"></canvas>
</div>
</div>
</div>
I'm currently using col class to arange them this way. This way it also works, but I want to use flexboxes for this, so to use hud-tt-info-block
The level and info container align just as I want them to. Level container takes 64x64px, while info container takes all the space left. But I'm not sure how to align info blocks the way i want them to be using flexbox
Using flexbox to align col classes is very important due to large numbers. Flexbox can adapt width as numbers get bigger, whereas my current solution doesn't work well with large numbers
You can nest flex elements, where adding display: flex to the .hud-tt-info-container being a flex item, it also becomes a flex container, and its children becomes flex items and so on.
See notes in CSS
.hud-tt-container {
display: flex;
}
.hud-tt-info-container {
flex-grow: 1; /* fill remaining space */
display: flex; /* added */
flex-wrap: wrap; /* added, allow items to wrap */
height: 64px;
}
.hud-tt-info-block {
height: 32px;
border: 1px solid gray;
box-sizing: border-box;
}
.col-full {
flex-basis: 100%; /* changed, take full width and push
the other items to a new row */
}
.col-half {
flex-basis: 50%; /* changed */
}
.hud-tt-lv-container {
width: 64px;
height: 64px;
border: 1px solid blue;
box-sizing: border-box;
}
<div class="hud-tooltip f16 fwhite">
<div class="hud-tt-container">
<div class="hud-tt-info-container">
<div class="hud-tt-info-block col-full"></div>
<div class="hud-tt-info-block col-half"></div>
<div class="hud-tt-info-block col-half"></div>
</div>
<div class="hud-tt-lv-container">
<canvas id="Bar"></canvas>
</div>
</div>
</div>
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
I use the above code to display a big div with two divs in it. For the first one I use position: absolute to place it on bottom left of the div.
How can I extend the height of the second gray one so that it's 5 pixels above the first, but without having to measure its exact height in pixel (like the pic below)? I can set height: 50px; for example but is there another way?
I would use a flexbox approach rather than absolute positioning (comments in css below)
div.div1 {
display: flex;
flex-direction:column;
/* add the above styles*/
border: 1px solid black;
min-height: 100px; /*I would also change this to min-height otherwise it may cause issues if your text goes to 2 lines*/
width: 100px;
padding: 10px;
}
div.div2 {
flex-grow:1; /* make div grow to fill the space */
margin-bottom:5px; /* minus the amount of margin you wanted */
background-color: gray;
border: 1px solid black;
padding: 10px;
}
div.div3 {
/* remove absolute positioning */
border: 1px solid red;
height: 20px;
width: 20px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
EDIT: I suggest that, if you can focus on the modern browser features, going the flexbox way as shown by Pete is definitely a cleaner approach than the ones I've shown bellow. That being said, here are the alternatives:
You can use calc to dynamically determine the height of div2:
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(
100%
- 20px /* div1: padding top and bottom */
- 2px /* div1: border top and bottom */
- 20px /* div3: height */
- 2px /* div3: border top and bottom*/
- 5px /* desired separation*/
);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
You can avoid including padding and border width in your calculations if you set the box-sizing for your divs to border-box (You might want to set this for all elements):
div {
box-sizing: border-box;
}
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(
100%
- 20px /* div3: height */
- 5px /* desired separation */
);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
There's this rather new, hip CSS property called 'flex' which you're now going to love because it does it exactly that without the need of positioning absolute etc. I did something similar yesterday where I had a vertical nav bar and I wanted one menu at the top and one at the bottom. In a responsive environment; using your approach of positioning absolute it would've resulted in a nasty mess of working out heights to stop the content from overlapping. Flex prevented this! Yeyyyyy
https://css-tricks.com/snippets/css/a-guide-to-flexbox/
In your example you want to do something like this:
.div1 {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
justify-content: space-around;
}
.div2 {
align-self: flex-start;
flex-grow:1;
width:100%;
}
.div3 {
align-self: flex-end;
width:100%;
}
Now your div 3 will always be at the bottom. Although now .div3 will extend the entire width so within the div insert your content and BOOM done.
You can use calc on the heightsetting as in my snippet below. That setting is 100% minus (20 + 10 + 2) for the height, border and bottom of the lower DIV minus (5 + 2) for the distance and the border of the first DIV minus 10px for the padding of the parent, summing up to 49px .
div.div1 {
position: relative;
border: 1px solid black;
height: 100px;
width: 100px;
padding: 10px;
}
div.div2 {
background-color: gray;
border: 1px solid black;
padding: 10px;
height: calc(100% - 49px);
}
div.div3 {
position: absolute;
border: 1px solid red;
height: 20px;
width: 20px;
bottom: 10px;
left: 10px;
}
<div class="div1">
<div class="div2">Test 123</div>
<div class="div3">A</div>
</div>
http://s4.postimg.org/mbrpxn2d9/Untitled.png
Edit: Not a duplicate. The other question doesn't contain information about divs being automatically adjusted to the words on the inside.
I have 4 divs. I have 3 divs inside another div, and I'm trying to float one to the left, one to the center, and one to the right. I'm also trying to make the width and height of the divs on the inside to be automatically adjusted to the width and height of the words on the inside of the divs. I also want the divs on the inside to stack up on top of each other, instead of being on the same line. So far, I got the left div to float to the left, and the right div to float to the right, but I just cannot get the middle div to be centered, nor get it to adjust to the width and height of the word inside of it. Please take a look at my code:
#outer {
border: 1px solid black;
width: 500px;
height: 500px;
}
#innerLeft {
border: 1px solid red;
float: left;
}
#innerMiddle {
border: 1px solid red;
margin: auto;
}
#innerRight {
border: 1px solid red;
float: right;
}
<div id='outer'>
<div id='innerLeft'>Left</div>
<div id='innerMiddle'>Middle</div>
<div id='innerRight'>Right</div>
</div>
Depending on the output of the image, I think flexbox solution would be a good way to go.
Let the container have a flexible layout with column wrapping.
Align each item based on position in the container i.e. flex-start, center and flex-end
#outer {
display: flex;
display: -ms-flex;
flex-flow: column wrap; /* Wrap the items column wise */
justify-content: flex-start; /* Items to start from the top of the container */
border: 1px solid black;
width: 500px;
height: 500px;
}
#innerLeft {
align-self: flex-start; /* Equivalent to float: left of your code */
border: 1px solid red;
}
#innerMiddle {
align-self: center; /* Equivalent to margin: auto */
border: 1px solid red;
}
#innerRight {
align-self: flex-end; /* Equivalent to float: right */
border: 1px solid red;
}
<div id='outer'>
<div id='innerLeft'>Left</div>
<div id='innerMiddle'>Middle</div>
<div id='innerRight'>Right</div>
</div>
If changing your HTML just a bit is an option, you can add span elements in your divs which will give you want, and it will work in all browsers:
#outer {
border: 1px solid black;
width: 500px;
height: 500px;
}
#innerLeft {
text-align:left;
}
#innerMiddle {
text-align:center;
}
#innerRight {
text-align:right;
}
div > div > span {
border: 1px solid red;
}
<div id='outer'>
<div id='innerLeft'><span>Left</span></div>
<div id='innerMiddle'><span>Middle</span></div>
<div id='innerRight'><span>Right</span></div>
</div>
This is what you mean?? I had Edited
#outer {
border: 1px solid black;
width: 500px;
height: 500px;
}
#innerLeft {
border: 1px solid red;
/* width: 30%; */
float: left;
}
#innerMiddle {
border: 1px solid red;
float: left;
margin: 0 5px;
}
#innerRight {
border: 1px solid red;
float: right;
}
<div id='outer'>
<div id='innerLeft'>LeftLeftLeftLeft</div> <br>
<div id='innerMiddle'>MiddleMiddleMiddleMiddle</div> <br>
<div id='innerRight'>RightRightRightRight</div>
</div>
write your html tags like this hope it help!
<div id='outer'>
<div id='innerRight'>Right</div>
<div id='innerLeft'>Left</div>
<div id='innerMiddle'></div>
</div>
How can i make a parent div (red) stretchable so that min number of chidren inside it can be one and maximum number can be 3 after which the fourth div sets vertically down automatically.
My css for inner div is
.inner_div {
min-height: 238px;
border-bottom: 1px dashed #e7e7e7;
border-right: 1px dashed #e7e7e7;
border-top: 1px dashed #e7e7e7;
border-left: 1px dashed #e7e7e7;
padding-top: 10px;
padding-bottom: 10px;
float: left;
padding: 9px;
width: 200px;
background-color: white;
}
and css for parent (outer div) is
.outer_div {
padding: 0 20px;
margin-top: 55px!important;
margin-bottom: 33px!important;
background: white;
border-left: 1px dashed #e7e7e7;
overflow: hidden;
max-width: 611px;
min-width: 223px;
width: auto;
}
Let's Get Fluid!
There are a lot of answers here!
The following example works across all screen sizes / widths for up to 3 boxes across.
That #media is used to give and take borders away at each viewport width, one column up to three columns. It also re-sizes the outer div for each step, and changes the background colour, etc if wanted. Refer to the comments in the snippet for a basic explanation of what's going on.
This example can consume as many or as few boxes as you want. Open it full screen and resize to see the results.
Update - I have given the inners a dark green background and the outer is display: inline-block to resize with its contents.
* {
box-sizing: border-box;
/* incorporate padding into width (.outer_div padding is excluded) */
}
.outer_div {
margin: 50px;
display: inline-block;
max-width: 640px;
min-width: 240px;
/* 200 * 3 across + 40 .outer_div padding = 640 */
padding: 20px;
/* transition? yes! on re-size! */
transition: background 1s;
transition: max-width 0.05s;
}
.inner_div {
min-height: 238px;
/* BORDER ALL THE THINGS!!!*/
border: 1px dashed #000;
float: left;
padding: 9px;
/* padding is accounted for in the width thanks to border-box */
width: 200px;
background: #0a8f08;
}
/* Clear the floats at the very end */
.outer_div:after {
content: ' ';
display: block;
clear: left;
}
/* 3 boxes across */
/*#media sizes increase and decrease dependant on inner box width and outer_div padding */
#media screen and (min-width: 756px) {
.outer_div {
background: #a3e9a4;
}
/* Remove all bottom borders */
.inner_div {
border-bottom: none
}
/* Remove every middle border */
.inner_div:nth-child(3n+2) {
border-right: none;
border-left: none;
}
/* Last child gets a right border */
.inner_div:last-child {
border-right: 1px dashed #000;
}
/* last three get a bottom border */
.inner_div:nth-last-child(-n+3) {
border-bottom: 1px dashed #000;
}
}
/* 2 boxes across */
#media screen and (min-width: 573px) and (max-width: 755px) {
.outer_div {
max-width: 440px;
background: #dcedc8;
}
/* Remove all bottom borders */
.inner_div {
border-bottom: none;
}
/* Remove every second border */
.inner_div:nth-child(2n) {
border-left: none;
}
/* last two get a bottom border */
.inner_div:nth-last-child(-n+2) {
border-bottom: 1px dashed #000;
}
}
/* 1 box across */
#media screen and (max-width: 572px) {
.outer_div {
max-width: 240px;
background: #f0f4c3;
}
/* Remove all bottom borders */
.inner_div {
border-bottom: none;
}
/* last one gets a border */
.inner_div:last-child {
border-bottom: 1px dashed #000;
}
}
<div class="outer_div">
<div class="inner_div"></div>
<div class="inner_div"></div>
<div class="inner_div"></div>
<div class="inner_div"></div>
<div class="inner_div"></div>
<div class="inner_div"></div>
</div>
You should probably add some pixels to you outer_div's max-width, otherwise 3 inner_divs just don't fit:
max-width: 660px;
And then clear every third inner_div:
.inner_div:nth-of-type(3n+1) {
clear: left;
}
Here's a jsfiddle.
Just change your outer div css with this
.outer_div {
padding: 0 20px;
margin-top: 55px!important;
margin-bottom: 33px!important;
background: white;
border-left: 1px dashed #e7e7e7;
overflow: hidden;
max-width: 100%;
min-width: 223px;
}
You can try following code change parameter as your needs proportionally.
display:inline-block; can do the tricks
.outer_div{
display:inline-block;
max-width:300px;
height:300px;
background-color:red;
overflow:auto;
}
.inner_div{
width:100px;
height:100px;
background-color:black;
float:left;
}
In inner-div class add this line
display:inline-block;
and outer-div must be like this
.outer_div {
padding: 0 20px;
margin-top: 55px!important;
margin-bottom: 33px!important;
background: white;
border-left: 1px dashed #e7e7e7;
overflow: hidden;
max-width: 669px;
min-width: 223px;
}
You can always change max-width to get more free space for fourth block or remove third block!
Use the :nth-child pseudo class.
To make the parent div stretchable, add a float: left or display: inline-block.
.outer_div {
padding: 0 20px;
margin-top: 55px!important;
margin-bottom: 33px!important;
background: white;
border-left: 1px dashed #e7e7e7;
overflow: hidden;
width: auto;
float: left;
clear: both;
margin: auto;
}
.inner_div {
min-height: 238px;
border: 1px dashed #e7e7e7;
float: left;
padding: 9px;
width: 200px;
background-color: white;
}
.inner_div:nth-child(3n+1) {
clear: left;
}
You can see the result in jsfiddle.
I would use something like flexbox for this kind of thing.
There would be a lot of possibilities/combinations, and would also be very easy to edit if required.
The likes of:
.parent {
display: flex;
height: 300px; /* Or whatever */
}
.child {
width: 100px; /* Or whatever */
height: 100px; /* Or whatever */
margin: auto; /* Magic! */
}
Here's an example of just one possibility.
Browser support:
See here
My case is as follows. I have a div with two children divs. I'd like the 'event' div to be 300px of width and height. First requirement is to keep the size of the 'event' div when 'content' and 'bar' elements use 100% of parent's width. Secondly as for now, borders of 'content' element are not visible. Is it possible to fit everything inside without using hardcoded values and get this display properly in most of the modern browsers (FF, Chrome, Opera, IE7+) ?
This is what I'd like to achieve (notice the left red bar which takes 100% height and doesn't collide with the grey border around the event element):
And this is what I have. Html :
<div id="wrapper">
<div id="scheduler">
<div class="event" style="top: 30px; height: 300px; width: 300px">
<div class="bar"></div>
<div class="content">
<div class="inner-content">Some text</div>
</div>
</div>
</div>
</div>
, css :
#wrapper {
width: 600px;
height: 600px;
}
#scheduler {
background-color: #E1FFFE;
display: block;
height: 100%;
width: 100%;
padding: 0 10px;
position: relative;
}
#scheduler .event {
display: block;
float: left;
position: relative;
width:100%;
overflow:hidden;
}
#scheduler .event .bar {
background-color: red;
display: inline;
float: left;
height: 100%;
position: relative;
width: 5px;
}
#scheduler .event .content {
background-color: white;
border: 1px solid #CCCCCC;
border-left: none;
display: inline;
float: left;
height: 100%;
position: absolute;
width: 100%;
}
and a runnable demo :
http://jsfiddle.net/6nTvD/1/
Try this. Take out the bar div, then change the .content css to:
#scheduler .event .content {
background-color: white;
border: 1px solid #CCCCCC;
border-left: 5px solid red; // replaces the bar
display: inline;
float: left;
height: 99%; // a bit of a hack to fit the border in
position: relative;
width: 98%; // hack
}
http://jsfiddle.net/Dp3yz/
EDIT: Code with the .bar still in place:
#scheduler .event .bar {
background-color: red;
display: inline;
float: left;
height: 99.9%; /* Small offset at bottom */
position: relative;
width: 5px;
}
#scheduler .event .content {
background-color: white;
/* revised border */
border-top: 1px solid #CCCCCC;
border-right: 1px solid #CCCCCC;
border-bottom: 1px solid #CCCCCC;
display: inline;
float: left;
height: 99%;
position: absolute;
width: 98%;
}
New version:
http://jsfiddle.net/JJrC9/1/
I don't think I fully understand your quandary, however, with the only difference I can spy between your desired outcome and your current work being the presence of the borders -- switching overflow:hidden; on #scheduler .event to overflow:visible; produces something that visually looks to me like it achieves the desired affect.