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

[RFC/WIP] Refs #????? -- Switched to logical properties in CSS. #17560

Draft
wants to merge 28 commits into
base: main
Choose a base branch
from

Conversation

ngnpope
Copy link
Member

@ngnpope ngnpope commented Nov 30, 2023

Over the past few months there have been a lot of regressions and subsequent fixes for various issues with RTL CSS.

For example: #17561, #17558, #17556, #17516 (comment), #17514, #16685, #16684, #16675... And that's just this year alone.

I'm wondering if it's just time to switch as much as possible of this over from physical to logical properties?

Support is generally pretty good now. We're probably just waiting a few months for the support percentage to creep up for Chrome/Edge for float, clear and some others which were unflagged in v118, but I think it's worth discussing now. We can also make use of @supports if necessary -- which is widely supported -- to check for some cases and fall back to physical properties for a period of time. A notable exception is lack of support for logical background-position, but we could perhaps be clever with use of CSS variables for this (which I haven't investigated here).

I've knocked up a script that can generate a bunch of commits so that we can easily re-run it. There will likely be a few manual things to tweak also, e.g. related to splitting shorthand properties that don't support logical dimensions. We'd also need to ensure that the documentation is updated to require use of logical properties (and perhaps add a linting check to avoid them creeping in).

Anyway... Is this a good idea worth pursuing? Pinging @knyghty and @felixxm for their input as they've fixed most of these issues.

@knyghty knyghty self-requested a review November 30, 2023 12:51
Copy link
Member

@knyghty knyghty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some (very) initial thoughts:

  1. Great idea!
  2. I wonder how much of this code is used or necessary as we've moved more and more to flex.
  3. I didn't know these existed at all! I worry a bit that these selectors are less well known and a bit harder for people to immediately understand.

From 2:

  • Is it better to do an audit and clean up unused styles first or do this first? Or no substantial difference?
  • I'd like to move more things to flex (it's on my list...), which would also likely reduce the need for RTL-specific styles.

@ngnpope
Copy link
Member Author

ngnpope commented Nov 30, 2023

  1. Great idea!

Why, thank you! 😄

  1. I wonder how much of this code is used or necessary as we've moved more and more to flex.

A good question, and probably not straightforward to answer. I could have a look through to see if there are any unused rules as a first pass. This will still probably make migrating things over to flex layout easier as it'll reduce how much thought needs to go into margins/padding, etc. There will also be cases that will still require these properties over flex. In addition, logical properties also help for vertical layout modes rather than only thinking about RTL.

  1. I didn't know these existed at all! I worry a bit that these selectors are less well known and a bit harder for people to immediately understand.

They've been around for quite a while, but some have taken more time to mature and there are still some issues, notably around shorthand rules, e.g. margin still expands to the physical properties and there was talk about a !logical modifier or perhaps something else. This isn't a problem though as we can use the separate logical properties, e.g. margin-{block,inline} or margin-{block,inline}-{start,end}.

This is also why I proposed a simple linting rule to check that we're not using the undesired properties.

  • Is it better to do an audit and clean up unused styles first or do this first? Or no substantial difference?

Probably worthwhile, yes. I already did some partial clean up in b9ad9fe and would likely look at what using CSS variables and calc() for the background images could look like as that's the last big unsupported thing.

  • I'd like to move more things to flex (it's on my list...), which would also likely reduce the need for RTL-specific styles.

For sure. As mentioned above, I think this could simplify that migration to more flex stuff by already cleaning up some of the warts related to RTL.


Now that we also have the support for generating screenshots in CI, it'll be interesting to do some comparisons! 🖼️

@thibaudcolas
Copy link
Sponsor Member

thibaudcolas commented Nov 30, 2023

This is great :)

The need for this is pretty clear-cut to me, it’s just not productive to maintain separate RTL styles when logical properties and values are possible, but there are enough specific implementation details that need careful consideration so I’d recommend proceeding with a DEP so there’s room for people to validate specific details of the implementation plan.

