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

Proposal: Add wrapper pseudo element #588

Closed
ianthedev opened this issue Oct 11, 2016 · 16 comments
Closed

Proposal: Add wrapper pseudo element #588

ianthedev opened this issue Oct 11, 2016 · 16 comments

Comments

@ianthedev
Copy link

ianthedev commented Oct 11, 2016

Please find the information of ::wrap pseudo element through this hyperlink.

There are abundant use cases of this pseudo element. For example, because there has been no wrapper element for wrapping <dt> and <dd> pairs in description list <dl>, web developers have been having no choice but to resort to JavaScript to insert <li role="presentation"></li> into <dl> or even use less semantic list elements like <ul>. Yet another example is that layout designs such as "left and right columns" is everywhere so we have been having to add extra wrapper <div>s into HTML for that kind of purpose.

The aforementioned examples are just a tip of iceberg. The use cases of ::wrap are a lot more than the use cases of :first-child, :empty, etc.

Could we please have this ::wrap pseudo element be formally adopted? With this pseudo element, web developers would be able to write more semantic HTML and no longer have to resort to JavaScript, which can result in the unwanted FOUC. From the aspect of use case, there seems to be no reason why this pseudo element should not be adopted.

@ianthedev
Copy link
Author

ianthedev commented Oct 18, 2016

If you support this proposal, please reply so that we can get more people involved and underline the importance of ::wrap pseudo element.

@SebastianZ
Copy link
Contributor

SebastianZ commented Oct 18, 2016

The most important part of this proposal is that it allows to get rid of wrapper HTML elements, which are only used for layout purposes.

An example for this can be seen on this very GitHub page, which currently has a structure like this:

<div id="discussion_bucket" class="clearfix">
  <div class="discussion-sidebar js-sticky is-stuck" style="position: sticky;"></div>
  <div class="discussion-timeline js-quote-selection-container "></div>
</div>

With this pseudo-element it would be possible to replace the outer <div> by a CSS rule like this:

#show_issue::wrap(:first-child, :last-child) {
  display: block;
}

#show_issue::wrap(:first-child, :last-child)::before {
  content: "";
  display: table;
}

#show_issue::wrap(:first-child, :last-child)::after {
  clear: both;
  content: "";
  display: table;
}

Note: This example also requires stacking of pseudo-elements. Though even without pseudo-element stacking there are use cases for a wrapper pseudo-element.

For reference, this proposal was previously discussed on www-style.

Sebastian

PS: @Ian-Y, please change the summary to "Add wrapper pseudo element" to be more general (and remove [css3-selector], as Selectors Level 3 is already a recommendation). This may rather be part of the CSS Pseudo-Elements Module.

@ianthedev ianthedev changed the title [css3-selector]: Proposal: Adop ::wrap pseudo element Proposal: Add ::wrapper pseudo element Oct 18, 2016
@ianthedev
Copy link
Author

ianthedev commented Oct 18, 2016

@SebastianZ Thank you for the example of use case. And I had changed the thread title as per your suggestion.

@ianthedev ianthedev changed the title Proposal: Add ::wrapper pseudo element Proposal: Add wrapper pseudo element Oct 18, 2016
@SebastianZ
Copy link
Contributor

SebastianZ commented Oct 18, 2016

Here are some older discussions about this:

I skimmed through them and saw three counter proposals:

Use tags for the start and end elements

Idea

Tag the start and end elements via group-open and group-close properties and introduce a ::group() pseudo-element making use of that tags to style the elements between them.

This was proposed by Marat Tanalin in '[selectors] New pseudo-element ::inner-wrapper & ::outer-wrapper (feature)'.

Example

DL.example > DT {group-open: myGroupName; }
DL.example > DD {group-close: myGroupName; }

/* Show green border around each `DT`/`DD` group. */
::group(myGroupName) {
  border: 2px solid #0d0;
}

Use decorators

Idea

Introduce an @decorator at-rule defining decorative elements, which can then be applied via a decorator property.

@FremyCompany mentioned this in '[css4-pseudo] The need for more powerful pseudo elements', which was obviously inspired by an old version of the Web Components spec.

