I have a horizontal navigation <ul>, and in one of the <li>s I have a <div> element that I was conducting some positioning experiments with.
Along the way I noticed that I could position the inner div inside of the li using
li div {
position: absolute;
top: inherit;
left: inherit;
}
even though I have assigned no top or left properties to the li! Even in Firefox "Computed Styles" inspector. How exactly is it inheriting properties that don't exist? Are my browsers (newest FF & Chrome) just implicitly positioning it, or do the top: and left: properties always exist invisibly?
Also I'm guessing IE<8 will cough this back up...
Here's a fiddle: http://jsfiddle.net/xAk97/
If you have any value with inherit the element is gonna take the same value as his parent. If you don't specify a value in your CSS the inherited value is the default one for that property.
In this case if top isn't defined the element will take that value as auto.
If you check the console in this Fiddle you can check what property is been assigned.
Related
The Set-up for Context
I think you can tell by my resume on Stack Overflow that I am no stranger to css and its behaviors. However, I just came across something I have not experienced before that seems completely incorrect--yet Firefox 27 and Chrome 33 and IE 11 all render it the same.
Here is the code (just two empty nested div elements is the html), which can be seen in this fiddle example:
CSS
div {
width: 50%;
height: 100px;
margin: 10px;
border: 1px solid red;
position: relative;
}
div > div {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
border-color: cyan;
}
I would have expected the absolute positioned div to directly overlap the size of the relative parent div. I expected it would have had its positioning properties override the width and height and margin positioning from the straight div call. I would have expected this behavior (1) because it is more specific in its selector, and (2) because it is positioned absolute and given positioning calls to all four sides.
As you can see by the referenced fiddle above it in fact retains its width and height and seems to essentially "ignore" its positioning values all together. That is, I get the same positioning if the positioning values are taken out. I need to override the previously set properties like so...
width: auto;
height: auto;
margin: auto;
...to get the positioning to actually do something. This appears to be standard behavior given that all the main browsers are reacting the same. I suppose I have never noticed it before because normally my sizing of a wrapping div is done by a class and thus applies only to that div, while my positioning of the absolute child is done likewise, and I don't bother to set a width and height on it.
The Question Itself
My question is seeking quote(s) and link(s) from the W3C documentation (or a highly respected source, such as from one of the major browser developers) that discusses why or that the width or height settings should override a setting of top, right, bottom, left, etc. settings. From the main page discussing absolute positioning, all I found was that either can be used to set the width/height, but the crux of my issue is that I would expect the more specific/last in cascade to take precedence no matter which way was defining the sizing. Yet this is not happening here.
A Description of the Behavior I am Seeing
#pjp found this sitepoint reference, stating:
Absolutely positioned boxes with both right and left having a value
other than auto will effectively define the width of the element
assuming that the element's width is auto. This may result in the
element having no width at all if left and right positions occur at
the same point or perhaps overlap. If the values for left,right and
width are over-constrained and the direction property is ltr, right
will be ignored. If direction is rtl, left will be ignored. Note that
replaced elements with a width of auto will have the elements
intrinsic width substituted and the preceding rules applied.
This exactly articulates the behavior I am seeing. It does not address why (officially) it is that way. I would have expected instead that either:
(1) A higher specificity or equal specificity but following in cascade order setting of width and height (whether explicitly by those properties or by the positioning properites) to take precedence.
(2) In the case of defining both at once (an illogical thing to do, but...):
div {
position: absolute;
width: 50%;
left: 0;
right: 0;
}
or
div {
position: absolute;
left: 0;
right: 0;
width: 50%;
}
That the last defining of width would supersede, so the first the positioning would win, and the second the width would win. This would be just like two definitions in the same block, like so:
div {
width: 50%;
width: 75%;
}
Here, width: 75% wins because it is "last" defined for the property.
I think that your confusion comes from handling the specificity in an inteligent way.
It works on a mechanical way.
That is, every property that has a value is handled in a cascade way, without any consideration about what others properties are some how related.
The width property is inherited by the child as 50% because there is no width set on the child. forget about the posibility of calculating the width from the left and right properties, there is no width property defined, and that is it.
Then, you have also the left and right properties, both set to 0. (no discussion here, I think).
And then, in the w3c docs, you see
If the values are over-constrained, ignore the value for 'left' (in case the 'direction' property of the containing block is 'rtl') or 'right' (in case 'direction' is 'ltr') and solve for that value.
That is a cite with almost the exact words of the cite in your question, but coming from an authorative source
I am working on a project and I am using woocommerce dynamic gallery pro plugin to preview product images in product page. but the issue is that the preview image is showing half in IE.
please can you guys check the following link in IE and help me to fix.
http://www.joannelouise.com/shop/sexy-ladies-red-embellished-dress/
I find a fix, but I am not understanding how i apply this.
I notice if i remove the position from the following class, it may fix the error. but when i am giving position some value like absolute, relative, fixed, static or even inherit. it isn't giving any response until i off the position.
so guys kindly help me to fix this.
following are my changes. which are effecting 50%.
.ad-gallery .ad-image-wrapper .ad-image {
overflow: visible !important;
position: inherit !important;
}
but position thing is not working
You should really avoid so many inline styles. It makes for messy code and more work.
For some reason you're setting .ad-image to {top: 179px;}. Try this (after removing the inline top statement):
.ad-gallery .ad-image-wrapper .ad-image {
top: 0;
}
Strangely, I see {top: .5px} in Firefox. I'm not sure what's going on.
I'm not on a widows box right now, but it could be a case of not clearing a float or a parent item isn't containing children who are floated.
Try using:
overflow:auto on the parent container of whatever images are not showing fully. Can also try using overflow:hidden to achieve the same but avoid scrolling bars in some instances.
Try to avoid ever using !important on production sites if possible.
OP, What version of IE are you using?
The position property specifies the type of positioning method used for an element (static, relative, absolute or fixed).
Note: The value "inherit" is not supported in IE7 and earlier. IE8 requires a !DOCTYPE. IE9 supports "inherit".
Via http://www.w3schools.com/cssref/pr_class_position.asp
IE 7/8 Work-around:
.ad-gallery .ad-image-wrapper .ad-image {
overflow: visible !important;
position: <whatever-the-parent-is> !important;
}
Since IE 7/8 doesn't understand to inherit the position from the element's parent, you can create a CSS rule that specifies what position you'd like the element to use.
I'm running into some extremely strange behaviors, and non-consistant across every browser i've tested.
I've a pretty complex layout, but the main issue lies here:
<div id="drop">
<div id="header"></div>
</div>
#drop has position:absolute and z-index:100
#header has position:fixed; top:60px;
As I start scrolling down Chrome ignores the position:fixed rule. If I remove either of the two styles above from #drop then Chrome starts respecting the position:fixed rule.
can't get it working on Ubuntu Chrome 23.0.1271.97 and see the same behavior on Mac Chrome 25.0.1364.99. My friend uses Ubuntu Chrome 25.0.1364.68 beta and it works correctly for him. I've tested it on firefox and it kinda works (with other symptoms)
Has anyone heard of this error? or can anyone even reproduce it?
edit
I'm using openlayers map as another div with position:fixed if I delete that layer or at least change it to display:none then this weird bug goes away.
edit
Noticed that during the presence of this bug, if I change the zoom level back and forth, then the position adjusts itself to the proper behavior. To me, this indicates a webkit issue that fails to execute some internal callback function on scroll.
Another extremely strange thing is that I have a few links inside of #header and they work if I just click the expected location, even though the the div does not appear there. Overall I've noticed that it's only the rendering that's broken. If at any point of time I force the browser to re-render by resizing the window, or changing zoom, or just doing Select-All, then the header bar jumps to the proper position, but does not remain fixed.
You mentioned in the comments that OpenLayers uses CSS transforms. That being the case:
the element with fixed positioning will become relative to the element with the transform - not relative to the viewport
Take a look at the spec: The Transform Rendering Model
Specifying a value other than ‘none’ for the ‘transform’ property
establishes a new local coordinate system at the element that it is
applied to.
.wpr
{
width: 200px;
height:1000px;
background: pink;
position:relative;
margin: 0 200px;
-webkit-transform: translateX(0);
transform: translateX(0);
}
.fixed
{
width: 200px;
height:200px;
margin: 50px;
position: fixed;
top:0;
left:0;
background: aqua;
}
<div class="wpr">
<div class="fixed"></div>
</div>
As the accepted answer says, this is the intended behavior, and is spec-compliant. Another important component of this is what it means to be using CSS transforms.
In your case, it was due to OpenLayers, but this applies to anyone using will-change: transform as well (probably a lot of the people visiting this question). This has been brought up on the Chromium bug tracker here, and marked as WontFix, because (as I said) it's intended behavior. The official comment is this:
This behavior is required by the spec
(http://dev.w3.org/csswg/css-will-change/): "If any non-initial value
of a property would cause the element to generate a containing block
for fixed-position elements, specifying that property in will-change
must cause the element to generate a containing block for
fixed-position elements."
The idea is that once will-change:transform is specified, you should
be able to add/remove/change transforms cheaply, without needing
fixed-position descendants to get re-layed-out.
Note that using other values of will-change (e.g. opacity, top) will
not change the positioning of fixed-position descendants.
As far as I am aware, the only solution is to make the child of the will-change element a sibling instead, to prevent the attribute from cascading.
As a side note, in my specific case, I was able to fix it by being more specific with the will-change attribute. Instead of using it on the div containing the performance-jarring element that required GPU offloading, I used it directly on the offending element. This was due to my original bad code, though, so it won't work for most cases.
You will have to place header outside the parent container drop to make it work.
I had slightly similar issues days back.For instance,if you set z-index of header,it will be attain the z-index of the parent dropcontainer.The z-index of header will be useless because it is already inside a container which has another z-index.
The same logic of z-index applies to position.
I want to add another possible solution because I was struggling with chrome ignoring position:fixed for quite some time until I finally found the culprit:
-webkit-perspective: 1000;
It was coming from a plugin I was using and causes ALL position:fixed elements to be ignored.
Hope it helps someone.
I think this is impossible, i don't think if two positions can be placed at the same place without one to collapse. But i think its better to use Avail height in javascript, i mean if you wanna an outer div to hold inner div, and outer div must cover the whole screen, use Availheight in js, this will get the screen height and then apply if, thereafter set all the divs in fixed position.
Add this to parent:
position: fixed;
...and this to the child:
position: sticky;
First of all, put something in your div as empty ones behave really weird. Then, what do you expect by putting a fixed into an absolute? Obviously, nobody knows what is the reference point of your fixed div. Should it be its parents position? which is not changing with scroll or the page position which changes? Try to use things that are completely meaningful and have a clear definition because if you fix it in chrome, what would happen with another browser? Do you really prefer to test is on all of them?
I suppose a small change in your divs so that pull the fixed div out of the absolute one or move the absolute div somewhere else.
OK, so I have three <ul> tags that each have float: left; applied to them. The <li> tags have a :hover specification that causes them to increase in width and gain a negative margin equal to the gain in width, so that on hover they increase in size without moving anything.
The issue is that instead of extending out over the following floated <ul> tags, they extend "under" them. Setting z-index has not seemed to do anything about this, though I may perhaps be using it wrong. I've tried setting z-index: 5; on the :hover specification, and I also tried setting z-index: 3;, z-index: 2;, and z-index: 1; on the successive <ul> tags, but neither made any difference.
One thing that did work was to have the <ul> tags be float: right; so that the last one was actually left-most, but I don't like this solution as it means my code is in the opposite order as it appears on the page, and it will mean that I have to set manual tabindex attributes on everything to fix the tab order.
EDIT: Fixed it; can't answer my own question for 7 hours, but it turns out that z-index does not work on position: static; (the default) elements. I just added position: relative; to the <li> tags and it works fine now.
You cannot use z-index for static elements. Consider changing their positioning to either relative or absolute.
I want an HTML element (let say a span or div) to be present on the page, but not take up any space, so I can switch on and off the visibility property, and nothing moves but the span disappears.
for example take a table. I want an 'edit' label to show at each row, when I move the mouse over. But I don't want it to take up space from the table width. I just want it to 'float' beside the table.
Any ideas how to achieve this?
I can not to use javascript. So I'll be very glad if this is possible with CSS only.
I have tried to use float, its not good because no element overlaps with it. (And i do want overlapping.)
I think you're after a CSS Tooltip. Here's an example of one:
http://psacake.com/web/jl.asp
div {
position: absolute;
left: 100px;
top: 100px;
}
This will take the div and position it relative to the first containing element with position other than static. If you have an item with a position of static (the default) or relative, it will affect the document flow and hence the position of other elements. If you set the position to absolute, it takes it out of the document flow and lets you 'drop' it onto the page at whatever pixel position you like. :D
Css position property
Without using javascript i suppose you could use CSS :hover. Like this:
<style type="text/css">
#world { display: none; }
#hello:hover #world { display: block; }
</style>
<div id="hello">
hello
<div id="world">world</div>
</div>
Demo: jsFiddle
The "float" property does not "float" an object over the other elements. It "float"s the element to one side or another.
To put an object over another object, use the z-index property combined with the position property.
z-index: 500;
position: absolute;
left: 50px;
top: 50px;
You can achieve this effect by making an additional column on the edge of your table that is invisible until its row is hovered over. You want to use visibility, not display, to hide and show because visibility maintains the allocated space of the cell.
Demo: http://jsfiddle.net/sCrS6/
You should be able to easily duplicate the code to make it work for your particular page.
This method also has the advantage of working more consistently across web browsers than using positioning, which often starts to have weird in IE behavior after a couple of elements are nested.