I play with floats and I noticed then "float collapse bug" does not arise with fixed position. Here is example.
So I have two divs:
<body
<div class="static">
<img>
<p>text text text</p>
</div>
<div class="fixed">
<img>
<p>text text text</p>
</div>
</body>
First with static position and second with fixed:
.fixed, .static{
outline: 1px solid black;
width: 150px;
}
.fixed{
position: fixed;
left: 200px;
top: 200px;
}
img{
float: right;
background-color: green;
width: 100px;
height: 100px;
}
And result:
So why the second fixed-div does not need something like .clearfix to fix float collapse?
Because position: fixed; creates Block formatting context.
Try the below styles also, which have similar effect in your div.
float
position absolute and fixed
display - inline-blocks, table, table-cells
overflow - hidden, auto
if you want them both to appear the same you can put in overflow-y:hidden;
https://jsfiddle.net/1nq8b7xs/3/
or if you want them to appear beside each other use display:inline-block and remove position-fixed from your fixed class
https://jsfiddle.net/1nq8b7xs/4/
.fixed, .static{
outline: 1px solid black;
width: 150px;
overflow-y:hidden; /*added this*/
}
.fixed{
left: 200px;
top: 200px;
}
img{
float: right;
background-color: green;
width: 100px;
height: 100px;
}
.fixed, .static{display:inline-block;}
<body>
<div class="static">
<img>
<p>text text text</p>
</div>
<div class="fixed">
<img>
<p>text text text</p>
</div>
</body>
Related
I'm making a website that has a series of offset cards, one with image and one with text and I want to alternate the offset for each line. The only issue is I can't quite figure out how to (while keeping both in the wrapper) make the image smaller than the wrapper in height so that the text card can be at the top and overlap the top and side, like this:
Sorry for the image layout, it was supposed to be landscape. Anyway, the way I have it now, the parent and child are both at the top of the wrapper. I want it so that the text (child) is at the top and the image is slightly shorter so that I get the overlap/overlay effect from the text box on the top as well as the right. I also need to make sure, for responsiveness, that they stay inside the wraper. How should I fix that?
#wrapper{
background-color:green;
}
#parent{
width: 500px;
height:400px;
border: 4px solid blue;
background-size:cover;
}
#child{
width:300px;
height:200px;
border: 3px solid red;
position:relative;
top:0%;
left:80%;
}
<div id="container">
<div id="wrapper">
<div id="parent">
<div id="child">
This is my overlapping Text
</div>
</div>
</div>
</div>
I'm not sure this is exactly what you're going for, but if you add padding to the top of the wrapper, you can offset the child element.
#wrapper {
background-color: green;
padding-top: 50px;
}
#parent {
width: 500px;
height: 400px;
border: 4px solid blue;
background-size: cover;
}
#child {
width: 300px;
height: 200px;
border: 3px solid red;
position: relative;
top: -50px;
left: 80%;
}
<div id="container">
<div id="wrapper">
<div id="parent">
<div id="child">
This is my overlapping Text
</div>
</div>
</div>
</div>
Here's the fiddle:
https://jsfiddle.net/16f8mj39/
I have added z-index to position the text-box in front of image box.Check my code.
#container{ width:100%;position:relative; }
#wrapper{ width:100%;border:1px solid black;position:relative;overflow:auto;height:400px; }
#text_box{ position:absolute;border:1px solid red;width:50%;height:250px;top:10px;right:10px;z-index:1;background-color:red; }
#image_box{ position:absolute;border:1px solid blue; width:70%;height:300px;bottom:10px;left:10px;z-index:0;background-color:blue; }
<div id="container">
<div id="wrapper">
<p>Wrapper</p>
<div id="text_box">
<p>Text Box</p>
</div>
<div id="image_box">
<p>Image Box</p>
</div>
</div>
</div>
I want to move down the red div like my example but I still get extra space above the image div (class two), like the red div is still there in the top of the page.
How can I solve this in a better way? I don't want to use absolute position because my site is responsive and set the Image div (class two) to top: -50px sounds like bad solution.
.one {
top: 100px;
position: relative;
width: 100px;
height: 50px;
background-color: red;
}
<div class="one">Some text</div>
<div class="two">
<img src="http://via.placeholder.com/350x350">
</div>
.one {
top: 100px;
position: relative;
width: 100px;
height: 50px;
background-color: red;
margin-bottom: -50px;
}
<div class="one">Some text</div>
<div class="two">
<img src="http://via.placeholder.com/350x350">
</div>
I want a CSS solution (in principle HTML5/CSS3) that would reproduce the behaviour of the following table-based layout:
<table width="80%" align="center" border="1">
<tr valign="top">
<td>Some content that varies in size</td>
<td width="200">Maybe an image, maybe some short text</td>
</tr>
</table>
My best attempt with CSS gets me the left-side contents (the "content that varies in size" above) to wrap around the div on the right.
Here's what I'm trying:
div.outsidecontainer {
position: relative;
width: 80%;
border: 1px solid silver;
margin-left: auto;
margin-right: auto;
}
div.absolute {
float: right;
width: 200px;
margin-bottom: 1px;
border: 1px solid silver;
}
div.filler {
border: 1px solid silver;
margin-bottom: 1px;
}
<div class="outsidecontainer">
<div class="absolute">This is the fixed-size div on the right</div>
<div class="filler">Another div element with a lot of text .....</div>
</div>
Any suggestions?
You can acomplish this in a few ways.
Instead of using float right to get the content on the right, just place it on the right. With float: left; on each of the containers contents and placing a clearfix:both; in the bottom of the container:
Your approach - fixed
* {
box-sizing: border-box;
}
.outsidecontainer {
width: 100%;
border: 1px solid black;
}
.cell {
float: left;
}
.absolute {
width: 200px;
}
.filler {
width: calc(100% - 200px);
height: 100%;
}
/*used to stop the container from collapsing*/
.clearfix {
clear: both;
}
<div class="outsidecontainer">
<div class="filler cell">Another div element with a lot of text .....</div>
<div class="absolute cell">This is the fixed-size div on the right</div>
<div class="clearfix"></div>
</div>
Alternatively you can use the display: table to replicate a table using divs.
display: table Approach
.t-body {
width: 80%;
display: table;
}
.t-row {
display: table-row;
}
.t-cell {
display: table-cell;
border: 1px solid black;
}
.fw {
width: 200px;
}
<div class="t-body">
<div class="t-row">
<div class="t-cell">Another div element with a lot of text ....</div>
<div class="t-cell fw">This is the fixed-size div on the right</div>
</div>
</div>
a common pattern is to set the parent ("outsidecontainer" in this case) to position: relative then the child element ("absolute") to position: absolute and right: 0. This pattern set's a position: absolute child elements to be constrained to the boundaries of the parent element (rather than being constrained by default to boundaries of the 'body' element)
this is an alternative to float: right (which would also work)
then set margin-right to compensate for the width of the "absolute" div
div.outsidecontainer {
position: relative;
width: 80%;
border: 1px solid red;
margin-left: auto;
margin-right: auto;
}
div.absolute {
position: absolute;
right: 0; /* position to the right of "outsidecontainer" div */
width: 200px;
margin-bottom: 1px;
border: 1px solid blue;
}
div.filler
{
border: 1px solid black;
margin-bottom: 1px;
margin-right: 200px; /* compensate for "absolute" div's width */
}
<div class="outsidecontainer">
<div class="absolute">
<p>This is the fixed-size div on the right</p>
<p>This is the fixed-size div on the right</p>
<p>This is the fixed-size div on the right</p>
</div>
<div class="filler">
<p>Another div element with a lot of text ..... </p>
<p>Another div element with a lot of text ..... </p>
<p>Another div element with a lot of text ..... </p>
<p>Another div element with a lot of text ..... </p>
<p>Another div element with a lot of text ..... </p>
<p>Another div element with a lot of text ..... </p>
</div>
</div>
Fiddle here: http://jsfiddle.net/csaltyj/mbnWm/
<style type="text/css">
#container {
border: 2px solid #000;
position: absolute;
width: 20em;
}
.box {
background: transparent;
position: absolute;
border: 1px solid #0f0;
}
</style>
<div id="container">
<div class="box">
<p>X</p>
<p>Taller than the other two.</p>
</div>
<div class="box">
<p> Y</p>
</div>
<div class="box">
<p> Z</p>
</div>
</div>
This is not working. They overlap fine, but there are issues. The goal is to:
Get the #container to properly wrap around the children divs.
Have the .box divs fill (width & height) the parent #container (so the green borders should reach all the way out to the thick black border).
This must be possible, I'm just having a hard time with positioning. (that and floats seem to be the toughest parts of CSS)
Thanks for any help.
The problem you have here is that anything that is position: absolute; is removed from flow. Thus, #container can never contain the .boxes. In this cause you will need to set height and width on #container and make sure the .boxes can never expand beyond it. You requested they fill the #container, so I've done that here: http://jsfiddle.net/X3EJ6/
Note though that because width and height are set to 100% the borders will not work correctly. You will need to set explicit values or use box-sizing and set it to border-box (this is not support in IE < 8).
<style type="text/css">
#container {
border: 2px solid #000;
position: absolute;
width: 20em;
height: 10ex;
overflow: hidden;
}
.box {
background: transparent;
position: absolute;
border: 1px solid #0f0;
width: 100%;
height: 100%;
}
</style>
<div id="container">
<div class="box">
<p>X</p>
<p>Taller than the other two.</p>
</div>
<div class="box">
<p> Y</p>
</div>
<div class="box">
<p> Z</p>
</div>
</div>
How to make children auto fit parent's width only with CSS?
I'd like to put two columns on the side of the content div. The part I have problems with is that I want the columns being built from 3 parts. The top and bottom should have fixed heights, but the middle one would adjust depending on the content height. Look at the sample with one column:
<html>
<head>
<style>
* { border: 1px solid black;}
#contentWrapper { width:450px; }
#leftColumn { width:100px; float: left; }
#leftColumnTop { width:100px; height:50px;
background-color: gray; }
#leftColumnMiddle { background-color: red; }
#leftColumnBottom { width: 100px; height:50px;
background-color: gray; }
#content { width: 300px; float: left; }
#footer { width: 400px; clear: both; }
</style>
</head>
<body>
<div id="contentWrapper">
<div id="leftColumn">
<div id="leftColumnTop"> </div>
<div id="leftColumnMiddle"> </div>
<div id="leftColumnBottom"> </div>
</div>
<div id="content">content<br> here <br>more
<br>more <br>more <br>more <br>more
<br>more <br>
</div>
<div id="footer">footer text</div>
</div>
</body>
</html>
What I want is the #leftColumnBottom stick at the top of the footer and red #leftColumnMiddle to fill the space between top and bottom part.
This works in everything except IE6; for that you'll need a conditional comment and css expression to set a height instead of bottom on #leftColumnMiddle
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<style>* { border: 1px solid black;}
#contentWrapper { position: relative; float:left; width: 450px; }
#leftColumnTop { position: absolute; width: 100px; height: 50px; left: 0; background-color: gray; }
#leftColumnMiddle { position: absolute; width: 100px; top: 50px; bottom: 50px; left: 0; background-color: red; }
#leftColumnBottom { position: absolute; width: 100px; height: 50px; left: 0; bottom: 0; background-color: gray; }
#content { width: 300px; float: left; margin-left: 100px;}
#footer { width: 400px; clear: both; }
</style>
</head>
<body>
<div id="contentWrapper">
<div id="leftColumnTop"> </div>
<div id="leftColumnMiddle"> </div>
<div id="leftColumnBottom"> </div>
<div id="content">content<br>
here<br>more<br>more<br>more<br>more<br>more<br>more<br>
</div>
</div>
<div id="footer">footer text</div>
</body>
</html>
And to the commenter - it nearly worked, so that's why. ;)
try min-height for the one that needs to grow
If you need both columns to be of equal height, and work in IE6, you basically have to hack.
A solution I've used in the past involves setting up a fake margin/padding for one of the columns. This assumes that you know a upper limit of how large the columns can grow (could be in the magnitude of several thousand px's).
This solution is outlined here.
Quoting from the page I linked:
The basic method works like this:
Blocks which will act as columns must be wrapped in a container element
Apply overflow: hidden to the container element
Apply padding-bottom: $big_value [2] to the column blocks, where $big_value is a large enough value to guarantee that it's equal to or larger than the tallest column
Apply margin-bottom: -$big_value to the column blocks