Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[cssom][css-position] Resolved value of over-constrained percentages in inset properties #3059

Open
Loirooriol opened this issue Aug 27, 2018 · 4 comments
Labels

Comments

@Loirooriol
Copy link
Contributor

CSSOM says for top, right, bottom and left:

If the property applies to a positioned element and the resolved value of the display property is not none or contents, and the property is not over-constrained, then the resolved value is the used value. Otherwise the resolved value is the computed value.

Therefore, if I use

element.style.cssText = "position: relative; left: 1%; right: 2%;";
getComputedStyle(element).right;

since relative positioning doesn't stretch boxes, there is over-constrainment, so I should get the computed value.

So what's the computed value of a percentage? https://drafts.csswg.org/css-position-3/#box-offsets-trbl says

For position: relative, see Relative positioning.
[...] Otherwise: [...] if specified as a <percentage>, the specified value[...].

Relative positioning doesn't mention percentages, so it seems it should be the specified value according to "otherwise". But that's not the case in Firefox and Blink, which return the absolute length instead.

WebKit returns the used value when there is over-contraintment and I want to implement the proper behavior, which is not clear.

@Loirooriol Loirooriol added the css-position-3 Current Work label Sep 12, 2018
@Loirooriol Loirooriol changed the title [css-position][cssom] Resolved value of over-constrained percentages in inset properties [css-position] Resolved value of over-constrained percentages in inset properties Sep 12, 2018
@Loirooriol
Copy link
Contributor Author

In fact what CSSOM says (without taking CSS Position into account) doesn't match any implementation.

Consider this code: https://jsfiddle.net/s6qgo0L3/
<pre id="log"></pre>
<div id="container">
  <div id="relative">
    <div id="static"></div>
  </div>
</div>
#container {
  height: 100px;
  width: 100px;
}
#relative {
  position: relative;
  top: 10%;
  left: 20%;
  bottom: 30%;
  right: 40%;  
}
#static {
  top: inherit;
  left: inherit;
  bottom: inherit;
  right: inherit;
}
function insets(el) {
  let {top, bottom, left, right} = getComputedStyle(el);
  return JSON.stringify({top, bottom, left, right});
}
log.textContent = insets(relative) + "\n" + insets(static);

From https://drafts.csswg.org/cssom/#resolved-value-special-case-property-like-top

If the property applies to a positioned element and the resolved value of the display property is not none or contents, and the property is not over-constrained, then the resolved value is the used value. Otherwise the resolved value is the computed value.

The relative element is overconstrained, so we should get the computed value. All Firefox, Chromium, WebKit and Edge provide an absolute length and not a percentage:

{"top":"10px","bottom":"30px","left":"20px","right":"40px"}

The static element uses inherit, so the computed values should be the lengths above. And since it's not positioned, getComputedStyle should provide that computed value.

However, all Firefox, Chromium and Blink provide the percentage instead:

{"top":"10%","bottom":"30%","left":"20%","right":"40%"}

Edge absolutizes the percentages even is static positioning, but they are different this time because they have been resolved with respect to the relative element instead of the container ancestor:

{"top":"0px","bottom":"0px","left":"20px","right":"40px"}

We can conclude that the computed value of the relative element is the percentage, and getComputedStyle doesn't return that percentage.


So I think CSSOM should say something like:

If the element is not positioned or the computed value is a length, then the resolved value is the computed value. Otherwise, if the property is not over-constrained, the resolved value is the used value length. Otherwise, the resolved value is the length that would result from resolving the computed value if there wasn't over-constrainment.

And then in CSS Position

Computed value: as specified, with lengths made absolute

(which is what CSS2 says a bit summarized)

Cc @emilio

@Loirooriol Loirooriol changed the title [css-position] Resolved value of over-constrained percentages in inset properties [cssom][css-position] Resolved value of over-constrained percentages in inset properties Sep 26, 2018
@emilio
Copy link
Collaborator

emilio commented Sep 26, 2018

The static element uses inherit, so the computed values should be the lengths above. And since it's not positioned, getComputedStyle should provide that computed value.

That's not true, the computed value is still the percentage.

@emilio
Copy link
Collaborator

emilio commented Sep 26, 2018

Sorry, pressed enter too early. You did notice that below:

We can conclude that the computed value of the relative element is the percentage, and getComputedStyle doesn't return that percentage.

That's exactly right. I think your proposal makes sense. Though why do you think css-position should change?

The sentence:

Computed value: the keyword auto or an absolute length and/or percentage expression

Looks ok to me, though it could be reworded as you say I guess.

@Loirooriol
Copy link
Contributor Author

why do you think css-position should change?

Because before 6516a86 the computed value of a percentage was not clear at all. And the spec hadn't been updated when I posted my previous comment. Now I guess it's OK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants