Repository: zulip/zulip
Pull request #33579: settings modal: Fix a few info density related issues
Author: login: evykassirer
Labels: name: size: XL
name: maintainer review
description: PR is ready for review by Zulip maintainers.
name: area: CSS quality and modernization
description: Issues related to light/dark themes, font size, and other patterns in how we use CSS.
Created: 2025-02-20T23:26:28Z | Merged: 2025-03-14T23:35:05Z

Changes:

* Scale width of "general/personal/subscriber" tabs with font size (and similar for user groups)
* Scale X button on the discard button with font size
* Left pane is always 40% width and right pane is always 60% width (previously it was 50/50 at wider screen sizes). This simplifies some CSS and also ensures there's enough space at larger font-sizes for the save/discard buttons to appear beside setting section headings without overflowing onto the next line (which was happening when the X icon got bigger)

**screenshots of subscriptions at 12/14/16/20 px**

| before | after |
| --- | --- |
| ![Screen Shot 2025-02-20 at 15 13 53](https://github.com/user-attachments/assets/7cd8d9b3-a344-466e-8182-a7aba113bc86) | ![Screen Shot 2025-02-20 at 15 21 29](https://github.com/user-attachments/assets/65f6224d-8221-44f3-9caa-2f97559c1496) |
| ![Screen Shot 2025-02-20 at 15 13 40](https://github.com/user-attachments/assets/7c4c6fd4-1651-438d-8cdf-74f497080e6d) | ![Screen Shot 2025-02-20 at 15 21 15](https://github.com/user-attachments/assets/a7141c19-d5c9-4ceb-994d-5ddc56db41a3) |
| ![Screen Shot 2025-02-20 at 15 13 20](https://github.com/user-attachments/assets/10c2639f-fad5-4192-ae04-144299d5c6e9) | ![Screen Shot 2025-02-20 at 15 21 00](https://github.com/user-attachments/assets/10d89b1d-35cc-4dec-a741-c08881c2bede) |
| ![Screen Shot 2025-02-20 at 15 13 07](https://github.com/user-attachments/assets/c00978d6-b72c-4ece-8599-ea76a0bdf04a) | ![Screen Shot 2025-02-20 at 15 20 45](https://github.com/user-attachments/assets/f1697e71-a2a6-4283-8982-b90c0edf07f7) |

**screenshots of usergroups at 12/14/16/20 px**

| before | after |
| --- | --- |
| ![Screen Shot 2025-02-20 at 15 26 09](https://github.com/user-attachments/assets/679fa4e3-35c7-4787-9d7e-e5f706b9d757) | ![Screen Shot 2025-02-20 at 15 23 27](https://github.com/user-attachments/assets/94aeef96-9d7d-4403-bdba-80cd1feabe2f) |
| ![Screen Shot 2025-02-20 at 15 25 51](https://github.com/user-attachments/assets/c0a72a5e-1463-423d-8c3a-6813914503d3) | ![Screen Shot 2025-02-20 at 15 24 04](https://github.com/user-attachments/assets/f8c032fc-e9f2-4d2c-8c00-f4aff5866412) |
| ![Screen Shot 2025-02-20 at 15 25 35](https://github.com/user-attachments/assets/196cde7a-d419-4676-b38b-57838990eefe) | ![Screen Shot 2025-02-20 at 15 24 14](https://github.com/user-attachments/assets/3cc6870a-afbc-44dd-8f91-106d2fb39a41) |
| ![Screen Shot 2025-02-20 at 15 25 14](https://github.com/user-attachments/assets/d448a72d-0d62-4516-800b-9aec039ed3eb) | ![Screen Shot 2025-02-20 at 15 24 31](https://github.com/user-attachments/assets/6c0714ff-a5db-4d67-a770-dadf9e778de8) |



Diff:
diff --git a/web/styles/app_components.css b/web/styles/app_components.css
index 0e2556221102c..199978d57fc60 100644
--- a/web/styles/app_components.css
+++ b/web/styles/app_components.css
@@ -870,11 +870,21 @@ input.settings_text_input {
     }
 }
 
+#stream_settings,
+#settings_page,
+#user_group_settings {
+    .subsection-header {
+        display: flex;
+        flex-wrap: wrap;
+    }
+}
+
 #stream_settings .save-button-controls,
 #settings_page .save-button-controls,
 #user_group_settings .save-button-controls {
-    display: inline;
-    margin-left: 15px;
+    display: flex;
+    margin: 0.2857em 0.5714em; /* 4px 8px at 14px/em */
+    align-items: center;
 
     &.hide {
         display: none;
@@ -883,13 +893,12 @@ input.settings_text_input {
     .save-discard-widget-button {
         border-radius: 5px;
         border: 1px solid hsl(0deg 0% 80%);
-        padding: 0.2143em 1em 0.2857em 0.7857em; /* 3px 14px 4px 11px at 14px/em */
         text-decoration: none;
         color: hsl(0deg 0% 47%);
-        min-width: 80px;
-        /* Limit the height of the button */
-        line-height: 1.2;
-        vertical-align: text-bottom;
+        min-width: 5.7142em; /* 80px at 14px/em */
+        display: flex;
+        align-items: center;
+        height: 1.8429em; /* 25.8px at 14px/em */
 
         &:hover,
         &:focus {
@@ -943,15 +952,11 @@ input.settings_text_input {
         }
 
         .save-discard-widget-button-icon {
-            vertical-align: middle;
             margin-right: 3px;
-            font-size: 15px;
+            font-size: 1.0714em; /* 15px at 14px/em */
             font-weight: 400;
-        }
-
-        .save-discard-widget-button-text {
-            vertical-align: middle;
-            line-height: 1;
+            display: flex;
+            align-items: center;
         }
     }
 }
diff --git a/web/styles/settings.css b/web/styles/settings.css
index 88ab84a9df445..38614f52483b5 100644
--- a/web/styles/settings.css
+++ b/web/styles/settings.css
@@ -507,6 +507,7 @@ input[type="checkbox"] {
         display: flex;
         align-items: center;
         cursor: pointer;
+        flex-wrap: wrap;
 
         .stream_setting_subsection_title {
             margin: 4px 8px;
diff --git a/web/styles/subscriptions.css b/web/styles/subscriptions.css
index f5fd91ab3220b..9b8a92ce7d166 100644
--- a/web/styles/subscriptions.css
+++ b/web/styles/subscriptions.css
@@ -122,6 +122,7 @@ h3.user_group_setting_subsection_title {
     font-size: 1.5em;
     font-weight: normal;
     line-height: 1.5;
+    margin: 4px 15px 4px 0;
 }
 
 h4.stream_setting_subsection_title {
@@ -339,89 +340,54 @@ h4.user_group_setting_subsection_title {
 }
 
 /* There's an awkward width of modal that is wider than the
-   @media breakpoint that collapses the left pane, but still
-   narrow enough (965px at 14px em) that the sort buttons need
-   a second row to be visible without overlapping other UI. */
-@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) {
-    @container subscriptions (width < calc(60em + 70px)) {
-        #subscription_overlay .subscriptions-container {
-            .left {
-                .list-toggler-container {
-                    height: 5em;
-                    justify-content: end;
-                    flex-wrap: wrap;
-                }
-
-                .tab-switcher {
-                    margin-right: 0;
-                }
-
-                .tab-switcher:first-child {
-                    /* This forces the other buttons to the next row */
-                    width: 100%;
-                    display: flex;
-                    justify-content: end;
-                }
-            }
-
-            .right .display-type {
+   breakpoint that collapses the left pane, but still narrow
+   enough that the sort buttons need a second row to be visible
+   without overlapping other UI. Note that for 16px and larger
+   font sizes, we always show two rows of buttons.
+
+   We also show two rows of buttons on particularly narrow
+   screens where there's only one panel and the overlay doesn't
+   have enough space for all the buttons. */
+@container settings-overlay (
+    ((width >= $settings_overlay_sidebar_collapse_breakpoint) and (width < calc(80em + 80px)))
+    or ((width < $settings_overlay_sidebar_collapse_breakpoint) and (width <= 36em))
+) {
+    #subscription_overlay .subscriptions-container {
+        .left {
+            .list-toggler-container {
                 height: 5em;
+                justify-content: end;
+                flex-wrap: wrap;
             }
 
-            .streams-list {
-                /* Calculated from several heights and padding/margin measurements
-                in .list-toggler-container and .stream_filter, with some added
-                fiddling to see what worked best at 12px - 20px font sizes.
-                Notably this height is shorter than the similar calculation
-                below because the toggler is taller.
-                When we redesign this area we should make this less brittle. */
-                height: calc(100% - 5.4em - 40px);
+            .tab-switcher {
+                margin-right: 0;
             }
 
-            #stream_settings {
-                height: calc(100% - 5em);
+            .tab-switcher:first-child {
+                /* This forces the other buttons to the next row */
+                width: 100%;
+                display: flex;
+                justify-content: end;
             }
         }
-    }
-}
-
-/* Copy all the above styles for the breakpoint where the overlay
-   becomes 40% left pane and 60% right pane, since that automatically
-   qualifies the modal for collapsing the buttons into two rows, and
-   especially for smaller font-sizes this will happen before the
-   breakpoint for the subscriptions container width. */
-@media (width < $lg_min) {
-    @container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) {
-        #subscription_overlay .subscriptions-container {
-            .left {
-                .list-toggler-container {
-                    height: 5em;
-                    justify-content: end;
-                    flex-wrap: wrap;
-                }
-
-                .tab-switcher {
-                    margin-right: 0;
-                }
-
-                .tab-switcher:first-child {
-                    width: 100%;
-                    display: flex;
-                    justify-content: end;
-                }
-            }
 
-            .right .display-type {
-                height: 5em;
-            }
+        .right .display-type {
+            height: 5em;
+        }
 
-            .streams-list {
-                height: calc(100% - 5.4em - 40px);
-            }
+        .streams-list {
+            /* Calculated from several heights and padding/margin measurements
+            in .list-toggler-container and .stream_filter, with some added
+            fiddling to see what worked best at 12px - 20px font sizes.
+            Notably this height is shorter than the similar calculation
+            below because the toggler is taller.
+            When we redesign this area we should make this less brittle. */
+            height: calc(100% - 5.4em - 40px);
+        }
 
-            #stream_settings {
-                height: calc(100% - 5em);
-            }
+        #stream_settings {
+            height: calc(100% - 5em);
         }
     }
 }
@@ -481,7 +447,7 @@ h4.user_group_setting_subsection_title {
         position: relative;
         display: inline-block;
         vertical-align: top;
-        width: 50%;
+        width: 40%;
         height: calc(100% - var(--settings-overlay-header-height));
         margin: 0 -2px;
     }
@@ -552,7 +518,7 @@ h4.user_group_setting_subsection_title {
     }
 
     .right {
-        width: calc(50% + 1px);
+        width: calc(60% + 1px);
 
         .nothing-selected .create_stream_button,
         .nothing-selected .create_user_group_button {
@@ -1065,7 +1031,7 @@ h4.user_group_setting_subsection_title {
 
             .ind-tab {
                 padding: 0 4px;
-                min-width: 80px;
+                min-width: 5.7142em; /* 80px at 14px/em */
                 width: auto;
                 display: flex;
             }
@@ -1446,17 +1412,6 @@ div.settings-radio-input-parent {
     .subscriptions-container {
         max-width: 95%;
     }
-
-    #groups_overlay,
-    #subscription_overlay {
-        .left {
-            width: 40%;
-        }
-
-        .right {
-            width: calc(60% - 1px);
-        }
-    }
 }
 
 @media (width < $lg_min) {


Reviews:
user: login: sahil839
body: - Text and icon for discard button seems misaligned for some font sizes like 14px and 18px.
![Screenshot from 2025-02-27 14-33-09](https://github.com/user-attachments/assets/12634a44-8647-4c60-8a70-f761dfb80311)
- On narrow screen at 16px. Is there some other way to handle this when screen space is limited? Maybe breakpoints for hiding left panel can be changed.
![Screenshot from 2025-02-27 14-34-05](https://github.com/user-attachments/assets/633f5bb1-d404-4f49-b292-3900864031c5)

state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-27T09:17:40Z
user: login: evykassirer
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-02-27T23:10:52Z
user: login: karlstolley
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-06T16:34:55Z
user: login: evykassirer
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-03-07T00:48:13Z

Review comments:
diff_hunk: @@ -0,0 +1 @@
+/srv/zulip-venv-cache/270ffd9b5616da7e0b0dfcea43f03d011c61be54/zulip-py3-venv
path: zulip-py3-venv
user: login: sahil839
body: I think was added due to changes for using `uv`.
created_at: 2025-02-27T08:56:24Z
author_association: COLLABORATOR
diff_hunk: @@ -0,0 +1 @@
+/srv/zulip-venv-cache/270ffd9b5616da7e0b0dfcea43f03d011c61be54/zulip-py3-venv
path: zulip-py3-venv
user: login: evykassirer
body: Oh oops, thanks! 🙈 
created_at: 2025-02-27T23:10:52Z
author_association: COLLABORATOR
diff_hunk: @@ -339,11 +340,16 @@ h4.user_group_setting_subsection_title {
 }
 
 /* There's an awkward width of modal that is wider than the
-   @media breakpoint that collapses the left pane, but still
-   narrow enough (965px at 14px em) that the sort buttons need
-   a second row to be visible without overlapping other UI. */
-@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) {
-    @container subscriptions (width < calc(60em + 70px)) {
+   breakpoint that collapses the left pane, but still narrow
+   enough that the sort buttons need a second row to be visible
+   without overlapping other UI. Note that for 16px and larger
+   font sizes, we always show two rows of buttons.
+
+   We also show two rows of buttons on particularly narrow
+   screens where the full overlay doesn't have enough space
+   for all the buttons. */
+@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) or (width <= 36em) {
+    @container subscriptions (width < calc(80em + 80px)) {
path: web/styles/subscriptions.css
user: login: karlstolley
body: I'm still uneasy about this compound query-within-a-query. It seems like we should be able to definite a container independent of `settings-overlay` whose width can be queried as a simple less-than condition.
created_at: 2025-03-06T16:34:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -339,11 +340,16 @@ h4.user_group_setting_subsection_title {
 }
 
 /* There's an awkward width of modal that is wider than the
-   @media breakpoint that collapses the left pane, but still
-   narrow enough (965px at 14px em) that the sort buttons need
-   a second row to be visible without overlapping other UI. */
-@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) {
-    @container subscriptions (width < calc(60em + 70px)) {
+   breakpoint that collapses the left pane, but still narrow
+   enough that the sort buttons need a second row to be visible
+   without overlapping other UI. Note that for 16px and larger
+   font sizes, we always show two rows of buttons.
+
+   We also show two rows of buttons on particularly narrow
+   screens where the full overlay doesn't have enough space
+   for all the buttons. */
+@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) or (width <= 36em) {
+    @container subscriptions (width < calc(80em + 80px)) {
path: web/styles/subscriptions.css
user: login: evykassirer
body: I was able to make things simpler because the two container queries were on elements with similar width, but:

(1) `settings-overlay` needs to be the `@container`, not `subscriptions-container`. The `subscriptions-container` is part of the CSS declaration inside the `@container` block and it doesn't seem to work unless the `subscriptions-container` is inside the `@container` classname. Maybe I'm missing something, let me know if so!

(2) There needs to be two conditions, one for the wider two-panel view and one for the narrower one-panel view. Both depend on the size of the left panel, but the `@container` query needs to be on the parent which contains the right panel which also needs to change. One possible alternative is two different queries for the left panel and right panel, but that seems overall more confusing to me. 
created_at: 2025-03-07T00:48:13Z
author_association: COLLABORATOR

PR comments:
user: login: alya
created_at: 2025-02-26T23:33:18Z
body: Feels good to me in manual testing! @sahil839 any feedback on this one?

I flagged [#issues > UI issues in channel settings (narrow windows)](https://chat.zulip.org/#narrow/channel/9-issues/topic/UI.20issues.20in.20channel.20settings.20.28narrow.20windows.29/with/2105438) while reviewing, but it's not caused by this PR.
author_association: CONTRIBUTOR
user: login: evykassirer
created_at: 2025-03-03T20:35:18Z
body: > Text and icon for discard button seems misaligned for some font sizes like 14px and 18px.

I'm having trouble reproducing this (see screenshots in the PR description for what it looks like for me). What browser are you using? Also out of curiosity what line height?
author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-03T20:57:44Z
body: Pushing a new commit to wrap the buttons to be on a second line on narrow screens (cc @alya who reported this elsewhere). It's not the most beautiful solution but it feels fine given that this area of the UI isn't redesigned yet.

![Kapture 2025-03-03 at 12 57 08](https://github.com/user-attachments/assets/1f21ac7d-26c3-4979-a1bf-fdacd7e37227)



author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-04T03:14:51Z
body: > I'm having trouble reproducing this (see screenshots in the PR description for what it looks like for me). What browser are you using? Also out of curiosity what line height?

Seems fine for 14px, but still looks slighty misaligned for 18px at 140 line height in Chrome.
author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-04T03:15:52Z
body: It is mentioned in [#issues > 🎯 UI issues in channel settings (narrow windows) @ 💬](https://chat.zulip.org/#narrow/channel/9-issues/topic/.F0.9F.8E.AF.20UI.20issues.20in.20channel.20settings.20.28narrow.20windows.29/near/2106698) that the left panel issue is fixed, but this still can be reproduced for screen width around 500px and less than that.
![Screenshot from 2025-03-04 08-42-10](https://github.com/user-attachments/assets/71663207-5120-4e7c-b64a-9d9e91fc50ba)

author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-05T19:20:01Z
body: This is what I see at 18px/140 in Chrome. I'm not sure why I can't reproduce?

<img width="684" alt="image" src="https://github.com/user-attachments/assets/e7107e6e-d12d-42b1-a33b-1101906a4cdd" />

----

> It is mentioned in [#issues > 🎯 UI issues in channel settings (narrow windows) @ 💬](https://chat.zulip.org/#narrow/channel/9-issues/topic/.F0.9F.8E.AF.20UI.20issues.20in.20channel.20settings.20.28narrow.20windows.29/near/2106698) that the left panel issue is fixed, but this still can be reproduced for screen width around 500px and less than that.

Ah I had forgotten about this narrow window case, thanks! Here's a fix

```diff
diff --git a/web/styles/subscriptions.css b/web/styles/subscriptions.css
index 8ba7c1dd2d..a79b3f8767 100644
--- a/web/styles/subscriptions.css
+++ b/web/styles/subscriptions.css
@@ -343,8 +343,12 @@ h4.user_group_setting_subsection_title {
    breakpoint that collapses the left pane, but still narrow
    enough that the sort buttons need a second row to be visible
    without overlapping other UI. Note that for 16px and larger
-   font sizes, we always show two rows of buttons. */
-@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) {
+   font sizes, we always show two rows of buttons.
+
+   We also show two rows of buttons on particularly narrow
+   screens where the full overlay doesn't have enough space
+   for all the buttons. */
+@container settings-overlay (width >= $settings_overlay_sidebar_collapse_breakpoint) or (width <= 36em) {
     @container subscriptions (width < calc(80em + 80px)) {
         #subscription_overlay .subscriptions-container {
             .left {

```
author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-06T14:18:10Z
body: I can reproduce the save-discard alignment bug only when window width is greater than 830px, might not be the exact breakpoint, but the alignment seems fine for widths less than 830px.
author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-07T00:54:33Z
body: > I can reproduce the save-discard alignment bug only when window width is greater than 830px, might not be the exact breakpoint, but the alignment seems fine for widths less than 830px.

I tried at several widths but couldn't reproduce. Could you see if you can find an alignment fix on your end and I can incorporate that?
author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-07T07:30:06Z
body: Ok. I will try to fix that.

Also, noticed this -
![Screenshot from 2025-03-07 12-52-17](https://github.com/user-attachments/assets/b97c2a6f-d70e-4e59-baee-cfefa4901f20)

author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-11T13:46:37Z
body: I did the following change -
```diff
diff --git a/web/styles/app_components.css b/web/styles/app_components.css
index f50c63721e..9f7247d843 100644
--- a/web/styles/app_components.css
+++ b/web/styles/app_components.css
@@ -955,6 +955,10 @@ input.settings_text_input {
             margin-right: 3px;
             font-size: 1.0714em; /* 15px at 14px/em */
             font-weight: 400;
+
+            &:before {
+                vertical-align: middle;
+            }
         }
 
         .save-discard-widget-button-text {
```

This fixes the case I shared above, but results in icon being slightly above at some screen width. Maybe you can check once.
![image](https://github.com/user-attachments/assets/831916ac-2f21-4006-a034-df5df4afd1d0)

author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-11T16:58:44Z
body: Updates:
* Rebased and resolve conflicts
* Removed the left margin from headings
* Instead of doing your change, I tried adding more flex and center alignment to the icons. Does that have a similar effect for you?

The slightly above alignment is hard to fix, and I think it's due to the icon's height itself (similar to our issues with emoji alignment). I think this is fine given that we'll want to redesign this UI and use a proper icon in the future.
author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-12T07:38:19Z
body: > Instead of doing your change, I tried adding more flex and center alignment to the icons. Does that have a similar effect for you?

I can still reproduce this without doing any changes in the PR.
![image](https://github.com/user-attachments/assets/4a3c3aaa-0263-4e50-b8ba-a59bc7cb69de)

author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-12T07:38:40Z
body: Yes, issue seems due to height. Will setting the icon height help?
author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-12T17:35:58Z
body: > Yes, issue seems due to height. Will setting the icon height help?

That doesn't seem to make any difference.
author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-12T17:36:27Z
body: > I can still reproduce this without doing any changes in the PR.

Does adding the same `vertical-align: middle;` on top of the current state of the PR still fix it for you?
author_association: COLLABORATOR
user: login: sahil839
created_at: 2025-03-13T03:44:59Z
body: > > I can still reproduce this without doing any changes in the PR.
> 
> Does adding the same `vertical-align: middle;` on top of the current state of the PR still fix it for you?

No.
author_association: COLLABORATOR
user: login: evykassirer
created_at: 2025-03-14T05:04:20Z
body: @timabbott how would you feel about integrating this PR as is, and doing this icon twiddling as a followup issue? I'd like to make sure the rest of it gets enough burn in on CZO, and I'm having trouble getting the last bit fixed in a way that works for me locally as well as for Sahil (whose issue I can't reproduce locally).
author_association: COLLABORATOR
user: login: timabbott
created_at: 2025-03-14T23:36:00Z
body: Yeah, I think it's probably better to merge this and fix that forward. Please make sure that save/discard icon issue is tracked as a release goal, maybe just start a new issues thread with a target on it, since I think weird quirks like this benefit from visibility.
author_association: MEMBER