Merge pull request #54186 from nextcloud/chore/refactor-header-scss

refactor: de-duplicate header styles, add comments and mark deprecations
This commit is contained in:
Ferdinand Thiessen 2025-08-06 11:35:28 +02:00 committed by GitHub
commit 7c69862a5d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 183 additions and 214 deletions

File diff suppressed because one or more lines are too long

View file

@ -1 +1 @@
{"version":3,"sourceRoot":"","sources":["header.scss","variables.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GCEA;AAAA;AAAA;AAAA,GDMA,mBAEC,yBACA,sBACA,qBACA,iBAEA,2QAGC,aAEA,qTACC,YACA,kBACA,oBACA,2BACA,WACA,WACA,kBACA,oDACA,uBACA,UAIF,2CAEC,uDAEA,0OACC,WAGD,2HACC,uBAOH,+DAGC,oBACA,kBACA,MACA,WACA,aACA,OCiCe,KDhCf,sBACA,8BAID,WACC,cACA,0BACA,kBACA,wBACA,sBACA,UACA,mBACA,aACA,eACA,gBACA,WAEA,mCACC,UAWD,8BACC,8CACA,sDACA,yCACA,sBACA,aACA,kBACA,gBAbD,gBACA,oCAcC,qBACA,ICRc,KDSd,SACA,gBAEA,gDACC,aAID,oCACC,gCACA,iDACA,YACA,YACA,SACA,QACA,kBACA,oBACA,sBAGD,mEAEC,iCAvCF,gBACA,oCA0CA,cACC,oBACA,yFACA,4BACA,wBACA,2BACA,WACA,kBACA,wBACA,QACA,WAEA,gFAGD,kCACC,aACA,wBACA,cAGD,oFAEC,oBACA,mBAGD,4CACC,SACA,mBACA,YAGD,wCACC,yBACA,cAKA,8CACC,gDAED,iDAEC,YACA,kBACA,yEACC,aACA,uBACA,mBACA,MCtFY,KDuFZ,YACA,eACA,YACA,UACA,aAEA,qFACC,UAGD,qGACC,aASL,0CACC,YAKD,gBACC,yCACA,eACA,iBACA,SACA,UACA,uBACA,gBACA,uBAEA,cAGD,aACC,aACA,sBACA,gBAGD,cACC,gBACA,uBAGD,kBACC,yCACA,kBACA,gBACA,eACA,iBACA,gBACA,uBAID,cACC,kBACA,gBACA,aACA,WACA,uBACA,aACA,aACA,eACA,SAEA,2BACC,IChKc,KDuKf,gDACC,mBACA,eAED,gJAEC,qBACA,YACA,WAIF,8DACC,QACC,wBAGD,sBACC,wCAGD,MAEC","file":"header.css"}
{"version":3,"sourceRoot":"","sources":["header.scss"],"names":[],"mappings":"AAAA;AAAA;AAAA;AAAA;AAAA,GAYA,cACC,kBACA,gBACA,aACA,WACA,uBACA,aACA,aACA,eACA,SAEA,2BACC,yBAKF,QAEC,yBACA,sBACA,qBACA,iBAGA,2BACC,oBACA,kBACA,MACA,WACA,aACA,4BACA,sBACA,8BAID,mBACC,cACA,0BACA,kBACA,iDACA,sBACA,UACA,mBACA,aACA,eACA,gBACA,WAEA,mDACC,UAID,yBACC,oBACA,yFACA,4BACA,wBACA,2BACA,WACA,kBACA,wBACA,QACA,WAEA,gFAMF,iIAGC,aAEA,sJACC,YACA,kBACA,oBACA,2BACA,WACA,WACA,kBACA,oDACA,uBACA,UAOF,sBACC,oBACA,mBACA,SACA,mBACA,YAKD,oBACC,oBACA,mBACA,yBACA,cAEA,uDAIA,iDAEC,YACA,kBACA,yEACC,aACA,uBACA,mBACA,2BACA,sCACA,eACA,YACA,UACA,aAEA,qFACC,UAGD,qGACC,aAIF,6DACC,8CACA,sDACA,yCACA,sBACA,aACA,kBACA,gBAvJH,mDACA,+EAwJG,qBACA,yBACA,SACA,gBAEA,iGACC,aAID,yEACC,gCACA,iDACA,YACA,YACA,SACA,QACA,kBACA,oBACA,sBAGD,wIAEC,iCAjLJ,mDACA,+EAsLG,mFACC,mBACA,eAED,sNAEC,qBACA,YACA,WAQJ,wBACC,yCACA,eACA,iBACA,SACA,UACA,uBACA,gBACA,uBAEA,cAGA,qCACC,aACA,sBACA,gBAEA,mDACC,gBACA,uBAGD,uDACC,yCACA,kBACA,gBACA,iCACA,mCACA,gBACA,uBAMJ,8DACC,2BACC,wBAGD,sBACC,wCAGD,MAEC","file":"header.css"}

View file

@ -3,16 +3,86 @@
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
@use 'variables';
/* prevent ugly selection effect on accidental selection */
#header,
#expanddiv {
@mixin header-menu-height() {
min-height: calc(var(--default-clickable-area) * 1.5); // show at least 1.5 entries
max-height: calc(100vh - var(--header-height) - (2 * var(--default-grid-baseline)));
}
/* Skip navigation links show only on keyboard focus */
#skip-actions {
position: absolute;
overflow: hidden;
z-index: 9999;
top: -999px;
inset-inline-start: 3px;
padding: 11px;
display: flex;
flex-wrap: wrap;
gap: 11px;
&:focus-within {
top: var(--header-height);
}
}
/* HEADERS ------------------------------------------------------------------ */
#header {
// prevent ugly selection effect on accidental selection
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
// for legacy the reasons the guest layout also uses the same id, so we need to exclude it as it uses a different layout.
&:not(.header-guest) {
display: inline-flex;
position: absolute;
top: 0;
width: 100%;
z-index: 2000;
height: var(--header-height);
box-sizing: border-box;
justify-content: space-between;
}
// This is the first entry in the header, it represents the "home"-link
#nextcloud {
padding: 5px 0;
padding-inline-start: 86px; // logo width + 2 * the inset (padding)
position: relative;
height: calc(100% - var(--default-grid-baseline));
box-sizing: border-box;
opacity: 1;
align-items: center;
display: flex;
flex-wrap: wrap;
overflow: hidden;
margin: 2px;
&:hover, &:active {
opacity: 1;
}
// the actual logo within the home-link entry
.logo {
display: inline-flex;
background-image: var(--image-logoheader, var(--image-logo, url('../img/logo/logo.svg')));
background-repeat: no-repeat;
background-size: contain;
background-position: center;
width: 62px;
position: absolute;
inset-inline-start: 12px;
top: 1px;
bottom: 1px;
// Invert if not customized and background is bright
filter: var(--image-logoheader-custom, var(--background-image-invert-if-bright));
}
}
// focus visible styles
// this adds a small line below all entries when visually focussed
#nextcloud:focus-visible,
.app-menu-entry a:focus-visible,
.header-menu button:first-of-type:focus-visible {
@ -32,141 +102,29 @@
}
}
.header-end {
// Add some spacing so the last entry looks ok
margin-inline-end: calc(3 * var(--default-grid-baseline));
a:not(.button):focus-visible::after, div[role=button]:focus-visible::after {
bottom: 4px;
}
#expand.menutoggle:focus-visible::after {
inset-inline-start: 40%;
}
}
}
/* HEADERS ------------------------------------------------------------------ */
#body-user #header,
#body-settings #header,
#body-public #header {
display: inline-flex;
position: absolute;
top: 0;
width: 100%;
z-index: 2000;
height: variables.$header-height;
box-sizing: border-box;
justify-content: space-between;
}
/* LOGO and APP NAME -------------------------------------------------------- */
#nextcloud {
padding: 5px 0;
padding-inline-start: 86px; // logo width + 2* pa
position: relative;
height: calc(100% - 4px);
box-sizing: border-box;
opacity: 1;
align-items: center;
display: flex;
flex-wrap: wrap;
overflow: hidden;
margin: 2px;
&:hover, &:active {
opacity: 1;
}
}
@mixin header-menu-height() {
min-height: calc(44px * 1.5); // show at least 1.5 entries
max-height: calc(100vh - #{variables.$header-height} - 8px);
}
/* Header menu */
#header {
.header-end > div > .menu {
background-color: var(--color-main-background);
filter: drop-shadow(0 1px 5px var(--color-box-shadow));
border-radius: var(--border-radius-large);
box-sizing: border-box;
z-index: 2000;
position: absolute;
max-width: 350px;
@include header-menu-height();
inset-inline-end: 8px; // relative to parent
top: variables.$header-height;
margin: 0;
overflow-y: auto;
&:not(.popovermenu) {
display: none;
}
/* Dropdown arrow */
&:after {
border: 10px solid transparent;
border-bottom-color: var(--color-main-background);
bottom: 100%;
content: ' ';
height: 0;
width: 0;
position: absolute;
pointer-events: none;
inset-inline-end: 10px;
}
& > div,
& > ul {
-webkit-overflow-scrolling: touch;
@include header-menu-height();
}
}
.logo {
display: inline-flex;
background-image: var(--image-logoheader, var(--image-logo, url('../img/logo/logo.svg')));
background-repeat: no-repeat;
background-size: contain;
background-position: center;
width: 62px;
position: absolute;
inset-inline-start: 12px;
top: 1px;
bottom: 1px;
// Invert if not customized and background is bright
filter: var(--image-logoheader-custom, var(--background-image-invert-if-bright));
}
.header-appname-container {
display: none;
padding-inline-end: 10px;
flex-shrink: 0;
}
#header-start, .header-start,
#header-end, .header-end {
// This is the first part of the header
// for the user template it contains the application icons (app menu)
// for public templates this contains e.g. share information
.header-start {
display: inline-flex;
align-items: center;
}
#header-start, .header-start {
flex: 1 0;
white-space: nowrap;
min-width: 0;
}
#header-end, .header-end {
// This is the last part of the header
// It contains the short cuts like unified search, contacts-, or account menu
.header-end {
display: inline-flex;
align-items: center;
justify-content: flex-end;
flex-shrink: 1;
}
// Add some spacing so the last entry looks ok
margin-inline-end: calc(3 * var(--default-grid-baseline));
/* Right header standard */
.header-end {
> .header-menu__trigger img {
filter: var(--background-image-invert-if-bright);
}
// legacy JQuery header menus
// TODO: we already migrated our own code and deprecated it - can be removed together with global jQuery
> div,
> form {
height: 100%;
@ -175,8 +133,8 @@
display: flex;
justify-content: center;
align-items: center;
width: variables.$header-height;
height: 44px;
width: var(--header-height);
height: var(--header-menu-item-height);
cursor: pointer;
opacity: 0.85;
padding: 0;
@ -190,86 +148,100 @@
outline: none;
}
}
> .menu {
background-color: var(--color-main-background);
filter: drop-shadow(0 1px 5px var(--color-box-shadow));
border-radius: var(--border-radius-large);
box-sizing: border-box;
z-index: 2000;
position: absolute;
max-width: 350px;
@include header-menu-height();
inset-inline-end: 8px; // relative to parent
top: var(--header-height);
margin: 0;
overflow-y: auto;
&:not(.popovermenu) {
display: none;
}
/* Dropdown arrow */
&:after {
border: 10px solid transparent;
border-bottom-color: var(--color-main-background);
bottom: 100%;
content: ' ';
height: 0;
width: 0;
position: absolute;
pointer-events: none;
inset-inline-end: 10px;
}
& > div,
& > ul {
-webkit-overflow-scrolling: touch;
@include header-menu-height();
}
}
.emptycontent {
h2 {
font-weight: normal;
font-size: 16px;
}
[class^='icon-'],
[class*='icon-'] {
background-size: 48px;
height: 48px;
width: 48px;
}
}
}
}
// Public layout related headers
// app related header container ONLY on public shares (layout.public.php)
.header-appname {
color: var(--color-background-plain-text);
font-size: 16px;
font-weight: bold;
margin: 0;
padding: 0;
padding-inline-end: 5px;
overflow: hidden;
text-overflow: ellipsis;
// Take full width to push the header-shared-by bellow (if any)
flex: 1 1 100%;
// container for the public template header information
.header-info {
display: flex;
flex-direction: column;
overflow: hidden;
.header-title {
overflow: hidden;
text-overflow: ellipsis;
}
.header-shared-by {
color: var(--color-background-plain-text);
position: relative;
font-weight: 300;
font-size: var(--font-size-small);
line-height: var(--font-size-small);
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
/* hover effect for app switcher label */
.header-appname-container .header-appname {
opacity: .75;
}
/* TODO: move into minimal css file for public shared template */
/* only used for public share pages now as we have the app icons when logged in */
.header-appname {
color: var(--color-background-plain-text);
font-size: 16px;
font-weight: bold;
margin: 0;
padding: 0;
padding-inline-end: 5px;
overflow: hidden;
text-overflow: ellipsis;
// Take full width to push the header-shared-by bellow (if any)
flex: 1 1 100%;
}
.header-info {
display: flex;
flex-direction: column;
overflow: hidden;
}
.header-title {
overflow: hidden;
text-overflow: ellipsis;
}
.header-shared-by {
color: var(--color-background-plain-text);
position: relative;
font-weight: 300;
font-size: 11px;
line-height: 11px;
overflow: hidden;
text-overflow: ellipsis;
}
/* Skip navigation links show only on keyboard focus */
#skip-actions {
position: absolute;
overflow: hidden;
z-index: 9999;
top: -999px;
inset-inline-start: 3px;
padding: 11px;
display: flex;
flex-wrap: wrap;
gap: 11px;
&:focus-within {
top: variables.$header-height;
}
}
/* Empty content messages in the header e.g. notifications, contacts menu, … */
header #emptycontent,
header .emptycontent {
h2 {
font-weight: normal;
font-size: 16px;
}
[class^='icon-'],
[class*='icon-'] {
background-size: 48px;
height: 48px;
width: 48px;
}
}
@media (display-mode: standalone) or (display-mode: minimal-ui) {
#header {
#header:not(.header-guest) {
display: none !important;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -44,7 +44,7 @@ p($theme->getTitle());
<div class="v-align">
<?php if ($_['bodyid'] === 'body-login'): ?>
<header>
<div id="header">
<div id="header" class="header-guest">
<div class="logo"></div>
</div>
</header>