Example

@decorator video {
  content: contents slot(icon) slot(text);
  @slot(icon) { content: ' V'; font-family: ...; }
  @slot(text) { content: ' video'; }
}

@decorator fog {
  content: slot(wrapper);
  @slot(wrapper) {
    content: contents slot(overlay);
    position: relative;
  }
  @slot(overlay) {
    position: absolute; top...;
    background: rgba(...);
  }
}

@decorator only-first-image {
  content: contents(img:first-of-type);
}

Use a pseudo-class

Idea

Introduce a :body pseudo-class matching all non-heading elements.

This is obviously restricted to some specific use case and was proposed by Leif Halvard Silli in 'A *:body pseudo class'.

He didn't provide a proper example of how he imagined the pseudo-class to work, though as he's talking about something that "encapsulates the entire "body text"", I assume he mixed up the use cases of pseudo-classes and pseudo-elements.

Sebastian

@SebastianZ
Copy link
Contributor

Some important comments from the related www-style thread:

@tabatkins:

It's definitely not impossible! … New pseudos that wrap "real" elements in
some way are... not popular among implementors. The idea for ::wrap
goes back well over a decade, and the complexity it adds to the
platform versus the benefit you get, when compared to just adding
wrapper elements in your HTML, has meant that implementors have never
bitten at the idea.

@Crissov

You’d need to convince Hixie et al., though.

Why isn’t there a grouping-type element for description lists to represent individual name-value groups (e.g., a “dli” element)? It would make styling as well as adding microdata to individual groups much easier.
HTML should group <dt>s and <dd>s together in <di>s!

This FAQ says:

This is a styling problem and should be fixed in CSS. There's no reason to add a grouping element to HTML, as the semantics are already unambiguous.

@Marat-Tanalin:

So virtual containers are far more than just a way to group DT/DD elements, instead they would be a powerful layout mechanism absolutely unachievable with current HTML and CSS.

@tabatkins
Copy link
Member

As I and @fantasai stated in the email thread, implementors have historically been strongly against this sort of functionality; it makes for a very complicated implementation, apparently. Features don't really do well without implementor interest, and in this case we have clear implementor anti-interest, which is a strong signal that we should not add the feature to a spec, as it will not be successful.

See https://wiki.whatwg.org/wiki/FAQ#Is_there_a_process_for_adding_new_features_to_a_specification.3F for a rough idea of how adding new features work. Author interest is one part of the process, but not all of it!

@Crissov
Copy link
Contributor

Crissov commented Oct 19, 2016

Everybody agrees that the dt-dd use case is a valid one, but effectively, @tabatkins says WONTFIX in CSS and @Hixie says WONTFIX in HTML. Both represent Google/Chrome. Can you figure out this deadlock internally?

@tabatkins
Copy link
Member

It's very possible for something to be WONTFIX in both languages!

But also, Hixie hasn't been the editor of HTML for a while now. This could possibly be relitigated in WHATWG; Domenic and Anne may have different opinions now. (And I'm happy to support reusing <li> for this purpose.)

@gavinmcfarland
Copy link

gavinmcfarland commented Dec 21, 2017

I came across this discussion after resorting to researching to see if a css pseudo wrapper element had miraculously been implemented after years of having to add wrapper divs to my designs for purely stylistic and layout reasons.

I wanted to add one of my biggest use cases for having to use wrappers and that is to support gutters in CSS with responsive designs. A technique which is used often is to add an inner wrapper to a container and apply a negative margin to it so that top and right margins can be added to it's children to simulate guttering between elements. It has to be done this way because if the order of the elements change (i.e. using media queries) or there are more than one row of elements then the margin must be applied to every child element and cannot be achieved using the :first and :last-child technique or .row technique. Guttering is so paramount to layouts and it is surprising because even now with the likes of flexbox and CSS grid layouts; guttering cannot be achieved using a "floating" method for content. CSS grid layout requires you to know, to a large degree what the content is and where it will be positioned dispite it having the best support for gutters.