I’d like to see specifically:

  • Whether the browser support is good enough for use in Django (Chrome/Edge since October/November 2023 for logical float: inline-start and inline-end, Safari 15 in September 2021 for border radius properties, Safari 14.1 from 2021 for lots of stuff)
  • Whether we really do need to use logical properties and values for both the horizontal and vertical axis, or whether we could do horizontal only (so LTR <-> RTL mirroring). I’d have thought the horizontal axis would be enough, as I can’t imagine anyone wanting to use Django in a TTB+RTL layout.
  • A plan for linting. I don’t see usage of logical properties and values being enforced without linting. We’ve just started discussing linting for CSS on the forum, but only in passing. I’ve already written Stylelint configs to enforce usage of logical properties and values if it helps, but we’d need to agree to use Stylelint first.
  • A plan for contributor docs. This stuff is simple once you know it but if you don’t it’s really surprising.
  • A plan for background-position and similar CSS transforms that only have physical values, with a CSS variable reversing the direction ideally rather than :dir or [dir] style overrides

If possible – I don’t think Django does this well currently but I’d also like to see:

  • An assessment of how much JS and Python code would need adapting for RTL languages (hopefully not too much)
  • Some ideas about how to rework Django’s icons so they’re mirrored.
  • How we will engage with people who actually use right-to-left languages to work on this and QA the work.

And ideally as "stretch goals":

  • A plan for code cleanup / moving more things to Flexbox or Grid.
  • A QA plan involving a visual regression testing setup, as this will be a case where for LTR languages there should be no changes at all. So this would be very simple to test with visual regression tools.

I wouldn’t recommend the cleanup being a pre-condition for this work. There’s plenty enough benefits to switching even unused code to logical properties and values :)

@ngnpope
Copy link
Member Author

ngnpope commented Dec 4, 2023

...but there are enough specific implementation details that need careful consideration so I’d recommend proceeding with a DEP so there’s room for people to validate specific details of the implementation plan.

Ok. Not sure there is all that much that it would require a DEP, but I guess we can look into doing one... Has the when to DEP or not thing been worked out yet - I know there was some discussion recently? It's never really been clear, and I'm concerned I'd spend time on something that nobody will engage with.

  • Whether the browser support is good enough for use in Django (Chrome/Edge since October/November 2023 for logical float: inline-start and inline-end, Safari 15 in September 2021 for border radius properties, Safari 14.1 from 2021 for lots of stuff)

So currently it looks like we're at 82.92% for the logical float/clear stuff. Am sure this has jumped up since last week. Based on our browser support, there is some leeway with this, but I expect we wouldn't be looking at landing something like this for a few months yet, but we can still plan.

  • Whether we really do need to use logical properties and values for both the horizontal and vertical axis, or whether we could do horizontal only (so LTR <-> RTL mirroring). I’d have thought the horizontal axis would be enough, as I can’t imagine anyone wanting to use Django in a TTB+RTL layout.

The point is that the vertical stuff should largely come for free (except for the background-position situation). We may not explicitly choose to support it, but if the writing mode is changed to be vertical and we're using logical properties/values, etc. it should all just flow as expected. The idea is that we shouldn't need to think about different directions as distinct things.

  • A plan for linting. I don’t see usage of logical properties and values being enforced without linting. We’ve just started discussing linting for CSS on the forum, but only in passing. I’ve already written Stylelint configs to enforce usage of logical properties and values if it helps, but we’d need to agree to use Stylelint first.

For sure. We'd want to make sure we don't regress. This is quite trivial, but we definitely will need something in place. Have seen the discussions and it seems positive, which is great.

  • A plan for contributor docs. This stuff is simple once you know it but if you don’t it’s really surprising.

This will be the biggest thing. Linting will help highlight stuff, but we effectively need to define our policy on this so that it's clear what the expectation is when contributing. Alas, visibility of this always seems to be the challenge - people will always contribute without reading the guidelines 🤷🏻

