How to make divs fill the width of its parent? - html

I want my divs(.give, .sep, .take) to fill its parent(.trade)'s width.
HTML code:
<div class="trade">
<div class="give"></div>
<div class="sep"></div>
<div class="take"></div>
</div>
CSS code:
.trade {
position: relative;
width: 90%;
height: 80px;
border: 1px solid black;
}
.give,
.take {
height: 100%;
display: inline-block;
}
.sep {
width: 20px;
height: 100%;
border-left: 1px solid black;
border-right: 1px solid black;
display: inline-block;
}
But, .give,.take{width:auto;} did not fill it.
I also tried:
.give,
.take {
position:absolute;
width:50%;
}
.sep {
position:absolute;
left:50%;
transform:translate(-50%,0);
}
.give {
left: 0;
}
.take {
right: 0;
}
But .give and .take invaded .sep's place.
How can I make it? I don't want to use Javascript if possible.
+) .give{margin-right:10px;} .take{margin-left:10px;} or .give{padding-right:10px;} .take{padding-left:10px;} didn't work and just expanded their width.

Is this the intended result? flexbox makes this fairly straightforward... The borders and the padding on .trade are for visual aid only
.trade{
display:flex;
flex-direction:row;
justify-content:space-around;
align-content:center;
border:1px solid red;
padding:1rem;
margin:0 auto;
float:none;
width:80%;
height:10rem;
}
.trade div{
border:1px solid black;
flex:1
}
.trade div:before{
content:attr(class)
}
<div class="trade">
<div class="give"></div>
<div class="sep"></div>
<div class="take"></div>
</div>

As said by G-Cyrillus, you shouldn't try to hack with float. inline-block is also completely unecessary and far to complicated for your purpose in this case.
The real tool is Flexbox. Add .trade { display: flex; } to the CSS to use flexbox.
Then you can use .give, .take { flex-grow: 1; } to make them extend to fill the entire parents width equally. Instead of using margins to seperate your 3 child elements, you can use .trade { column-gap: 20px; } instead.
.trade {
position: relative;
width: 90%;
height: 80px;
border: 1px solid black;
display: flex;
column-gap: 20px;
}
.sep {
width: 20px;
}
.give,
.take {
flex-grow: 1;
}
/* added for demonstration */
.trade {
background-color: red;
}
.give,
.sep,
.take {
background-color: blue;
}
<div class="trade">
<div class="give"></div>
<div class="sep"></div>
<div class="take"></div>
</div>

Related

How to add line after text using css? [duplicate]

