I have a div element wrapping other div elements like so:
<div style="overflow:hidden">
<div id="a"></div>
<div id="b"></div>
</div>
I have other css rules that manage the dimensions of the outer div. In my actual code, I want to position the div#a exactly 10 px below the outer div. However, I want div#b to still be cut off by the outer div's overflow:hidden.
What is the best way to achieve this?
Method 1
A good way to do it is by setting the overflowing element to position:fixed (which will make it ignore the parent overflow), and then positioning it relative to the parent using this technique:
.parent {
position: relative;
.fixed-wrapper {
position: absolute;
.fixed {
position: fixed;
}
}
}
One caveat is that you cannot have any of the top,right,left,bottom properties set on the fixed element (they must all be default 'auto'). If you need to adjust the position slightly, you can do so using positive/negative margins instead.
Method 2
Another trick I recently discovered is to keep the overflow:hidden element with position:static and position the overriding element relative to a higher parent (rather than the overflow:hidden parent). Like so:
http://jsfiddle.net/kv0bLpw8/
#wrapper {
width: 400px;
height: 50px;
position: relative;
z-index: 1000;
left: 0px;
top: 0px;
}
#wrapper #insideDiv {
width: 400px;
height: 50px;
overflow: hidden;
position: absolute;
z-index: 2000;
left: 0px;
top: 0px;
}
#wrapper #a {
position: absolute;
height: 30px;
width: 100px;
bottom: -40px;
z-index: 1000;
left: 0px;
}
<div id="wrapper">
<div id="a">AAA</div>
<div id="insideDiv">
<div id="b">BBB</div>
</div>
</div>
The easiest and most convenient way is to wrap your container div inside another div and set position: relative on the external div.
.outer-container {
position: relative;
height: 50px;
}
.container {
background: gray;
overflow: hidden;
height: 50px;
}
#a,
#b {
height: 100px;
width: 100%;
}
#a {
background: green;
position: absolute;
top: 60px;
}
#b {
background: red;
font-size: 60px;
}
<div class="outer-container">
<div class="container">
<div id="a"></div>
<div id="b">Cut off</div>
</div>
</div>
as people said, the element must be presented outside the parent in order to be not cropped. But you can do this with JavaScript to achieve the similar concept without having to change your actual markup:
function breakOverflow(elm) {
var top = elm.offset().top;
var left = elm.offset().left;
elm.appendTo($('body'));
elm.css({
position: 'absolute',
left: left+'px',
top: top+'px',
bottom: 'auto',
right: 'auto',
'z-index': 10000
});
}
then pass the element you want to exclude from the cropping of its parent:
breakOverflow($('#exlude-me'));
Related
I have 3 divs on top of each other having following css.
.d1 {
position: relative;
background-color: yellow;
height: 50px;
width: 100px;
overflow: hidden;
}
.d2 {
position: absolute;
background-color: green;
height: 25px;
width: 50px;
}
.d3 {
position: absolute;
left: 83px;
}
and the divs that have classes are as follows:
<div class="d1">
<div class="d2">
<div class="d3">text</div>
</div>
</div>
and as a result I see content of d3 cut off because of overflow:hidden in d1.
How can I avoid cut off content of d3 without modifying d1?
Getting around the overflow..
An element can overflow from a relative or absolute positioned parent by setting its position to fixed. An element that has position: fixed will have the default left,right,top, and bottom styles set as auto. This will position .d3 to the top-left of .d2, and then the left: 83px style will push it to the left from there.
Making up the additional space..
However, to get that additional movement to the right as the original markup, you will need to add margin-left: 8px, which will make-up the additional ~8px needed to replicate the original. Further adjustments to the position of .d3 will need to be done by setting the margin style (see below).
Your updated code should look like this..
.d1 {
position: relative;
background-color: yellow;
height: 50px;
width: 100px;
overflow: hidden;
}
.d2 {
position: absolute;
background-color: green;
height: 25px;
width: 50px;
}
.d3 {
position: fixed;
margin-left: 8px;
left: 83px;
}
Some considerations and caveats..
As a previous commenter mentioned, best practice would be to fix your html markup because this solution could cause issues if you ever need to move the position of .d3. For example, setting left,right,top, or bottom will cause the default setting of this style, auto, from being unset, and the element will be positioned relative to the viewport rather than the parent relative or absolute element.
Here is the HTML I am working with.
<div id="outer" style="min-width: 2000px; min-height: 1000px; background: #3e3e3e;">
<div id="inner" style="left: 1%; top: 45px; width: 50%; height: auto; position: absolute; z-index: 1;">
<div style="background: #efffef; position: absolute; height: 400px; right: 0px; left: 0px;"></div>
</div>
</div>
What I would like to happen is for the inner div to occupy 50% of the space given to its parent div(outer). Instead, is is getting 50% of the space available to the viewport, which means that as the browser/viewport shrinks in size, so does it.
Given that the outer div has min-width of 2000px, I would expect the inner div to be at least 1000px wide.
Specifying a non-static position, e.g., position: absolute/relative on a node means that it will be used as the reference for absolutely positioned elements within it http://jsfiddle.net/E5eEk/1/
See https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Positioning#Positioning_contexts
We can change the positioning context — which element the absolutely positioned element is positioned relative to. This is done by setting positioning on one of the element's ancestors.
#outer {
min-width: 2000px;
min-height: 1000px;
background: #3e3e3e;
position:relative
}
#inner {
left: 1%;
top: 45px;
width: 50%;
height: auto;
position: absolute;
z-index: 1;
}
#inner-inner {
background: #efffef;
position: absolute;
height: 400px;
right: 0px;
left: 0px;
}
<div id="outer">
<div id="inner">
<div id="inner-inner"></div>
</div>
</div>
Use position: relative on the parent element.
Also note that had you not added any position attributes to any of the divs you wouldn't have seen this behavior. Juan explains further.
I've got a fixed container which is vertically and horizontally centred on the page, and an element within that container. Ideally I would like to have this element positioned in the very top left of the window, however I'm struggling to make it work.
This JS Bin illustrates the problem.
https://jsbin.com/nodonatifo/edit?html,css,output
Initially I thought I would just be able to do something like this on the element.
#container {
width: 300px;
height: 400px;
background-color: #55ffdd;
/* Center on page */
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#element-actual {
background-color: red;
width: 100px;
height: 100px;
position: fixed;
top: 0px;
left: 0px;
}
<div id="container">
<div id="element-actual"></div>
</div>
However that just fixes the element in the top left corner of the parent container, rather than the window.
Is this possible with my current styles?
#container {
width: 300px;
height: 400px;
position: fixed;
top: 50%;
left: 50%;
background-color: #55ffdd;
margin-top: -200px;
margin-left: -150px;
}
If you use translate property then its children div will place relatively to the parent div only even when it is position:fixed so you can use the above code to place #container in center and you red div will be placed relatively to the window not the parent div :)
As Gaurav Aggarwal already pointed out, the fixed element will still be relative to the parent's transformed positioning. If you want the container element to be dynamically positioned (even if it has unknown dimensions), then you could use the following approach and avoid using transform: translate(-50%, -50%) for vertical/horizontal centering.
This method essentially positions the container element to fill the height/width of the window element with top: 0/right: 0/bottom: 0/left: 0, and then centers it vertically/horizontally using margin: auto.
Example Here
#container {
width: 300px;
height: 400px;
position: fixed;
top: 0; right: 0;
bottom: 0; left: 0;
margin: auto;
background-color: #55ffdd;
}
#element-actual {
background-color: red;
width: 100px;
height: 100px;
position: fixed;
top: 0;
left: 0;
}
<div id="container">
<div id="element-actual"></div>
</div>
Easy, add this to the child:
position: sticky;
it's a known 'bug' that elements with fixed position loose their position if the container is translated. For example, if i've got a structure like this:
<div class="container">
<div class="fixed"></div>
</div>
and, say, the container is scrolled, when the conteiner gets transformed (say, translate(x,y), rotate(), or so..), then the fixed element behaves like it was positioned relative and it scrolls with the container. I can see it on the latest firefox, for example.
How can one fix this kind of problem? Is there any way?
This behaviour is not a bug. It's actually the specs recommended behaviour.
(See this post by Eric Meyer, or this question here on SO which accepted solution only provides a link to the same meyer's post)
For those who don't know this issue, and because you didn't provide a snippet into your question, here's one.
document.addEventListener('click', function() {
document.getElementById('container').classList.toggle('transformed')
}, false);
#bg {
border: 1px solid #AFA;
height: 100%;
width: 100%;
position: fixed;
top: 0;
left: 0;
}
#container {
border: 1px solid #FAF;
height: 50%;
width: 75%;
position: relative;
margin: 0 auto;
overflow: auto;
}
#content {
background: rgba(125, 175, 0, .7);
position: fixed;
width: 100%;
top: 0;
left: 0;
}
.transformed {
transform: translate(0, 5em);
}
<div id="bg">
<div id="container" class="transformed">
.<br>.<br>.<br>.<br>.<br>.<br>.
this is a scrollable paragraph
<br>.<br>the "fixed" content does scroll with the paragraph
<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
you can click to toggle the transformation On/Off
<br>.<br>.<br>.<br>.<br>.
<span id="content">relatively fixed content</span>
</div>
</div>
However, I did find something that may help others facing the same issue.
It's not really a solution, since the "fixed" element will be only inside the container, (except for IE browsers where it will really be fixed to the document). But in my case, it's actually what I wanted and maybe it'll be fine for others too.
If you add a wrapper, set its height:100%; width:100%; and overflow:auto, then your "fixed" content won't scroll with the container.
Actually it's not you container which scrolls anymore, but the wrapper. So you might want to set the container's overflow:visible or hidden to avoid unwanted scrolling of the not so well "fixed" element.
Also, note that you need your wrapper be a block or inline-block element.
#bg {
border: 1px solid #AFA;
height: 100%;
width: 100%;
position: fixed;
top: 0;
left: 0;
}
#container {
border: 1px solid #FAF;
height: 50%;
width: 75%;
position: relative;
margin: 0 auto;
overflow: visible;
}
#wrapper {
height: 100%;
width: 100%;
overflow: auto;
}
#content {
background: rgba(125, 175, 0, .7);
position: fixed;
width: 100%;
top: 0;
left: 0;
}
.transformed {
transform: translate(0, 50%);
}
<div id="bg">
<div id="container" class="transformed">
<div id="wrapper">
.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.<br>.
<span id="content">relatively fixed content</span>
</div>
</div>
</div>
I am not familiar with this bug, but when you use positioned: fixed; the element is positioned relative to the browser window, so it doesn't really make any sense to put it inside a container.
This markup would be my recommendation:
<div class="fixed"></div>
<div class="container"></div>
Once you use position: fixed; on any element it is positioned relative to the view-port. Directly from page in MDN about position property.
fixed
Do not leave space for the element. Instead, position it at a specified position relative to the screen's viewport and don't move it when scrolled.
So what you are experiencing is a what it is actually supposed to work like and not a 'bug'.
Now if what you want is something that is positioned with relation to the .container div and translate with it than you will have to use absolute positioning here. Take a look at this fiddle. The important CSS is-
.container {
width: 200px;
height: 100px;
position: relative;
}
.absolute {
position: absolute;
width: 20px;
height: 10px;
top: 50px;
left: 50px;
}
Notice that with positioning the inner div as absolute I have also positioned the outer div as relative as the inner div takes its position in reference to the closest parent div positioned as anything different from static.
I am trying to put simple divs and arrange them, but my child div disappearing from parent div even though I am using parent div with relative and child div with absolute positioning. I want connect_us_01 and registeration divs insideheader_block1. I am working towards responsive webdesign. Many thanks.
JSFiddle
<div id="header">
<div id="header_block1">
<div id ="registeration">reg</div>
<div id ="connect_us_01">social media</div>
</div>
<div id="header_block2">
<div id="crown_logo">logo</div>
<div id="nav">navigation</div>
<div class="contact_No_01">020324234233</div>
</div>
</div>
css
#header {
position: relative;
width: 100%;
background-color: #ff6a00;
}
#header_block1 {
position: relative;
margin: 0 auto;
width: 90%;
background-color: pink;
}
#header_block2 {
margin: 0 auto;
width: 90%;
position: relative;
background-color: aqua;
}
/*----social media & connect us block*/
#connect_us_01 {
position: absolute;
width: 300px;
height: 50px;
right: 0;
background-color: blue;
}
#registeration {
position: absolute;
left: 1px;
width: 200px;
height: 50px;
background-color: brown;
}
Elements with position: absolute are taken out of the content flow, meaning they have no inherent height. Since the children have no height, the parent gets no height either, rendering the children invisible. You could resolve it by giving the parent a static height (as in, for instance, height: 100px), but that's not very practical and not responsive at all.
What you're looking for isn't position: absolute; it's float: left and float: right. Apply those properties to the children and give the parent overflow: hidden (or whatever method of clearing floats works best with your layout) and it'll work just fine.
To show block you refering to just add to #header_block1 a height parameter also.
#header_block1 {
position: relative;
margin: 0 auto;
width: 90%;
height: 50px;
background-color: pink;
}