When we do this, we'll likely call it out in the top section of the release notes that the admin has changed to using logical properties with a link to the details in the conributing guide. The good news is that, where people have overridden stuff using physical properties, they've probably largely only considered LTR anyway, and things should mostly continue to work as before in those situations with no backward compatibility issues. Even where people have overridden for RTL with physical properties should work in general, but there may be small issues here and there.

  • A plan for background-position and similar CSS transforms that only have physical values, with a CSS variable reversing the direction ideally rather than :dir or [dir] style overrides

This is what I want to investigate next. We'll need one of those overrides at the top level to define the variable(s), but the idea is that everything else flows from that.

  • An assessment of how much JS and Python code would need adapting for RTL languages (hopefully not too much)

A good shout. I don't think there is much, but this reminds me that we should also look at the various error pages, etc. I've mainly focused on the admin at this point.

  • Some ideas about how to rework Django’s icons so they’re mirrored.

Also interesting. Some of this is handled by using multiple icons, but are there situations where we can flip and/or rotate instead? 🤔

  • How we will engage with people who actually use right-to-left languages to work on this and QA the work.

Another excellent point. I have an idea of a few people we could ask, but it'd be good to put out a call on the forum, perhaps when we have progressed with an initial DEP or such...

  • A plan for code cleanup / moving more things to Flexbox or Grid.

While I'm all for this, I think we should keep this firmly as a separate goal. I don't see that switching properties from physical to logical would be an impediment to this in any way - in fact, I think it may even simplify the task. It's likely that we can even delete some of the logical styles when migrating things to flex or grid as those layout models take flow directions into consideration by design.

  • A QA plan involving a visual regression testing setup, as this will be a case where for LTR languages there should be no changes at all. So this would be very simple to test with visual regression tools.

We've added the capability to take screenshots, but there isn't support for easy comparison yet. I guess we could look into something like percy.io or equivalent - maybe some generous company will donate it as a freebie? 🤞🏻

I wouldn’t recommend the cleanup being a pre-condition for this work. There’s plenty enough benefits to switching even unused code to logical properties and values :)

Agreed. Clean up is good irrespective of when it comes. If some things come before, that's just a bonus of smaller diffs for review.

@thibaudcolas
Copy link
Sponsor Member

thibaudcolas commented Dec 6, 2023

@ngnpope if you’re hesitant to start the DEP I’d happily volunteer to do that, at least a first draft which you can add to at a later date? Let me know what you think. @knyghty what do you think, does this "require a DEP"?

As far as engaging with it once opened – there are a lot of glaring issues with Django’s RTL support currently, and @django/accessibility has been struggling a lot with the state of Django’s CSS, which this work would help in improving quite a bit. So personally I’d suspect this will be smooth-sailing to take through.


Re browser support – sounds good to me!


The point is that the vertical stuff should largely come for free (except for the background-position situation). We may not explicitly choose to support it, but if the writing mode is changed to be vertical and we're using logical properties/values, etc. it should all just flow as expected. The idea is that we shouldn't need to think about different directions as distinct things.

It’s not really for free though, as it means people who write code will need to think of left-right mirroring and of the "vertical" axis direction. Personally I doubt anyone wants to use the Django admin in a TTB-RTL layout, so I’d rather we skipped this entirely.


Some ideas about how to rework Django’s icons so they’re mirrored.

Also interesting. Some of this is handled by using multiple icons, but are there situations where we can flip and/or rotate instead? 🤔

I would recommend it’d be better for maintenance if we had a policy to only use icons in the UI that are either non-directional, or that can safely be mirrored. That way you don’t have to write so many overrides on "which icon to use in which variant of the admin" – you just write individual icon definitions with the LTR perspective, and then have some way to define which icons are and aren’t mirrored.

A note on icons mirroring – I think this should also be in the "separate goal" / "not MVP" area, because Django’s icon definitions are currently really hard to work with for other reasons, and I think it’d be better to fix this tech debt before changing the code for RTL support. Starting to use logical properties and values is plenty enough work as it is.

A plan for code cleanup / moving more things to Flexbox or Grid.

While I'm all for this, I think we should keep this firmly as a separate goal.

Same. I think it’d be nice to cover this in the DEP nonetheless, but not as something that must happen as part of this switch to logical properties.