Im trying to make a line after each of my h2 tags. I canĀ“t figure out how I should tell the width, cause the lenght of the h2 headlines is differ from h2 to h2.
I use the :after method to create lines
h2:after {
position: absolute;
content: "";
height: 2px;
background-color: #242424;
width: 50%;
margin-left: 15px;
top: 50%;
}
Check code here: http://jsfiddle.net/s9gHf/
As you can see the line get too wide, and make the website too wide.
You could achieve this with an extra <span>:
h2 {
font-size: 1rem;
position: relative;
}
h2 span {
background-color: white;
padding-right: 10px;
}
h2:after {
content: "";
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 0.5em;
border-top: 1px solid black;
z-index: -1;
}
<h2><span>Featured products</span></h2>
<h2><span>Here is a very long h2, and as you can see the line get too wide</span></h2>
Another solution without the extra <span> but requires an overflow: hidden on the <h2>:
h2 {
font-size: 1rem;
overflow: hidden;
}
h2:after {
content: "";
display: inline-block;
height: 0.5em;
vertical-align: bottom;
width: 100%;
margin-right: -100%;
margin-left: 10px;
border-top: 1px solid black;
}
<h2><span>Featured products</span></h2>
<h2><span>Here is a very long h2, and as you can see the line get too wide</span></h2>
External examples: First, Second
There's no need for extra wrappers or span elements anymore. Flexbox and Grid can handle this easily.
h2 {
display: flex;
align-items: center;
}
h2::after {
content: '';
flex: 1;
margin-left: 1rem;
height: 1px;
background-color: #000;
}
<h2>Heading</h2>
using flexbox:
h2 {
display: flex;
align-items: center;
}
h2 span {
content: "";
flex: 1 1 auto;
border-top: 1px solid #000;
}
<h2>Title <span></span></h2>
Here is another, in my opinion even simpler solution using a flex wrapper:
.wrapper {
display: flex;
align-items: center;
}
.line {
border-top: 1px solid grey;
flex-grow: 1;
margin: 0 10px;
}
<div class="wrapper">
<p>Text</p>
<div class="line"></div>
</div>
External link
I notice that there are some flexbox implementations but they don't explain why and how to use it.
First, we just need one element, for this example h2.
We will change the element's display behavior to display: flex
Then, we center vertically its child elements using align-items: center.
h2 {
...
display: flex;
align-items: center;
}
Then, let's draw the line using the pseudo-element after.
We add '' to the content property to draw the element (we must).
Now lets make it flexible using flex: auto. This means that our element is sized according to its width and height properties. It grows to absorb any extra free space in the flex container, and shrinks to its minimum size to fit the container. This is equivalent to setting flex: 1 1 auto.
Then we add an small gap between the text and the line using margin-left: 1rem.
Finally, we draw a black line using border-top: 1px solid #000.
h2::after {
content: '';
flex: auto;
margin-left: 1rem;
border-top: 1px solid #000;
}
Here is functional snippet.
h2 {
font-size: 1em; /* not needed */
display: flex;
align-items: center;
}
h2::after {
content: '';
flex: auto;
margin-left: 1rem;
border-top: 1px solid #000;
}
<h2>Normal title</h2>
<h2>Very long title to test the behavior of the element when the content is wider</h2>
This is the most easy way I found to achieve the result: Just use hr tag before the text, and set the margin top for text. Very short and easy to understand! jsfiddle
h2 {
background-color: #ffffff;
margin-top: -22px;
width: 25%;
}
hr {
border: 1px solid #e9a216;
}
<br>
<hr>
<h2>ABOUT US</h2>
Here is how I do this:
http://jsfiddle.net/Zz7Wq/2/
I use a background instead of after and use my H1 or H2 to cover the background. Not quite your method above but does work well for me.
CSS
.title-box { background: #fff url('images/bar-orange.jpg') repeat-x left; text-align: left; margin-bottom: 20px;}
.title-box h1 { color: #000; background-color: #fff; display: inline; padding: 0 50px 0 50px; }
HTML
<div class="title-box"><h1>Title can go here</h1></div>
<div class="title-box"><h1>Title can go here this one is really really long</h1></div>
I am not experienced at all so feel free to correct things. However, I tried all these answers, but always had a problem in some screen.
So I tried the following that worked for me and looks as I want it in almost all screens with the exception of mobile.
<div class="wrapper">
<div id="Section-Title">
<div id="h2"> YOUR TITLE
<div id="line"><hr></div>
</div>
</div>
</div>
CSS:
.wrapper{
background:#fff;
max-width:100%;
margin:20px auto;
padding:50px 5%;}
#Section-Title{
margin: 2% auto;
width:98%;
overflow: hidden;}
#h2{
float:left;
width:100%;
position:relative;
z-index:1;
font-family:Arial, Helvetica, sans-serif;
font-size:1.5vw;}
#h2 #line {
display:inline-block;
float:right;
margin:auto;
margin-left:10px;
width:90%;
position:absolute;
top:-5%;}
#Section-Title:after{content:""; display:block; clear:both; }
.wrapper:after{content:""; display:block; clear:both; }

Overflow clipped, rest of the content visible

