Assuming that what I said was accurate (that we could do element-based positioning if the target was in the same or a descendant containing block), then all three of your examples would work. Here’s an example that wouldn’t work:
Really glad this got brought up, and I like your solution too. It addresses a problem I think most of us have faced many times. My only gripe is that it makes you either use inline styles or tie yourself to DOM ids in the CSS to be able to use it, which puts some limits on how dynamic it can be. That’s a hard thing to get around, though. One way to decouple it a bit and maintain SoC could be to allow something like:
I’m all for syntax reform (I just pulled a usable example from an existing feature), but I’m not sure I’m on board with your suggestion. I’ve always felt that there’s a little bit of an illusion when it comes to full SoC with our front-end code. Our JS and CSS files will always need to be somewhat aware of the DOM structure (either through tags, attributes or classes/ids) in order to operate on it.
Your example relies on a reference attribute and an attached class to tie your two elements together. At first blush that may seem decoupled, but ultimately, to me, it feels less maintainable and verbose for the end user. I have to set two values to accomplish the same thing I would be able to do with the former syntax in one value.
If we were trying to convey semantic meaning behind this, I think utilizing an attribute would be a good idea. We could treat it like the for attribute and have it be a part of UA stylesheets or something. But I see this as purely presentational, so I think a pure CSS solution is ideal here.
What about changing element() to be something like first-sibling() or first-ancestor() (or I guess first-descendant(), though I thought lookahead CSS rules were a no-go), where it refers to the first element (along a search path relative to the element, within the rules Tab stated) matching a given CSS selector (not just ID selectors)?
I imagine such an ancestor search could have perf problems, but there’s probably some way to sidestep that, eg. by using values with more constrained search paths (like maybe previous for the sibling element immediately before this one).
Also, for that reason, I think the selector should be a second word of the property, with the first defining the relation to the selected element like relative-to (with other possible values, as I mentioned above, like before or after).
Based on what I’ve seen over at Bootstrap, supporting (or aiding implementation of) robust full-featured positioning of tooltip-ish elements is a tad more complicated, although this is certainly a step in the right direction.
Some complications / use-cases to consider:
(A) Say the tooltip is above the element. If the user scrolls down so that the element is at the very top of the screen, my tooltip is now partially/totally outside the viewport and not visible. I want my tooltip to “flip” to be below the element instead. Strawman syntax just to give some examples of what I’m talking about:
relative-placement: top; = tooltip always goes above element, regardless of whether that puts it outside the viewport
relative-placement: auto(top, right, bottom); = tooltip goes above element, unless that would put it outside of the viewport, otherwise the tooltip goes on the right side of the element, otherwise the tooltip goes below the element; if all of those placements are outside the viewport, then go above since top is first in the list. Authors are advised to include all available directions in their auto preference list.
(B) Say the element is a <span> with multiple rendering boxes cut across two lines (example visual: http://imgur.com/ta68YjM.png). Where does the tooltip get positioned? Most users feel that placing it over the empty space between the two boxes feels pretty weird, although that’s the easiest behavior to opt for.
So I’m generally in favor of giving the end-user as much flexibility as possible when it comes to features because they end up doing things the implementors could never imagine with them… and that’s great! Allowing any CSS selector would give a lot more flexibility but it would also open it up to some issues and I don’t think the tradeoffs are worth it.
By sticking with Id’s, we can select one element as fast as possible and we have built in guarantees that the element is unique (or else the document is invalid). It also gives us a much simpler syntax than the one you’re proposing. Finally, if a user runs into issues using the property, there’s a single point of failure to look at… that element exists in the DOM or it does not.
Using your proposed syntax, there’s no guarantee we’ll find only one element and each of these queries could/would be noticeably slower than using Id’s, even if we’re only using the first element returned by the selection.
All that to say I’m favoring simplicity and speed over flexibility in this case.
Yes, but a rule that only works once on the page is useless for anything but fixed UI elements and dialog boxes. Assigning the rule to a unique element means it’s completely incapable of working for any sort of repeatable component outside of Shadow DOM.
This argument could be applied to anything that uses CSS selectors. It’s not a valid point.
Since I’ve never actually touched UA code for CSS engines, I leave tractable perf concerns to people like Tab who have some applicable experience in this domain.
I’m pretty sure I’m misunderstanding what it is exactly that you’re trying to accomplish with your syntax (over the original) so if you could provide an example that’d be great.
The one exception to this (in your case) would be the ability to use pseudo classes, which would be a definite plus!
Except that selectors don’t typically reside in property values. I think the additional clarity afforded to me by an Id here would be beneficial.
I haven’t touched UA code either, but I’m not asking you to take my word for it. Just run some perf tests in your own browser using dev tools. I imagine the scoping of your functional syntax would help mitigate some of the issues, but you should be able to see get a general idea of how the selectors perform.
To add to that, I feel like I worded my initial response poorly so let me try to better explain my point. I’m not trying to say that only Id’s will perform adequately. I’m just suggesting that the open-ended nature of your syntax invites performance considerations. By restricting the selectors to just Id’s, we know that it’ll work, because we have viable examples using the same syntax in existing browsers.
I guess my big question for you is: Why would I want all the extra stuff in your syntax, when at the end of the day all I’m trying to target is one element? Id’s only return one element and that’s what I want… why make it more complicated?
I wonder if there might be an overlap with position: sticky, or any of the work there.
In general, my two cents are that when in doubt, making the behavior match how positioning would work if the element were position: absolute and a direct descendent of the target is probably the right call. So for example in @cvrebert’s (B), setting left: 0; right: 0 would render the width 0.
I hope this helps! Happy to share more of my experiences working on Tether or its consumer libraries Tooltip, Drop, Select, Shepherd, etc.
When it comes to positioning the element, stuff we have (directional properties, media queries, transforms) and stuff that’s in the works (container queries) looks like it’d pretty much accomplish what I needed.
The suggested syntax accomplished everything I needed, would be super easy to implement for the end developer, and has a track record in existing browsers.
As other use cases are added/considered my suggested syntax probably won’t be all things for all people and that’s why it’s awesome to see everyone commenting. They have more cases from a variety of different perspectives.
If you have another use case in mind, please link it up or post it here! Ultimately, any additional flexibility the spec could give us in this area is a good thing.
When you say this it makes me think you’ve got a list of items with counters, tooltips, etc. I’ve been able to accomplish this effect with a combination of position: relative/absolute; as outlined in one of my earlier posts. If you have other use cases, please link or add them to the thread.
Hopefully that makes sense! As long as I can accomplish my simple use case I’ll be happy with anything