diff --git a/assets/less/classes/header.less b/assets/less/classes/header.less index e167c24a..f2f3f4d4 100644 --- a/assets/less/classes/header.less +++ b/assets/less/classes/header.less @@ -2,16 +2,12 @@ --header-image-px: 60px; flex: 0 0 auto; transition: height .2s; - position: absolute; + position: fixed; top: 0; left: 0; right: 0; z-index: 500; - &--new { - position: fixed; - } - &--floating { --header-height: var(--header-height-floating); --header-image-px: 40px; @@ -26,8 +22,13 @@ background: var(--background-pattern); background-color: var(--header-accent-colour); background-blend-mode: multiply; - mask-image: linear-gradient(180deg, var(--background-colour) 0, transparent 100%); - -webkit-mask-image: linear-gradient(180deg, var(--background-colour) 0, transparent 100%); + transition: box-shadow .2s, mask-image .2s, -webkit-mask-image .2s; + } + + &:not(&--floating) &__background { + --header-background-mask-image: linear-gradient(180deg, var(--background-colour) 0, transparent 100%); + mask-image: var(--header-background-mask-image); + -webkit-mask-image: var(--header-background-mask-image); // fuck chrome } &__wrapper { diff --git a/assets/less/classes/headerv1.less b/assets/less/classes/headerv1.less new file mode 100644 index 00000000..aa73c6b8 --- /dev/null +++ b/assets/less/classes/headerv1.less @@ -0,0 +1,291 @@ +.headerv1 { + --header-image-px: 60px; + flex: 0 0 auto; + transition: height .2s; + position: absolute; + top: 0; + left: 0; + right: 0; + z-index: 500; + + &__background { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: var(--background-pattern); + background-color: var(--header-accent-colour); + background-blend-mode: multiply; + mask-image: linear-gradient(180deg, var(--background-colour) 0, transparent 100%); + -webkit-mask-image: linear-gradient(180deg, var(--background-colour) 0, transparent 100%); + } + + &__wrapper { + margin: 0 auto; + display: flex; + align-items: center; + padding: 4px; + max-width: var(--site-max-width); + height: var(--header-height); + transition: height .2s; + + @media (max-width: @site-mobile-width) { + flex-direction: column; + height: 100%; + } + } + + @media (max-width: @site-mobile-width) { + &__icons { + display: flex; + justify-content: space-between; + width: 100%; + } + } + + &__icon { + display: none; + cursor: pointer; + width: 40px; + height: 40px; + + &--menu { + font-size: 3em; + justify-content: center; + align-items: center; + } + + @media (max-width: @site-mobile-width) { + display: inline-flex; + } + } + + &__logo { + flex: 0 0 auto; + color: inherit; + text-decoration: none; + cursor: pointer; + display: block; + background: url('/images/logos/imouto-default.png') no-repeat center / cover; + width: var(--header-image-px); + height: var(--header-image-px); + font-size: 0; + transition: width .2s, height .2s; + + &--manage { + background-image: url('/images/logos/imouto-broom.png'); + } + + @media (max-width: @site-mobile-width) { + width: 40px; + height: 40px; + } + } + + &__menu { + flex: 1 1 auto; + margin: 0 6px; + list-style: none; + display: flex; + + &-toggle { + display: none; + } + + @media (max-width: @site-mobile-width) { + display: none; + font-size: 1.6em; + line-height: 1.5em; + margin-top: 4px; + width: 100%; + background: var(--header-accent-colour); + + &-toggle:checked ~ .headerv1__menu { + display: block; + } + + &__item:not(:last-child) { + border-bottom: 1px solid var(--header-accent-colour); + } + + &__link { + width: 100%; + display: block; + padding: 4px 8px; + color: inherit; + text-decoration: none; + } + } + + @media (min-width: @site-mobile-width) { + &__item { + text-align: center; + transition: background-color .2s, border-color .2s; + margin-right: 1px; + border: 1px solid transparent; + border-radius: 2px; + + &:hover, + &:active, + &:focus, + &:focus-within { + background-color: var(--background-colour-translucent-9); + border-color: var(--header-accent-colour); + + .headerv1__submenu { + transform: scaleY(1); + } + } + } + + &__link { + font-size: 1.2em; + color: inherit; + text-decoration: none; + display: block; + padding: 6px 4px; + min-width: 100px; + cursor: pointer; + } + } + } + + &__submenu { + list-style: none; + display: block; + + @media (max-width: @site-mobile-width) { + &__link { + padding: 2px 16px; + display: block; + width: 100%; + color: inherit; + text-decoration: none; + } + } + + @media (min-width: @site-mobile-width) { + position: absolute; // floating + left: -1px; + transform: scaleY(0); + transform-origin: center top 0; + background: var(--header-accent-colour); + overflow: hidden; + z-index: 100; + text-align: left; + box-shadow: 0 2px 2px var(--header-accent-colour); + transition: transform .2s; + padding: 1px; + border-radius: 2px; + + &:hover, + &:focus { + transform: scaleY(1); + } + + &__link { + color: inherit; + text-decoration: none; + display: block; + padding: 2px 6px; + min-width: 100px; + background-color: var(--background-colour-translucent-9); + transition: background-color .2s; + + &:hover, + &:focus { + background-color: var(--background-colour-translucent-7); + } + + &:active { + background-color: var(--background-colour-translucent-8); + } + } + } + } + + &__user { + flex: 0 0 auto; + display: flex; + order: 3; + align-items: center; + + @media (max-width: @site-mobile-width) { + justify-content: flex-end; + } + + &-toggle { + display: none; + } + + @media (max-width: @site-mobile-width) { + display: none; + width: 100%; + margin-top: 4px; + + &-toggle:checked ~ .headerv1__user { + display: flex; + } + } + + &__avatar { + width: var(--header-image-px); + height: var(--header-image-px); + margin-left: 5px; + transition: box-shadow .2s, width .2s, height .2s; + box-shadow: 0 0 4px #111; + + &:hover, + &:active, + &:focus { + box-shadow: 0 0 4px var(--header-accent-colour); + } + + @media (max-width: @site-mobile-width) { + display: none; + } + } + + &__button { + margin: 2px; + color: inherit; + text-decoration: none; + font-size: 1.5em; + line-height: 32px; + width: 32px; + height: 32px; + transition: background-color .2s; + border-radius: 4px; + text-align: center; + + &:hover, + &:focus { + background-color: fade(#fff, 20%); + } + + &:active { + background-color: fade(#fff, 10%); + } + + @media (max-width: @site-mobile-width) { + width: 40px; + height: 40px; + line-height: 40px; + font-size: 2em; + } + + &__count { + position: absolute; + bottom: 1px; + right: 1px; + font-size: 10px; + background-color: var(--header-accent-colour); + opacity: .9; + border-radius: 4px; + line-height: 12px; + padding: 2px 4px; + } + } + } +} diff --git a/assets/less/main.less b/assets/less/main.less index f76c7e2e..28cb4750 100644 --- a/assets/less/main.less +++ b/assets/less/main.less @@ -6,8 +6,9 @@ :root { --site-max-width: 1200px; - --header-height: 70px; + --header-height-static: 70px; --header-height-floating: 50px; + --header-height: var(--header-height-static); --background-image: initial; @@ -120,6 +121,7 @@ html { // Specific styles @import "classes/footer"; @import "classes/header"; +@import "classes/headerv1"; @import "classes/index"; @import "classes/permissions"; @import "classes/auth"; diff --git a/assets/typescript/misuzu.ts b/assets/typescript/misuzu.ts index 6043ca6e..1c888ef8 100644 --- a/assets/typescript/misuzu.ts +++ b/assets/typescript/misuzu.ts @@ -47,18 +47,22 @@ window.addEventListener('load', () => { const siteHeader: HTMLDivElement = document.querySelector('.js-header'); if (siteHeader) { - const siteHeaderFloating: string = 'header--floating'; - - window.addEventListener('scroll', () => { - if (scrollY > 0 && !siteHeader.classList.contains(siteHeaderFloating)) { - siteHeader.classList.add(siteHeaderFloating); - } else if (scrollY <= 1 && siteHeader.classList.contains(siteHeaderFloating)) { - siteHeader.classList.remove(siteHeaderFloating); - } - }); + window.addEventListener('scroll', () => updateHeader(siteHeader)); + updateHeader(siteHeader); // initial call to bring it in the right state } }); +function updateHeader(element: HTMLDivElement): void +{ + const floating: string = 'header--floating'; + + if (scrollY > 10 && !element.classList.contains(floating)) { + element.classList.add(floating); + } else if (scrollY < 10 && element.classList.contains(floating)) { + element.classList.remove(floating); + } +} + function loginFormUpdateAvatar(avatarElement: HTMLElement, usernameElement: HTMLInputElement, force: boolean = false): void { if (!force) { if (loginFormAvatarTimeout) diff --git a/templates/_layout/header-old.twig b/templates/_layout/header-old.twig index 9cceb620..2d0aff79 100644 --- a/templates/_layout/header-old.twig +++ b/templates/_layout/header-old.twig @@ -1,87 +1,87 @@ {% from '_layout/input.twig' import input_checkbox_raw %} {% set in_manage = manage_menu is defined %} -