Просмотр исходного кода

[web] Update footer responsiveness with container queries (#22346)

* Remove padding around the footer

* Use CSS container queries instead of media queries on the full window

Container queries are supported by 92.76%	of web users, which can be an issue.
https://caniuse.com/css-container-queries

Though we do use them in other places

* Use `@supports` to check if `@container` can be used and use mixins

* Add the max sidebar width the fallback media query

* Update the footer responsiveness so we don't affect the default variant

GitOrigin-RevId: bed3e4244f1a97fd84740dcf87fb27c760be91ad
Antoine Clausse 1 год назад
Родитель
Сommit
b165e71ba9

+ 52 - 50
services/web/frontend/js/features/project-list/components/project-list-ds-nav.tsx

@@ -63,60 +63,62 @@ export function ProjectListDsNav() {
       <main className="project-list-wrapper">
         <SidebarDsNav />
         <div className="project-ds-nav-content">
-          {error ? <DashApiError /> : ''}
-          <UserNotifications />
-          <div className="project-list-header-row">
-            <ProjectListTitle
-              filter={filter}
-              selectedTag={selectedTag}
-              selectedTagId={selectedTagId}
-              className="text-truncate d-none d-md-block"
-            />
-            <div className="project-tools">
-              <div className="d-none d-md-block">
-                {selectedProjects.length === 0 ? (
+          <div className="p-4">
+            {error ? <DashApiError /> : ''}
+            <UserNotifications />
+            <div className="project-list-header-row">
+              <ProjectListTitle
+                filter={filter}
+                selectedTag={selectedTag}
+                selectedTagId={selectedTagId}
+                className="text-truncate d-none d-md-block"
+              />
+              <div className="project-tools">
+                <div className="d-none d-md-block">
+                  {selectedProjects.length === 0 ? (
+                    <CurrentPlanWidget />
+                  ) : (
+                    <ProjectTools />
+                  )}
+                </div>
+                <div className="d-md-none">
                   <CurrentPlanWidget />
-                ) : (
-                  <ProjectTools />
-                )}
+                </div>
               </div>
-              <div className="d-md-none">
-                <CurrentPlanWidget />
-              </div>
-            </div>
-          </div>
-          <div className="project-ds-nav-project-list">
-            <OLRow className="d-none d-md-block">
-              <OLCol lg={7}>
-                <SearchForm
-                  inputValue={searchText}
-                  setInputValue={setSearchText}
-                  filter={filter}
-                  selectedTag={selectedTag}
-                />
-              </OLCol>
-            </OLRow>
-            <div className="project-list-sidebar-survey-wrapper d-md-none">
-              <SurveyWidget />
             </div>
-            <div className="mt-1 d-md-none">
-              <div
-                role="toolbar"
-                className="projects-toolbar"
-                aria-label={t('projects')}
-              >
-                <ProjectsDropdown />
-                <SortByDropdown />
+            <div className="project-ds-nav-project-list">
+              <OLRow className="d-none d-md-block">
+                <OLCol lg={7}>
+                  <SearchForm
+                    inputValue={searchText}
+                    setInputValue={setSearchText}
+                    filter={filter}
+                    selectedTag={selectedTag}
+                  />
+                </OLCol>
+              </OLRow>
+              <div className="project-list-sidebar-survey-wrapper d-md-none">
+                <SurveyWidget />
+              </div>
+              <div className="mt-1 d-md-none">
+                <div
+                  role="toolbar"
+                  className="projects-toolbar"
+                  aria-label={t('projects')}
+                >
+                  <ProjectsDropdown />
+                  <SortByDropdown />
+                </div>
+              </div>
+              <div className="mt-3">
+                <TableContainer bordered>
+                  {tableTopArea}
+                  <ProjectListTable />
+                </TableContainer>
+              </div>
+              <div className="mt-3">
+                <LoadMore />
               </div>
-            </div>
-            <div className="mt-3">
-              <TableContainer bordered>
-                {tableTopArea}
-                <ProjectListTable />
-              </TableContainer>
-            </div>
-            <div className="mt-3">
-              <LoadMore />
             </div>
           </div>
           <FatFooter {...footerProps} />

+ 65 - 8
services/web/frontend/stylesheets/bootstrap-5/components/footer.scss

@@ -1,5 +1,60 @@
 @use 'sass:map';
 
+// Max width of the sidebar
+$footer-width-delta: 320px;
+
+@mixin footer-container-up($bp) {
+  $size: map.get($grid-breakpoints, $bp);
+
+  @supports (container-type: inline-size) {
+    @container fatfooter (width >= #{$size}) {
+      @content;
+    }
+  }
+
+  @supports not (container-type: inline-size) {
+    @at-root {
+      .project-ds-nav-page & {
+        @media (min-width: #{$size + $footer-width-delta}) {
+          @content;
+        }
+      }
+
+      :not(.project-ds-nav-page *) & {
+        @media (min-width: #{$size}) {
+          @content;
+        }
+      }
+    }
+  }
+}
+
+@mixin footer-container-down($bp) {
+  $size: map.get($grid-breakpoints, $bp);
+
+  @supports (container-type: inline-size) {
+    @container fatfooter (width < #{$size}) {
+      @content;
+    }
+  }
+
+  @supports not (container-type: inline-size) {
+    @at-root {
+      .project-ds-nav-page & {
+        @media (max-width: #{$size + $footer-width-delta}) {
+          @content;
+        }
+      }
+
+      :not(.project-ds-nav-page *) & {
+        @media (max-width: #{$size}) {
+          @content;
+        }
+      }
+    }
+  }
+}
+
 footer.site-footer {
   background-color: var(--bg-light-primary);
   border-top: 1px solid var(--border-primary-dark);
@@ -63,6 +118,8 @@ footer.site-footer {
 }
 
 .fat-footer {
+  container-name: fatfooter;
+  container-type: inline-size;
   background: var(--bg-dark-primary);
   color: var(--content-secondary-dark);
   display: flex;
@@ -71,7 +128,7 @@ footer.site-footer {
   .fat-footer-container {
     margin: var(--spacing-11) auto;
 
-    @include media-breakpoint-down(sm) {
+    @include footer-container-down(sm) {
       margin: var(--spacing-11) 0;
     }
   }
@@ -177,7 +234,7 @@ footer.site-footer {
     white-space: nowrap;
   }
 
-  @include media-breakpoint-down(md) {
+  @include footer-container-down(md) {
     .fat-footer-sections {
       grid-template-columns: repeat(2, 1fr);
       grid-template-rows: repeat(4, auto);
@@ -214,7 +271,7 @@ footer.site-footer {
         gap: var(--spacing-09);
         justify-content: center;
 
-        @include media-breakpoint-down(sm) {
+        @include footer-container-down(sm) {
           gap: var(--spacing-06);
         }
       }
@@ -234,7 +291,7 @@ footer.site-footer {
     }
   }
 
-  @include media-breakpoint-up(md) {
+  @include footer-container-up(md) {
     .fat-footer-container {
       width: (map.get($grid-breakpoints, 'md') - ($spacing-04 * 2));
     }
@@ -280,7 +337,7 @@ footer.site-footer {
     }
   }
 
-  @include media-breakpoint-up(lg) {
+  @include footer-container-up(lg) {
     .fat-footer-container {
       width: (map.get($grid-breakpoints, 'lg') - $spacing-07);
     }
@@ -290,7 +347,7 @@ footer.site-footer {
     }
   }
 
-  @include media-breakpoint-up(xl) {
+  @include footer-container-up(xl) {
     .fat-footer-container {
       width: (map.get($grid-breakpoints, 'xl') - $spacing-09);
     }
@@ -343,7 +400,7 @@ footer.site-footer {
 .website-redesign-fat-footer,
 .website-redesign .fat-footer {
   .fat-footer-container {
-    @include media-breakpoint-down(sm) {
+    @include footer-container-down(sm) {
       margin: var(--spacing-11) 0;
     }
   }
@@ -381,7 +438,7 @@ footer.site-footer {
     background-image: url('../../../../public/img/ol-brand/overleaf-black.svg');
   }
 
-  @include media-breakpoint-down(sm) {
+  @include footer-container-down(sm) {
     .fat-footer-sections {
       grid-template-columns: repeat(1, 1fr);
       grid-template-rows: repeat(6, auto);

+ 1 - 7
services/web/frontend/stylesheets/bootstrap-5/pages/project-list-ds-nav.scss

@@ -133,17 +133,11 @@
       overflow-y: auto;
       position: relative;
       background-color: var(--bg-light-secondary);
-      padding: var(--spacing-08) var(--spacing-06);
 
-      @include media-breakpoint-up(md) {
-        padding: var(--spacing-08);
+      @media (width >= 768px) {
         border-top-left-radius: var(--border-radius-large);
       }
     }
-
-    .fat-footer-container {
-      width: 100% !important;
-    }
   }
 
   .ds-nav-icon-dropdown {