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
Related
How could I make the effect of below picture with HTML, CSS using the the bootstrap framework?
I need two adjacent divs with trapezoid shape (or separated by a diagonal line). Both need to have a border.
You can do this by drawing a shape in CSS.
You can draw such a triangle in CSS by playing with different borders (top, right, bottom left) of an element that has zero width.
Example: https://css-tricks.com/snippets/css/css-triangle/
In the example below I use the pseudo element :after for this effect:
/* Apply styles to both DIVs */
.container > div {
width: 50%;
float:left;
font-weight: bold;
padding-left: 10px;
/* include padding in the height/width */
box-sizing: border-box;
margin: 0;
}
.container {
/* One way to make the DIV height extend to full heihgt of `float:left` DIVs inside it. Not the only way */
clear: both;
}
.container div:first-child {
background: #66ff66;
/* The triangle will be position:absolute, so it requires a `position:relative` parent */
position: relative;
/* We are drawing a full rectangle later, so we hide the rest of it */
overflow: hidden;
}
.container div:last-child {
background: #ff6666;
}
.container div:first-child:after {
position: absolute;
display: block;
content: ' ';
padding: inherit;
box-sizing: border-box;
/* Change below units (you can use px not just em)
to make the line become at different angles */
border-top: 1.3em solid transparent;
border-bottom: 1.3em solid transparent;
border-right: 1.3em solid #ff6666;
right: 0;
top: 0;
}
<div class="container">
<div>div١</div>
<div>div٢</div>
</div>
Update
But as you indicated in the comment, you wanted a different answer that uses div2 for the triangle, so here you are:
/* Apply styles to both DIVs */
.container > div {
width: 50%;
float:left;
font-weight: bold;
/* include padding in the height/width */
box-sizing: border-box;
margin: 0;
}
.container {
/* One way to make the DIV height extend to full heihgt of `float:left` DIVs inside it. Not the only way */
clear: both;
}
.container div:first-child {
background: #66ff66;
padding-left: 10px;
}
.container div:last-child {
background: #ff6666;
position: relative;
padding-left: 1.3em;
}
.container div:last-child:before {
position: absolute;
content: '';.
width: 0;
height: 0;
box-sizing: border-box;
/* Change below units (you can use px not just em)
to make the line become at different angles */
border-top: 1.3em solid #66ff66;
border-bottom: 1.3em solid transparent;
border-right: 1.3em solid transparent;
top: 0;
left: 0;
}
<div class="container">
<div>div١</div>
<div>div٢</div>
</div>
Update 2
The picture you showed in comments also included real borders. This requires changing the approach. The new approach still uses :before, but adds border to it, and rotates it 45 degrees.
The idea is based on an example from: https://kilianvalkhof.com/2017/design/sloped-edges-with-consistent-angle-in-css/
To imagine it:
Here's the code:
/* Apply styles to both DIVs */
.container > div {
width: 50%;
float:left;
font-weight: bold;
/* include padding in the height/width */
box-sizing: border-box;
margin: 0;
}
.container {
/* One way to make the DIV height extend to full heihgt of `float:left` DIVs inside it. Not the only way */
clear: both;
}
.container div:first-child {
background: #66ff66;
padding-left: 10px;
border: 1px solid;
border-right: none;
}
/*
The following assumes diemnsions 1.3em * 1.3em
Your real case can change the number
*/
.container div:last-child {
background: #ff6666;
position: relative;
border: 1px solid;
border-left: none;
padding-left: calc(1.5 * 1.3em);
overflow: hidden;
}
.container div:last-child:before {
position: absolute;
content: '';
width: calc(2 * 1.3em);
height: calc(2 * 1.3em);
box-sizing: border-box;
background: #66ff66;
border: 1px solid ;
transform:rotate(45deg);
margin-top: -1.3em;
margin-left: -1.3em;
left: 0;
top: 0;
}
<div class="container">
<div>div١</div>
<div>div٢</div>
</div>
just use border-right like following code snippet and see result :
.parent{
width: 100%;
display: flex;
background-color: #01579b;
}
.div1 {
width: 30%;
border-bottom: 100px solid #000;
border-right: 50px solid transparent;
}
.div2 {
width: 70%;
height: 100px;
}
<div class="parent">
<div class="div1"></div>
<div class="div2"></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>
I'm trying to create some CSS to have a icon or image in the center with a line on both sides, but it seems like i'm doing something wrong and need some help.
For simplicity I just use a star character in the code.
<div class='line-container'><div class='line-icon'>*</div></div>
.line-icon {
text-align: center;
}
.line-icon::before {
width: 25%;
height: 1px;
border: 1px solid #ccc;
}
.line-icon::after {
width: 25%;
height: 1px;
border: 1px solid #ccc;
}
Try adding a content to your ::after and ::before, and setting its display:
.line-icon {
text-align: center;
}
/* Joined both selectors, since were pretty much the same */
.line-icon::before,
.line-icon::after {
/* Styles kept */
width: 25%;
height: 1px;
/* Changed to border-top (instead of border) to simulate a line better */
border-top: 1px solid #ccc;
/* Styles added */
display: inline-block;
content: '';
/* Use padding to vertical align the line */
/* Use padding in em for a responsive icon height */
padding-top: 0.5em;
/* Use margins to give the lines some spacement around the icon */
/* Use margins in % for a responsive spacement */
margin-left: 5%;
margin-right: 5%;
}
<div class='line-container'><div class='line-icon'>*</div></div>
A different style but may be usefull for u
.seperator {
padding: 0;
border: 0px;
border-top: 1px solid #ccc;
color: #000;
text-align: center;
}
.seperator:after {
content: "vs";
display: inline-block;
position: relative;
top: -0.7em;
font-size: 1.5em;
padding: 0 0.50em;
background: #fff;
}
<hr class="seperator"></hr>
I've recreated my issues with this jsfiddle
My date div on the right get moved down if the window becomes too small when re-sized (thinking mobile device view)
Is it possible to re-size the text area and keep the date div at the top when re-sized?
I've included two screen showing the issue when re-sized.
Screen 1
Screen 2 (re-sized)
My current css looks like this:
div.thumbnail_image {
float: left;
height: 64px;
position: relative;
width: 64px;
}
.widget-content {
padding: 12px 15px;
border-bottom: 1px solid #cdcdcd;
}
.msg-list {
border-top: 1px solid #DDDDDD;
padding: 10px 12px;
}
.msg-list span {
display:block;
}
.msg-list .msg-date {
display: block;
border: solid 1px #00ff00;
color: #BBBBBB;
float: right;
margin: 0 0 0 0;
text-align: center;
width: 50px;
}
.msg-list .msg-date .msg-month {
display: block;
font-size: 19px;
font-weight: bold;
margin-bottom: -4px;
}
.msg-summary {
border: solid 1px #ff0000;
display: block;
float: left;
max-width: 70%;
}
One way to achieve that is to remove the float: left from .msg-summary and give it a margin to the right to reserve the space for the date-div, see http://jsfiddle.net/ZybhC/2/
You can achieve such a design by ordering your elements like this:
image
date
text
All you need then is float the image div left, float the date div right, apply margin to the text div equal to the other divs width:
.middle {
float:none;
margin:0 64px;
}
.date {
float:right;
}
.msg {
width:50%;
min-width:200px;
}
Demo: http://jsbin.com/ofevot/1/edit
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.