We've added the capability to take screenshots, but there isn't support for easy comparison yet. I guess we could look into something like percy.io or equivalent - maybe some generous company will donate it as a freebie? 🤞🏻

Yeah Percy would be great. It does have a free tier, but I’m not sure the free tier would be enough for what we’d need here.

I can recommend BackstopJS for one-off efforts like this, as something we’d run locally. I’ve used it extensively so happy to expand further on what this would look like.

@thibaudcolas
Copy link
Sponsor Member

There’s overwhelming support for setting up Prettier for CSS in the forum discussion about Adding a formatter for CSS & JS. Based on discussions here and on that forum thread, do people think we should start a forum discussion about linting CSS already? Or wait for more to happen with either the auto-formatting or this logical properties and values refactoring?

@ngnpope
Copy link
Member Author

ngnpope commented Dec 6, 2023

I think it's worth starting the discussion. Things can be done in phases - just having something in place to begin with would be great and then adapting the rules for logical properties later would be best.

@ngnpope
Copy link
Member Author

ngnpope commented Dec 6, 2023

Regarding the DEP - sounds fine if there is enough interest in it. Happy to put something together if we want to take that path. I just wasn't sure whether this was big enough a change to warrant it.

I can recommend BackstopJS for one-off efforts like this, as something we’d run locally.

Nice. I'm also currently working on overhauling django-docker-box to make it easier to work with and resolve many longstanding issues. One thing will be making it easy to work with linting and coverage and get the output/reports. This could be something we wire in to that too to reduce the barrier to contribution.

@knyghty
Copy link
Member

knyghty commented Dec 6, 2023

@knyghty what do you think, does this "require a DEP"?

I think it's easier to start with a forum post and then move to a DEP if there's no clear consensus, personally. But it's also unclear on what requires one or not.

@thibaudcolas
Copy link
Sponsor Member

👍 thanks! Main reason I suggested a DEP over a forum post is there there are a lot of aspects to this that I think it’d be easier to validate by reviewing a documented implementation plan, where there can be multiple drafts, rather than a long thread of replies. But if others think it’s not needed, happy to follow suite!

@thibaudcolas
Copy link
Sponsor Member

Hi @ngnpope, happy new year :) I thought I’d check in and ask what your plans are to move this along?

I see right-to-left support as a great way to get new people involved with core development, as there are lots of obvious gaps. I’m aware of a few development sprints coming up in the first half of 2024, as well as programs dedicated to new contributors – where this work would make for lovely contributions.

What are your plans? Do you still intend to publish a forum post about this?

@ngnpope
Copy link
Member Author

ngnpope commented Jan 8, 2024

Hi @thibaudcolas. I haven't really had a chance to look into this yet. Might do later in the month.

@ngnpope
Copy link
Member Author

ngnpope commented Jan 8, 2024

I think there's no need to rush here anyway... I get that it'd be a nice clean up prior to flex stuff, but if you want to focus on that, then I think that should happen independently.

So currently it looks like we're at 82.92% for the logical float/clear stuff.

This is now 85.57% with Chrome < 118 at 5.28% being the biggest detriment. In a few months time I expect we'll be > 90% and it'll mostly be mobile browsers, e.g. Samsung Internet, that affect this.

This will be one of the things that I want to consider - do we need to go down the @supports route or do we just hold on a little longer? Also - do we care about mobile browsers like Samsung Internet and Opera Mobile, or not, if they haven't gained support for these rules?

What are your plans? Do you still intend to publish a forum post about this?

I think I'll do a forum post, but I'd like to consider some more things first, e.g. an approach to handling background images and icons.

@thibaudcolas
Copy link
Sponsor Member

👍 thanks :)

Samsung Internet is a Chromium derivative, I don’t know how many versions behind Google Chrome they’re at but we could do the math and I wouldn’t be surprised if they did land support by the time this work would be released for Django.

For Opera Mobile, be worth double checking Django’s exact browser support rules but I wouldn’t expect it’s one we want to support.

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