-
Notifications
You must be signed in to change notification settings - Fork 671
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
[css-cascade][css-pseudo] How does 'inherit' keyword behave in a child of ::first-line? #1097
Comments
Yes, I noticed that. It must be like this because the span might generate multiple boxes, some not in the first line. So in general the span inherits from the div, but the part of the span in the first line inherits from
Well, Firefox and Edge do the same for And it's OK, because being able to do this is the only point in having If it's not supposed to be like this, the spec needs to be clarified. |
Nah you didn't get it :) The color of the span inherits from the div, always. The fact Chrome does not do that is a violation of css-cascade. The existence of pseudo elements doesn't change the style of normal elements. The style of elements is computed before layout. The reason the text is red is that the color of the text is not the color of the span (if you execute the line of javascript I provided, you will be able to confirm that color is blue) but, insead, it is the color of the text run; the text run is not an element and is created based on styling information during layout; its style thus may depend on the ::first-line style, but that is a totally different thing than to say the span inherits from ::first-line. I should never do, for no property. Neither color, nor background, nor border. At least that is my understanding of it. |
Thanks for the clarifications. Now I will try to be more precise. Suppose we have <div>
<span>ABCDEFGHIJKLMNOPQR<br />STUVWXYZ</span>
</div> If I understand properly, I think you say it becomes somewhat like this: <div>
<span>
<div::first-line>ABCDEFGHIJKLMNOPQR<br /></div::first-line>
STUVWXYZ
</span>
</div> (not sure where to put the Then I agree that using However, it doesn't seem to be the case. Try div {
color: red;
}
span {
color: green;
}
div::first-line {
color: blue;
} All Firefox, Edge and Chrome paint the text with green color, even the text run in the first line. This means the Moreover, Finding the First Formatted Line says
The <div>
<div::first-line>
<span::fragment-1>ABCDEFGHIJKLMNOPQR<br /></span::fragment-1>
</div::first-line>
<span::fragment-2>STUVWXYZ</span::fragment-2>
</div> And then, according to Inheritance and the ::first-line Pseudo-element,
Now this portion in the first line is not only a text run, but a fragment of the span. So that fragment Maybe I'm being obtuse, but I don't find the spec much clear, and implementations don't match, so I think the spec should be clarified. |
Nope, I didn't say the first-line pseudo element is moved inside the span; technically we do no even have any ::first-line box in our browser (the only caveat being the background which is drawn as part of a special logic). What I said is that in Edge/Firefox only the text runs' styles are computed based on the style of the ::first-line pseudo-element of the parent block. I meant to say that "only the style of elements that are generated during layout can depend on the style of pseudo-elements, and the span is not such a thing". I hadn't considered however the possibility of saying the span had fragments, which themselves are layout constructs and could inherit from the first-line pseudo at run-time... In that case I can see how you would expect background to inherit. Looking at our code, this is what we actually do, so I guess our behavior needs some more explanation than just "only layout constructs can have weird styles"... The correct explaination is that in Edge (and apparently Firefox too) we have this concept of render style which applies to text only, and which is the mechanism we use to transfer ::first-line styles vs other styles. That is why background does not inherit from the ::first-line even though it can be defined on the ::first-line: because it is not a text property (we do have a character-level background for selections etc, but this is another, internal-only property). The fact Chrome inherits the border is a bug though. Like the spec mentions, only properties that apply on the first line are supposed to propagate to the layout-generated boxes. Maybe to match Edge and Firefox we should update the spec and create the concept of "text styles" and specify that only "text styles properties" inherit from ::first-line to its content. |
Thanks, this clarifies the problem. My interpretation of Where should the "text styles" be specced? css-pseudo, css-cascade, css-text? I guess the editor of the appropriate spec should be notified about this problem. |
I think we would want someone from Chrome to tell their opinion on this issue. I had a quick look and I don't see this concept at all in Webkit/Blink so maybe we should just say all properties applicable to ::firstline (except background?) should inherit and file the relevant bugs in browsers. Another interesting test case is https://jsfiddle.net/bdxbptz4/ (currentColor is still resolved during computation in Edge which may explain our behaviour here). |
I have been thinking and inheritance from Suppose someone has this code, without any explicit <div>
<span>ABCDEFGHIJKLMNOPQR<br />STUVWXYZ</span>
</div> div {
background: linear-gradient(to right, cyan, yellow 75%, red);
width: 300px;
}
span {
background: inherit;
-webkit-box-decoration-break: clone;
box-decoration-break: clone;
border: 1px solid blue;
line-height: 1.5em;
} Then I think most people would expect this However, if the fragment of the span in the first line inherits the default This seems undesirable, and I see three ways to fix it:
Currently I don't see any approach to avoid this problem in the specs, I think the csswg should choose some and update the specs. |
Sound like we have a good call to resolution here. Let's wait another week to allow @tabatkins to come back from vacation, but then we should just add the Agenda+ tag and resolve on call. |
@fantasai Thanks for the label, but precisely ::first-line is not defined in selectors-4. The labels should be css-cascade-4, css-pseudo-4 and, if any, selectors-3. But now I see selectors-3 is very old so I will remove selectors from the title. @tabatkins I think you came back from vacation, what do you think about this issue? |
@FremyCompany It seems @tabatkins does not see the notifications. If you still think this needs Agenda+, maybe you can add it yourself? By the way, about what you noticed in #1097 (comment), it gets more interesting with CSS variables. For example, Firefox allows different inline boxes of the same element to have different paddings and margins. https://jsfiddle.net/bdxbptz4/1/ div::first-line { --padd: 0 30px }
span { padding: var(--padd) } Of course, this does not work with display or float. Chrome does not allow this with padding, but still does with things like color, border, letter-spacing, text-decoration, etc. Edge seems like Chrome except border. |
The css variables one is a good point. It is never mentioned anywhere they should work on ::first-line but I guess authors would expect so. How that then affects inheritance is a totally undefined territory. Added Agenda+ so we can discuss this on the call this week or next week. |
It's... not undefined? Text nodes can inherit from the ::first-line pseudo, but you can't specify a variable for them (they only get values from inheritance, and variables are resolved before inheriting). Nothing else inherits from a pseudo-element. |
That was my expectation as well but actually it looks like not only text nodes inherit from ::first-line, but apparently any inline as well. We have special code to make this work. You probably have a better idea of what the spec says than me, what do you think is the behavior you expect for http://wptest.center/#/sjfma2 ? div {
width: 75px;
--text-color: green;
}
div::first-line {
--text-color: red;
color: var(--text-color);
}
span {
color: inherit;
background: currentColor;
outline: 3px solid var(--text-color);
} Three browsers yield three different results here:
|
My reading of this is that if Edge fixed the others (unrelated) bugs we have, we would behave as Chrome in this case. My reading of the spec is that the spec says we should behave as Firefox. if --text-color:red applies on ::first-line (it obviously does) then --text-color of the span should be taken from the first line like color does. The proposed resolution here was to say that only properties that applies on ::first-line and inherit by default should be transferred, which would still include custom properties like Firefox is doing. The reason it doesn't work that way in Edge is that custom properties are not part of the Render Styles, but there is no such "render-style" concept in CSS right now. Chrome is obviously inheriting anything from ::first-line, except for some reason custom properties, so that is not consistent. |
Ahaha that's a good workaround indeed :) The currentColor difference from Chrome comes from the fact we still resolve currentColor at computation time, which means that once we reapply the styles later on for ::first-line fragments currentColor has already been flattened to "black"; if we didn't have this other bug we would match Chrome here, like I mentioned earlier. |
At first sight, Firefox seems the most flexible and useful. But I was testing, and setting So I think it would be better to say CSS variables do not apply to Alternatively, CSS variables could have two values: one inherited through the element tree, and other taking But this approach can be problematic, e.g. if a new feature allows an old property to affect the box tree. And given the great amount of bugs related to So despite CSS variables applying to |
The way this work in Edge, only render styles should be affectable by the ::first-line cascading pass. Render styles can cause layout differences but should never cause box or layer differences. If we were to allow to reset all properties this could indeed be total chaos. I don't disagree the simplest option is to make sure custom properties never propagate from ::first-line to the elements that are considered in it. That is a complete protection that seems fail-proof; relying on a careful distinction between property sets is less bug-proof. So, that would leave us with ::first-line being used, if needed, as inheriting source for properties that both inherit by default, are not custom properties, and also apply to ::first-line. I don't see a good reason not to allow to redefine a custom property on ::first-line for usage directly in ::first-line itself. |
I haven't read the entire (long!) thread, but I'd note one special Gecko (Firefox) behavior: for ::first-line (specifically -- not other pseudos), properties that don't inherit by default ('Inherited: no') have different inheritance behavior: explicit |
@dbaron Thanks, this matches observations and I think makes more sense than what the spec says. You are right this thread has become so long, so I will try to summarize it. TL;DRInheritance from
|
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: How does 'inherit' keyword behave in a child of ::first-line?<dael> Github issue: https://github.com//issues/1097 <dael> fremy: There's a proposal that makes sense. On the properties that apply on first line and inherit should inherit and not custom properties. <dael> fremy: I can explain the issue if someone needs. <dael> Rossen: Yes, please. <dael> fremy: The issue is a span is inside a div with first line. If you set on the span color: inheit will do so from first-line. In webkit if you do this wrong it also appends. It seems like it's causing some problems. <myles> dbaron++ <dael> fremy: It furthers what happens with custom properties where if you do the inherit from the first line it could befomre a block and then it's not part of first line. The prop is if custom properties & background do not inherit byt he children of the first line. <dael> fremy: If you spec a background inherits on the first line it'll inherit from the div. <dael> Florian: At first it sounds reasonable, but I expect horrible, subtle things hiding somewhere. <dael> fremy: I think proposal makes sense. <dbaron> Is the proposal written somewhere? <dael> Florian: I think so too <dael> fantasai: I agree with Florian. I don't have time to look right now. I would prefer a week to look. <dael> Rossen: We can push the resolution out a week. Let's look at this one. <dael> Rossen: Florian are you okay? <dael> Florian: Yeah. <dael> Rossen: fremy? <dael> fremy: Sure. <dael> dbaron: If we have a week, can there be a written version of the proposal? The issue is very long and I don't know what proposal we're looking at. <tantek> ^^^ that problem <dael> Rossen: fremy let's have you summerize the proposal on the github issue. |
I wanted to note there is a TLDR just above but if I have to summarize even more, the proposed resolution for next week is:
Rationale is:
|
The CSS Working Group just discussed The full IRC log of that discussion<dael> Topic: How does 'inherit' keyword behave in a child of ::first-line?<dael> github topic: https://github.com//issues/1097#issuecomment-300553985 <dael> fremy: We added this last week and people needed more time to review. <dael> fremy: Did people review? <dael> Florian: I did not. <dael> astearns: Looks like you added the summary which is great. <dael> astearns: Is it just Florian that needs to look? <TabAtkins> I haven't reviewed it, but now that Elika and I have thought more about ::first-line this week, we should be able to understand it better now. <dael> Florian: I don't think so. Reason I need to look is to see if it will scale to similar pseudos. That's forward looking. For now someone else needs to check. <dael> fantasai: I think...I was looking at proposal with that in mind. There's parts to the proposal. <dael> fantasai: The part that says if you inherit non-inheritied you go directly to parent is fine. <dael> fantasai: There was some discussion I didn't follow about how first-line is text inside a span inside a first line...it didn't make sense. Text inside a span should inherit from a span and text inside a first-line inherits from first-line. <dael> fantasai: There was something about how a unstyled firs-tline should act like the first line isn't htere. <dael> fantasai: There were three inveriants we need to preserve for things to work in the same way. <tantek> present= <dael> fantasai: One part of proposal was about variables and I don't have a strong opinion on that. THere was concern about setting display via a variable but has same problem if you set not via a variable <dael> fantasai: I'm not sure variable behavior in there is necessarily what we want, but at this point in time it doesn't much matter. It's a q for as we extend in the future. We might want variables ot work more like normal inherited then. <dael> fremy: Reason we didn't want variables to work is because first-line is more special then fragment. THere is condition that you need to be inline to be first-line. We didn't want to spend too much time figuring this out. <dael> Florian: From birds eye view it seemed sane. Id idn't review details. <dael> fantasai: I suggest we go one by one for the proposal <dael> astearns: Do we want to continue on GH? <dael> fantasai: I'm okay either way. I wand dbaron opinion on this. <dael> astearns: and dbaron can't be on so I suggest...this transcript will go into the issue. We can refine in GH and resolve next week. <dael> fantasai: sounds good. <dael> astearns: fremy? <dael> fremy: Yes. It just should be done at some point. <dael> astearns: Yeah. There's a few things to hammer out. Getting dbaron next week. Please @ him on the issue if he's not there. <dael> fremy: He's in the issue. |
@astearns Why did you remove the Agenda+ tag? Didn't you say that the CSSWG would resolve this week? |
Still waiting on a response from @dbaron or others here |
I'm fine with @FremyCompany's proposed resolution above:
I would note one issue, though. It's not clear to me that condition (1) is even needed. In most cases, an "Applies to:" line doesn't affect computed values, but I've always had the understanding that pseudo-element restrictions worked differently, and a property that doesn't apply to that pseudo-element doesn't change their computed values. I'm not sure if there's a spec that backs up that interpretation, though. And I don't think it hurts to include condition (1), except that it makes that interpretation of how application to pseudo-elements works a little bit more of a stretch since it wouldn't be needed if that interpretation were correct. |
I think the important point is that there can be some property which potentially affects the box tree and which inherits by default. This property shouldn't be inherited from With condition (1) this is easy to solve: simply don't include that property in the list of properties that apply to Without (1), maybe try not to create such a property (make it non-inheritable by default), or otherwise exclude it specifically just like custom properties in (3). This approach seems harder to maintain (in fact, are custom properties the only existing case of such a property? I'm not entirely sure.) |
My point was that condition (1) might not be needed because it's already implied by something (that should be) elsewhere in the spec that's more general, not because the concept isn't needed. And that explicitly including it might add confusion about the general point. |
The CSS Working Group just discussed
The full IRC log of that discussion<dael> Topic: How does 'inherit' keyword behave in a child of ::first-line?<dael> github topic: https://github.com//issues/1097 <dael> fremy: I had been presenting that. We were debating 2 weeks ago on dbaron's reply. <dbaron> s/debating/waiting/ <shane> OK we're in now! <dael> fremy: dbaron basically agreed witht he proposal and I think we should prob just resolve ont he behavior from the issue. <dael> fremy: We were debating on best way to enter this into the spec, it's editorial so it's up to the editor. <dael> fremy: We were trying to desc how inherit works when child of first pseudo element. <dael> fremy: To recap: The element is a child of the first-line pseudo and will generate the propety and it will inherit by default. <dbaron> Proposed resolution was: "Inheriting properties of inline fragments that are contained in a ::first-line only inherit from the ::first-line if those properties (1) do apply to ::first-line, (2) do inherit by default, and (3) are not custom properties." <dael> fremy: dbaron felt the approach was right if not the best wording. <dael> fremy: We can work throught he right wording, I guess. <dael> astearns: Anyone with more comments or wants more explination? <tantek> this sounds reasonable, I'm wondering what the interop situ is on this? <dael> fantasai: I'm a little confused why we need to check if they apply to first-line <dael> dbaron: That's what my comment was about. It wasn't about wording but if that should be more general. Normally in CSS applies to don't effect computed values. But applies to pseudo elements does effect computed has been my undderstanding. But we don't say that anywhere. <dael> dbaron: My comment was that if that is the case we should a) say it and b) remove condition 1 since it becomes redundant. <dael> fantasai: It could effect computed value on psuedo element. BUt having properties inherit differently is really hairy. There are a lot of properties where applies to is more general <dael> dbaron: It's possible that we need to seperate applies to and if properties apply to pseudo elements. That's more clear cut. <dael> TabAtkins: I agree. The rest of applies to are editorial pointered, but that's reasonably mechanically relevent <dael> fantasai: There's a lot of prop where we say it applies ot everything, but that's because it inherits. WE could tighten that, but the majority of applies to aren't tight <dael> Florian: And sometimes it's the opposite case where we state the things it doesn't apply to. It's a fuzzy mess. <dbaron> s/psuedo/pseudo/g <dael> fantasai: It's not percise enough. If it's going to determine how things inherit we need to be rigerous. I don't think we should make the spec depend on if a properties applies to. It should be if it's inherit or now. <dael> dbaron: I think we need it for if it applies to pseudo elements, but the specs aren't great on specifying. In Gecko we list every prop that applies to a pseudo in the code. If it's doesn't apply the declarations aren't applied. That's first-letter and first-line. <dael> fantasai: What's that case where we need the distinction? <dael> dbaron: display <dael> fantasai: It's not inheritable. <dael> dbaron: I need to look at examples then. <dael> fremy: I don't have a list of, but user-select would be one. <dael> Florian: Tha'ts not inherited. <dael> dbaron: I think the main reason inheritencec needed restrition was variables. <dael> fremy: Yes, yes. <dael> fremy: Variables, in that case,t hey could apply to any property. But that's condition #3 where we say we don't generate custom properties for first-line. There may be others. <dael> fantasai: If we're going to have this condition I want an example that is inheritable, not a custom prop, and doesn't apply to first-line. If there's no such property we don't need this conditional <dael> fremy: Is there a lsit of properties that inherit? <dael> fantasai: INdexes. <dael> TabAtkins: That's not tracked across specs. It's on the to do list. <dael> astearns: Sounds like we're converging on resolving to take the propsal except possible condition 1 which needs a real world example of why it's needed. <dael> fantasai: Yes. I'm happy to resolve on the rest but I don't want this conditional if it's not needed. <dael> dbaron: Writing mode and direction are the two prop I've found so far that are problematic. <dael> Florian: If you try and change the writing mode on the first-line...yeah. Don't do that. <dael> astearns: The treatment that is currently in the issue, weither or not we have that first conditional, are writing mode still problematic? <dael> dbaron: They're inherited, not custom, but no one interprets them as applying to first-line <dael> fantasai: That's a good/interesting one. First-letter could be in a different writing mode <dael> astearns: To answer tantek from earlier, it sounds like we dont' have interop. Correct? <dbaron> 'white-space' may also be a problem (with ::first-line and 'pre') <dael> fremy: it's correc,t i think. The issue was mostly Chorme allowed a few more properties to inherit and the custom properties weren't blacklisted in FF <dael> astearns: Can we resolve to accept the proposal, possibly excluding condition 1 if there is no compelling example. <dael> Florian: I think we found an example. Which leads to applies to not being specific enough to rely. <dael> fremy: We can agree on the behavior of this issue. I think we can discuss the other issue seperately. We can agree on the behavior and discuss further what applies to means. <dael> Florian: I think having or not having part 1 is a difference of behavior. <dael> Florian: I'm okay resolving this and filing issues agaist specs to tighten applies to. <dael> fantasai: That won't happen in any reasonable time frame. The exclusion list should be explicit for now and then look for a better way to distribute. Most don't take into consideration first-line and first-letter and may say "all applies" <dael> fremy: Ccurrently in psuedo spec there's a list of properties. <fantasai> https://drafts.csswg.org/css-pseudo/#first-line-styling <dael> dbaron: CSS 1 & 2 had a list of what first-line and -letter are for, but I think it was a should <dael> dbaron: That may or may not be different to the applies to line. We discussed about moving it, but we never did. <dael> Florian: Should we point to pseudo 4? <dbaron> s/ what first-line and -letter are for/ what properties apply to ::first-line and ::first-letter/ <dael> fantasai: What we need here is a list of properties that aren't inherited from the pseudo elements and we can come up witha more general apploahs, but a good black list is a starting point. <dael> astearns: Sounds like were' resolving on the proposal witha blacklist, but further define how to do it later. This is the behaior we want. <Florian> pseudo-4 isn't good enough for the list. It has the list of "at least these must apply", it does not have "these do not". <liam> [css 2.1 lists for first-letter, font properties, color property, background properties, 'word-spacing', 'letter-spacing', 'text-decoration', 'text-transform', and 'line-height', and then says, UAs may apply other properties as well. ] <liam> [ https://www.w3.org/TR/CSS2/selector.html#first-line-pseudo just before 5.12.2 first-letter ] <Florian> https://drafts.csswg.org/css-pseudo/#first-line-styling <dbaron> It could have a list of "these apply", a list of "these do not apply" and a note that if it's on neither list you should contact the spec editor. <Florian> https://drafts.csswg.org/css-pseudo/#first-letter-styling <dael> tantek: I think I like the rough approach. I asked about interop because everytime we've tried to do this in the past there has been compat issues. If someone wants to try this with simple examples it could illuminate the likelyhood of this approach. I'd propose someone writes tests to test their assumptions and show how bad the situation is. <dael> tantek: It's a hard problem <fantasai> dbaron: That's a decent approach :) <dael> astearns: Proposed resolution is try and specify this behavior and see how that proposed behavior and interop goes. <dael> RESOLVED: Take hte behavior described in the issue and work witht o to make sure it works for compat. |
@FremyCompany @Loirooriol Edited in the changes. Specifically excluded (Technically, I think we could have |
shouldn't that be "any other property" (singular)?
Why still
Other than that, sounds to be what was resolved last time, and LGTM. That said, I don't have insights into how this particular bit is currently implemented in Blink and Gecko so I can't provide more value than an informed opinion ;) |
Yes, the edit seems according to the resolution and LGTM. What I don't really like is that inheriting from ::first-line means that we have inheritance in the fragment tree, but usually inheritance is in the element tree. So interaction between |
Could go either way, I think.
Afaict this issue is about standardizing the behavior of what inherits and how, and not about standardizing which properties apply to ::first-line; and there was no serious discussion or conclusion on exactly which properties apply to ::first-line or don't. It's one of the reasons why we didn't want to make the inheritance behavior depend on that. |
TL;DR - see proposal
CSS Cascade says
It says "parent element" and "document tree", but both CSS Selectors and CSS Pseudo-elements seem to override this for
::first-line
:However, browsers do strange things (https://jsfiddle.net/0geoep6t/)
If I understand correctly, since
background
applies to::first-line
,background: inherit
should inherit from the::first-line
, like Chrome does. And sinceborder
does not apply to::first-line
,border: inherit
should inherit from thediv
, like Firefox and Edge do.Am I right? Consider adding some note to the spec to clarify this.
The text was updated successfully, but these errors were encountered: