Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

More specific css absolute positioned element not overriding height/width previously set

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.

like image 802
ScottS Avatar asked Oct 20 '22 13:10

ScottS


1 Answers

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

like image 146
vals Avatar answered Oct 27 '22 20:10

vals