-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Revisit image floats. #7721
Revisit image floats. #7721
Conversation
core-blocks/image/index.js
Outdated
@@ -217,6 +217,16 @@ export const settings = { | |||
/> | |||
); | |||
|
|||
if ( 'left' === align || 'right' === align ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need a deprecation handler for this change. This will make all old blocks having align
set to right or left to be recognized as externally modified.
core-blocks/image/index.js
Outdated
if ( 'left' === align || 'right' === align ) { | ||
return ( | ||
<aside> | ||
<figure className={ classes }> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid code duplication, we can assign figure
to its own variable, similar to what is done for img
above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this can be refactored to not repeat the <figure>
code and needs a deprecation handler, but the idea seems fine to me. I think the extra tag is okay; the explanation is solid, cheers! 👍
core-blocks/image/index.js
Outdated
@@ -217,6 +217,16 @@ export const settings = { | |||
/> | |||
); | |||
|
|||
if ( 'left' === align || 'right' === align ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's the style in core and it's unrelated to your patch, but constant-first does my head in… it feels unlike how anyone would speak logically about the conditional. </rant>
This looks like it'll need a deprecated
handler because this changes block markup.
core-blocks/image/index.js
Outdated
if ( 'left' === align || 'right' === align ) { | ||
return ( | ||
<aside> | ||
<figure className={ classes }> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it could be a variable defined above, so it's not duplicated.
@gziolo and I are twins! 😆 |
Thanks so much for the reviews and examples and thoughts. I think this is a 3.3 milestone thing, in any case it's sort of a sensitive change, which is why I'm going to let it sit for a bit and gather thoughts and opinions. It solves an issue, and I believe it's the best way to solve that issue. But nonetheless I expect there to be valid opinions. |
I don't follow why it would be sensitive 🤷♂️. It fixes a legit problem and doesn't remove any markup, just adds a (valid in this case) wrapper tag which, hey, sometimes you need for flexibility in HTML 😄 |
I took a stab at addressing your comments in 41b3db4, please have a look and see if I did it right. Also, I realized that this markup change only applies on the frontend. But ideally is reflected in the backend as well. The markup is a bit more verbose in the admin, which hides some of the real world issues themers have to deal with, which is why I didn't catch this the first time round. In any case, if anyone has bandwidth for helping me with adding the wrapping |
I'm having a look now 👀 EDIT: Sorry I got distracted and failed. I'll try looking at this again tomorrow (July 6); feel free to ping me on Slack if you want help or if you've got a handle on it and don't need my help anymore. 😄 |
I am not certain that |
I'm back from some vacation ready to look at this. But before I rebase and address semantics feedback (suggestions welcome — div fine?), I'd love some idea on whether we're okay with this. I'm personally very okay and believe it's the only rock solid way to achieve the necessary flexibility for layouts. But I also know it's controversial. @pento any thoughts? |
I find myself quite excited about the prospect of using |
Thanks Gary — is that also a way of stating that you would be okay with the added wrapping element when that element is floated? |
It absolutely is my obtuse way of saying I'm okay with adding a wrapping element. 😉 |
Aside should be used with caution, and mainly to mark an entire region that is "tangentially related" rather than single pieces of content. The reason is that in ARIA terms, the aside element is mapped to a complementary role which is a landmark role. Landmarks should be used to identify the main regions of a page. Having (potentially) dozens of landmarks in a page would defeat their purpose. (aside: 🙂in core there's the same problem with the widgets). |
7086ffe
to
23960d5
Compare
This PR has been rebased, squashed, updated, tested, to fix the remaining issues. I believe it's ready for final review. The small things:
Note that the editor markup differs from the frontend, due to a plethora of editor necessary containers, such as one for resizing and so on. I'm not sure we can ever get the backend markup to match the frontend, so instead I've made sure to map the containers necessary for getting floats to behave the same in the admin as the frontend. See d36cce2 for details. The trick is that when an image is floated, the parent container (block container) retains its same max-width which usually allows a centered column to coexist with wide images. But it is zeroed out in height. The child element, the figure itself, is then floated, which allows the caption to share the same width as the figure, using a table-caption trick. See also this codepen: https://codepen.io/joen/pen/zLWvrW Note that this PR only touches images. If this is approved and merged in, we'll probably want to backport these changes to other blocks that can float, i.e. video, embed, cover image — any others?. Screenshots: |
Add clarity to HTML elemeents in the comments which might also be read as words.
We have a plethora of different combinations of images and captions. Floated images with captions, non floated images with captions, small images with captions, etc. etc. In general we use a `display: table;` trick to get the caption to size itself according to the image. However if an unfloated image follows a floated image, this means the unfloated image can size itself down to "fit in the available space", which is not what we want. So for now, if you upload a small image and _don't_ float it, a wide caption will be as centered as the block itself. This might be worth revisiting, but at this point I'd like to look at that separately from this PR which is already big.
34a6c80
to
35bf4c1
Compare
I chatted with @youknowriad and he let me know the div getting those classes is normal: https://wordpress.slack.com/archives/C02QB2JS7/p1534760407000100?thread_ts=1534753637.000100&cid=C02QB2JS7 So this is all good to go by me. I say we 🚢 Thanks for all your work and the constant back and forth on this one! |
Okay, I'm merging now. While it's a big change, it's been in progress for a while, it's solid, and it's fixing a number of issues. Thanks for the reviews everyone! |
In #7721, we introduced a new wrapping div for the image block. As part of that, the margin for the figure was also zeroed out. This is what caused the regression. Most themes don't touch the figure, and it's born with 1em margin top and bottom. In testing, however, we noticed that some themes _do_ provide figure styles, and they zero them out. As such, this PR fixes the regression by: - Removing the regression. Situations with figures that worked prior to the regression will work the same. - Adding comments to the code to prevent this from happening again. - Adding an additional bottom margin to the caption style, to ensure themes that zero out the figure have some bottom margin. This PR adds a 1em bottom margin to all captions. This margin collapses if the figcaption is inside a figure, but is still there in case it's inside a div.
In #7721, we introduced a new wrapping div for the image block. As part of that, the margin for the figure was also zeroed out. This is what caused the regression. Most themes don't touch the figure, and it's born with 1em margin top and bottom. In testing, however, we noticed that some themes _do_ provide figure styles, and they zero them out. As such, this PR fixes the regression by: - Removing the regression. Situations with figures that worked prior to the regression will work the same. - Adding comments to the code to prevent this from happening again. - Adding an additional bottom margin to the caption style, to ensure themes that zero out the figure have some bottom margin. This PR adds a 1em bottom margin to all captions. This margin collapses if the figcaption is inside a figure, but is still there in case it's inside a div.
@jasmussen Glad to have found this! I've been struggling to find the answer to this question and it's popped sporadically and completely threw off a legacy theme I had developed midway through Gutenberg being released and so it's good to now actually get a concrete bit of information about it. It has recently popped up again as I am now working on developing a theme for the HeadlessWP+React+SSR framework frontity. My latest issue I posted in response to that problem. I defer to your expertise in this stuff but I'd like to ask a quick question and offer some feedback: First I'm not sure I totally understand this reasoning. Why would people apply a float to a wide image? Aren't wide images full width etc? So they would wouldn't really be floated right? Second if a wrapper div is needed, I think it should be consistent across all images. I find it kind of confusing that images are div->figure and then wide images etc are just figure. Consistency in the structure would be nice because there is some CSS that applies to all images that I would like to be able to target, and then could have the variations targeted in a nested fashion (via css-in-js or scss etc) like so: div.wp-image-block. {
opacity: 50%;
background-color: yellow;
&.alignleft {
float: left
}
&.fullwidth {
...
}
} Preferable to me though is just having figure elements but I understand that you guys have already given a lot of thought to this stuff. (I'm also curious how much of some of these problems could be addressed in a flexbox fashion? ) |
@jcklpe Sorry for the headaches this has caused you! Let me try and answer to the best of my ability!
Yes that phrasing was obtuse. You are correct, a wide and fullwide image will never be floated, so that's not the problem. The problem is: how do you create a layout that accommodates both wide, fullwide, and floated images? This codepen shows how the block editor solves it. Traditionally in themes you'd have a centered main column, something a la Therefore the approach taken for the editor styles, is one where there isn't a
This allows wide and fullwide images to go from edge to edge without having to use Floats, as you can imagine, become a challenge, because if you simply float a block, it goes right up against the edge of the viewport, where usually you'd want it to go up against the margin of the perceived main column. We accomplish this by having a wrapping container element, the div, which allows you to assign a max-width to that container, and then float the figure inside.
Yes indeed, it was unfortunate the change had to be made as such. The truth is, any image inserted after the change was made, will have the wrapping div and be consistent going forward. But images inserted before that, don't break because they lack the wrapper. You could re-insert the old images, and they will be updated to the new markup. It's a headache, I understand, but ultimately the wrapping div was added in order to give more control to themers like yourself. Wide images, floats, figures that are only as wide as the caption inside, and combinations of the three present quite the challenge to solve. Hope this helps! |
@jasmussen yes thank you that does help. Quick question though, for the purposes of my developer self education. I've been until now applying my elements to the perceived main column via margin similar to how you do here:
What I do instead is something more like this though:
and then when something is floated right I just do this
Why not do something like this second example? I see you mention vw being an issue for the editor but you seem to be saying that in the context of full width images right? Or were you saying that this is an issue for floated images in the editor because vw is based on viewport width and in the editor that layout won't be taking into account the more limited space due to the editor and wordpress admin bar etc? Why not simply have separate rules output for the admin versus the frontend? isn't that what is already done in wordpress themes? One can just build separate build outputs based on scss imports right? At the very least would it be possible to add some kind of class to the top level wp-image-block wrappers that contain an alignedright figure? That way when people want to use vw they can just apply a float to the top level container block and write a second set of styles for their admin view. |
Yes, the last part exactly. Consider here that 20vw to the right and left of the paragraph below the image would make for a very thin paragraph. However you can definitely use vw units for the front-end. What we have learned from user test is that if the editor looks like the frontend, usability is drastically increased, which is why editor styles are very much recommended. However they don't have to be 100% accurate to the front-end. So if you use % in the editor and it looks good, that's totally fine. A personal goal of mine is to make it so you can load the theme CSS directly into the editor without changes. This is a bit difficult, but there are ways to accomplish that, but it's going to take some time to make this possible.
This layout: brings with it this markup:
Was this helpful? |
Indeed, the markup you get is what I get as well. I'm not very confused how I got the other markup to show up. A glitch in the matrix? A case of lack of sleep on my part? My bad, in any case. I do understand how if the alignment class was on the parent node, there would be more control on the part of themers, yes. I think you should feel free to open a ticket to suggest that additional class. |
@jasmussen Cool. I've opened a request here: #18276 |
Just wanted to drop a comment here that randomly deciding to display images like tables (only when the is-resized class is applied) is completely insane and causes a bunch of unexpected headaches. This is extremely disappointing. |
It would be helpful if you could explain why it's bad and what would be better. Maybe open an issue suggesting how to fix it? |
This adds a wrappingaside
element to any image block that's floated left or right. From the spec, https://www.w3.org/TR/html52/grouping-content.html#the-figure-element:The above is the reasoning for using thePer subsequent discussion, we're going with a div.aside
element to wrap thefigure
.But why wrap the
figure
at all?Because due to issues surfaced in #7624 (comment), it seems our current implementation isn't responsive.
The challenge is — what if you float a very small image to the left, and write a giant caption. Even if we apply
width: fit-content;
on thefigure
, the caption will expand thefigure
to accommodate as much text as the parent wrapping element will allow.min-content
doesn't work either, because this will make thefigure
only as wide as the smallest word.What we have in master works in most cases, through dark magic, but it also only works because we remove the
max-width
from the nested image. This means the image won't resize with the viewport, and is therefore not responsive.I have explored so many many options for fixing this, and after all this time, what it boils down to is this:
figure
, so that it and thefigcaption
can be sized using table rules, as in this PR. See also https://codepen.io/joen/pen/qKGYwy?editors=1100Why not just set the width on the figure element and float that? Because then we can't accommodate wide images, which rely on an unbounded main column.
It's not ideal that we have to add an extra wrapping element, but it can be semantic, and it feels like the simplest to work with for themers implementing wide images coexisting with floats.