Considering the following DOM distribution. I have a flexbox container with two children, one of them has a fixed size while the other shrinks with an overflow: hidden. I was wondering, however, if there is a way for the overflown content to remain visible without any impact on the flow of the DOM.
Fleshed out Example at Codepen
ul.current {
list-style: none;
display: flex;
width: 40%;
margin: 0 auto;
}
li {
overflow: hidden;
}
li:last-child {
flex-shrink: 0;
}
li div {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
li:last-child {
margin-top: 2rem;
}
li:last-child div {
background: red;
}
/* GOAL */
section {
margin: 0 auto;
width: 40%;
}
.item {
position: absolute;
}
.item:last-child {
margin-top: 2rem;
margin-left: 5rem;
}
.content {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
.item:last-child .content {
background: red;
}
<h3>Shrink the viewport to get an idea of what's the intended scenario</h3>
<ul class="current">
<li><div></div></li>
<li><div></div></li>
</ul>
<h3>Visual representation of the overlap behavior</h3>
<section>
<div class="item"><div class="content"></div></div>
<div class="item"><div class="content"></div></div>
</section>
What I want, basically, is for the images to "overlap" each other in a flexible context, meaning, a solution that would work on N cases.
Your issue may be more clear to resolve if you didn't use quite as much inline style. I added classes and css to your code to make it easier to read.
By adding flex-wrap:wrap; to the display:flex; on the section, the images wrap. I set the images to background-images, and the bg-size to cover. If you wish the first-listed image to display second, simply switch the divs.
Hope this helps
#imagedisp {
display: flex;
flex-wrap: wrap;
}
#div1 {
flex-shrink: 1;
/* overflow: hidden;*/
border: 1px dashed;
background-image: url("https://s3-media4.fl.yelpcdn.com/bphoto/xFlymSQW0weBqXjwZM6Y2Q/ls.jpg");
}
#div2 {
margin-bottom: 40px;
border: 1px dashed;
background-image: url("https://s3-media3.fl.yelpcdn.com/bphoto/_-U30Zk2XbUKe2fcdtEXLQ/o.jpg");
}
#div1,
#div2 {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
div {
min-width: 300px;
/*width:300px;*/
height: 100px;
}
<section id="imagedisp">
<div id="div1">
<!-- <img />-->
</div>
<div id="div2">
<!-- <img />-->
</div>
</section>
In order to have an overlap you have to either use positioned elements (which is not the best solution if you want to keep the element in-flow) or use negative margin.
Let's consider negative margin. The trick is to find a way to adjust the margin in order to create the overlap when the parent container will shrink.
Here is a basic example:
section {
max-width: 300px;
border: 1px solid;
animation:change 2s linear infinite alternate;
}
#keyframes change {
from {max-width: 300px;}
to {max-width: 100px;}
}
.item{
height: 80px;
min-width: 80px;
background:blue;
display: inline-block;
vertical-align:top;
margin-right:calc((100% - 200px)/2);
}
.item:last-child {
margin-top: 2rem;
background: red;
}
<section>
<div class="item">
</div>
<div class="item">
</div>
</section>
As you can see, the trick is to define the margin considering the width of the container (100%) and we will have two cases:
When the width is bigger than Xpx we have a positive margin and a normal behavior with spacing
When the width is smaller than Xpx we will have a negative margin and will have the overlap effect without wrapping.
We need to simply find the good way to define the margin in order to obtain the needed behavior. We may also consider media query in case we want a different behavior like having no margin and then overlapping:
section {
border: 1px solid;
font-size:0;
}
.item{
height: 80px;
min-width: 80px;
background:blue;
display: inline-block;
vertical-align:top;
}
.item:nth-child(odd) {
margin-top: 2rem;
background: red;
}
#media all and (max-width:350px) {
.item{
margin-right:calc((100% - 320px)/4)
}
}
<section>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
</section>
Another idea that work with nested element (like your intial code) is to keep the overflow visible and force the outer element to shrink using min-width:0.
ul.current {
list-style: none;
display: flex;
width: 40%;
margin: 0 auto;
animation:change 2s infinite linear alternate;
}
#keyframes change {
from {width:100%}
to {width:40%}
}
li {
min-width:0;
}
li div {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
li:nth-child(odd) {
margin-top: 2rem;
}
li:nth-child(odd) div {
background: red;
}
/* GOAL */
section {
margin: 0 auto;
width: 40%;
}
.item {
position: absolute;
}
.item:last-child {
margin-top: 2rem;
margin-left: 5rem;
}
.content {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
.item:last-child .content {
background: red;
}
<ul class="current">
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
</ul>

Center div on html line

I have a problem with html. I am trying to set a html line and on that line I have to set a div with text. Here is the example, but it is a photo. I would like to get this in html.
I hope someone can help me.
Edit:
I know how to get a line in html and I know how to get this yellow div with the text. The problem is. How do I get the yellow div on the line. This is my current result.
You can do this with Flexbox and pseudo-elements. Here is Fiddle
.element {
display: flex;
align-items: center;
}
.price {
background: #FEC538;
font-size: 30px;
font-weight: bold;
padding: 10px 40px;
border-radius: 50px;
}
.element:before,
.element:after {
content: '';
flex: 5;
height: 3px;
background: #C3C3C3;
}
.element:after {
flex: 1;
}
<div class="element">
<div class="price">Save 35%</div>
</div>
This will do it
<div class='c1'>
<span>save 35%</span>
</div>
.c1{
position:relative;
text-align:center;
}
.c1:before{
content:'';
height:2px;
width:100%;
background:#CDCCCD;
position:absolute;
top:50%;
left:0;
margin:-1px 0 0;
}
.c1 span{
display:inline-block;
padding:5px 15px;
background:#FEC538;
border-radius:20px;
position:relative;
}
see it here : https://jsfiddle.net/IA7medd/6tonuvg6/
That will do..
Html
<div class="center-div"></div>
**Css**
body
{
background-color: #fcfcfc;
}
.center-div
{
position: absolute;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100px;
height: 100px;
background-color: #ccc;
border-radius: 3px;
}
Set width, and set margin:auto;.
div.c2 {
margin:auto;
width:80px;
text-align:center;
/*color*/
background-color: #FEC538;
border-radius: 10px;
}
<div>
<div class=c2>Save 35%</div>
<div>

Two 50% width divs don't fit in parent

Sorry if it is a duplicate of something, I have searched honestly, but I still have the problem which is shown in this fiddle: http://jsfiddle.net/tfvdzzee/1/
The code here:
html
<div id="wrap">
<div id="one">1</div>
<div id="two">2</div>
</div>
css
#wrap
{
max-width: 400px;
margin: auto;
border: 2px solid black;
}
#one, #two
{
width: 50%;
background: green;
}
#two
{
float: right;
background: red;
}
I believe display: inline-block; is the best answer, as it prevents bugs of overlapping and overflowing, while also keeping its parent definitions.
JsFiddle Demo
HTML
<div id="wrap">
<div id="one">1</div><!--
--><div id="two">2</div>
</div>
CSS
#wrap
{
max-width: 400px;
margin: auto;
border: 2px solid black;
}
#one, #two
{
width: 50%;
background: green;
display: inline-block;
/* If worried about IE7 and IE6, add the two next lines */
*display: inline;
*zoom: 1;
}
#two
{
background: red;
}
Demo Fiddle
You need to both float:left the #one element as well as set overflow:hidden to the parent to ensure it wraps the children correctly.
Change your CSS to:
#wrap
{
max-width: 400px;
margin: auto;
border: 2px solid black;
overflow:hidden; /* <---ensure the parent wraps the children */
}
#one, #two
{
width: 50%;
background: green;
float:left; /* <---ensure the children display inline */
}
#two
{
float: right;
background: red;
}
Add the following style in your CSS.
#one{float:left}
DEMO
Remove the Css property for #two and add this
#one, #two
{
width: 50%;
background: green;
float: left;
}
Use float: left and you don't need float: right for #two.
#one, #two
{
width: 50%;
background: green;
float: left;
}
#two
{
background: red;
}
Fiddle example.
You will need to float both your divs. After the float, clear the float using the clearfix class.
CSS:
#one, #two{ float:left; }
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
HTML:
<div id="wrap" class="clearfix">
<div id="one">1</div>
<div id="two">2</div>
</div>
DEMO
#wrap
{
max-width: 400px;
margin: auto;
border: 2px solid black;
}
#wrap:after{
clear:both;
content:"";
display:block;
}
#one, #two
{
width: 50%;
float:left;
background: green;
}
#two
{
background: red;
}
Try this and use clearfix on the :after pseudo element of your #wrap div.
DEMO
To Expand on the comment by sifu and answer the question in a choice of ways
The first method (Using float's)
#wrap
{
max-width: 400px;
margin: auto;
border: 2px solid black;
}
#one,#two
{
float:left;
width:50%;
}
http://jsfiddle.net/tfvdzzee/7/
Display Inline-block method
#wrap
{
max-width: 400px;
margin: auto;
border: 2px solid black;
font-size:0px;
}
#one,#two
{
width:50%;
display:inline-block;
font-size:16px;
}
http://jsfiddle.net/tfvdzzee/8/
Both methods can be used however if you are still developing for IE7 (not sure why you would) then method 2 wont work.

Dynamically sized float expanding beyond container

Please see http://jsfiddle.net/jr32V/ which contains the following:
CSS:
body {
font-size: 2em;
color: white;
background-color: grey;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
.topmenu, .main {
width: 500px;
margin: 0 auto;
}
.topmenu {
background-color: red;
}
.main {
background-color: black;
}
.mainpicker {
margin-right: 20px;
float: left;
background-color: green;
}
.maincontent {
width: 600px; /*get rid of this line to see how it should look*/
float: left;
background-color: blue;
}
HTML:
<body>
<div class="topmenu">
A whole bunch of menu stuff
</div>
<div class="main">
<div class="mainpicker">
Picker
</div>
<div class="maincontent">
Content on right of picker
</div>
</div>
</body>
I would like the "maincontent" div to be exactly to the right of "mainpicker", just as it seems if you remove the width attribute on it.
Note that the width attribute is just to illustrate the point, in actual use the width may go beyond the container by any amount.
Also note that I do not want the parent container ("main") to exactly expand, since it must begin at the same left position as "topmenu". i.e. that they both have the same width vis-a-vis centering/margin-auto calculation
I think this is what you are looking for. Add width and margin to your .main class and remove float:left; from your .maincontent class. I updated your fiddle
.main {
background-color: black;
width:500px;
margin:0 auto;
}
.mainpicker {
margin-right: 20px;
float: left;
background-color: green;
width:100px;
}
.maincontent {
width: 600px;
background-color: blue;
}
EDIT:
If you want to float both children you have to stay inside the given width of you parent class. So your code would look like this:
.topmenu {
background-color: red;
width:500px;
margin:0 auto;
}
.main {
width:500px;
margin:0 auto;
}
.mainpicker {
background-color: green;
width:100px;
float:left;
}
.maincontent {
background-color: orange;
width:400px;
float:left;
}
You can watch it here
The following code seemed to do the trick, even though the result doesn't look pleasing to the eye.
.mainpicker {
margin-right: 20px;
float: left;
background-color: green;
display: inline-block;
position: relative;
}
.maincontent {
width: 600px;
float: left;
background-color: blue;
display: inline-block;
position: absolute;
width: auto;
}
DEMO: http://jsfiddle.net/thauwa/jr32V/5/
http://jsfiddle.net/jr32V/6/
i put box-sizing: border-box; and width as percentages to mainpicker and maincontent
.mainpicker {
float: left;
background-color: green;
width: 20%;
box-sizing: border-box;
}
.maincontent {
float: left;
background-color: blue;
width: 80%;
box-sizing: border-box;
}
does this help you?