Therefore using wrappers is the most flexible and effective way to overcome these layout issues with respect to managing spacing between elements in layouts. Yet having to use wrapper divs creates so much chaos with regards to managing CSS as they mess with the hierarchy of the DOM and CSS specifity becomes a real nightmare. It makes it almost impossible to reliably and consistently style other elements inside wrapper divs especially when working on large teams made up of members of different skill levels.

I think that because the need for responsive sites and apps is growing, it is becoming even more paramount that we ease the burden of authoring HTML, instead of forcing developers and front-end designers to add wrapper divs where CSS falls short.

@joallard
Copy link

joallard commented Jan 10, 2018

Adding a use case here, I can only strongly echo that the rationale for this is to separate the semantic content in HTML and presentational concerns in CSS. Quite simply, take a basic webpage where you have many sections, and you want its content to have a max-width, but the background to run the full width. As of today, I effectively need to go in and add a non-semantic .container wrapper for that. Heck, you could make the argument this applies to all non-semantic wrappers in HTML.

Pending that, is there any way we can bridge the gap to implementers, maybe some are around here, and reconcile our differences maybe? If we deem this as a desirable spec, then the thing that's left to do is only to figure out how to feasibly implement it 😉

@tomhodgins
Copy link

I've had a bunch of people ask me about a ::wrapper pseudo-element, but I can't figure out how it would work. If you have HTML like this:

<ul>
  <li>item
  <li class=target>target
  <li>item

And you do something like this:

.target::wrap {}

How does CSS see your HTML? Does a selector like li ~ li skip over the wrapped <li>?

Can anybody explain how it would work? What happens to event listeners on wrapped elements? Does the wrapper respond to things like parentNode or parentElement or is it 'invisible' to JavaScript?

If the desire is for more layout control, are there better ways this layout ability could be used without relying on using CSS to fake HTML in order to accomplish it?

@gavinmcfarland
Copy link

@tomhodgins I would expect it act just like styling the Shadow DOM works in that it would be invisible and other CSS pseudo selectors would ignore any faux elements represented by CSS selectors, just like :after is ignored when manipulating the DOM with JavaScript.

I would expect

.target::wrap {}

to only exist for the sake of styling the element it has selected.

@tabatkins
Copy link
Member

Yeah, pseudo-elements don't change the DOM structure; Selectors only looks at the DOM structure for the purpose of matching. li + li matches exactly as it would without the wrapper.

I'll note that the use-case of "grouping dt/dd" has now been solved - HTML just allows div inside of dl now for this purpose.

@Marat-Tanalin
Copy link

Marat-Tanalin commented Jan 19, 2018

@tabatkins

the use-case of "grouping dt/dd" has now been solved - HTML just allows div inside of dl now for this purpose.

The way how the feature is done unfortunately makes it very limited: multiple nested DIVs around DT/DD are not allowed, so if styling requires that, the good old ULLIDL approach is still relevant and more flexible.

Also, please don’t forget that CSS-based wrappers could be dynamically changed depending on e.g. media queries which is impossible with hard-coded HTML wrappers.

@jorrit
Copy link

jorrit commented Sep 27, 2018

My use case would be supporting responsive iframes, for which the only solution currently is to have a wrapper element with height: 0 and padding-top: 0.5625% or whatever proportion is required:

iframe.responsive::wrap {
  display: block;
  height: 0;
  padding-top: 0.5625%;
  position: relative;
  overflow: hidden;
}

iframe.responsive {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 0;
}

@frivoal
Copy link
Collaborator

frivoal commented Sep 28, 2018

Issue #2406 is about a different but related proposal, which seems much more likely to gain acceptance, as it is significantly easier to implement. People who like this proposal should consider who well that one would serve their needs, and get behind that if it works for you.

mjumbewu added a commit to appropriatetech/icat9 that referenced this issue Sep 30, 2020
I was trying to see how far I could get with avoiding wrapping elements 
to achieve sections as full-width bands. There are some exciting CSS 
things being discussed:

* A [::wrapper pseudo 
element](w3c/csswg-drafts#588) seems stalled 
because it could cause some tricky situations in the DOM, but
* A [::contents pseudo 
element](w3c/csswg-drafts#2406) is still under 
consideration and has some steam.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants