mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-27 17:10:19 +00:00
Refactor chevron across components + separate watchstar
Consolidates the CSS responsible for styling chevrons into one implementation. This removes the need for custom padding and background positioning for the following components: - "more" menu - user menu - watchstar - language button - languge button in sticky header Instead of absolutely positioning the chevron on these components, the parent label element is set to `display: inline-flex` so that the chevron is vertically aligned and given enough space by default. The watchstar, although not a chevron, is also given the `display: inline-flex` treatment so that it can be aligned with other elements in the toolbar. This new implementation requires splitting the watchstar component into legacy and modern due to a quirk in Firefox that causes a bug with the watchstar in legacy Vector. NOTE: This change causes visual changes due to the difference in centering the chevrons via flexbox vs percentage positions. Bug: T308344, T310838 Change-Id: Ie9e0fce1366cd25a5899fee49770de4a09424fe2
This commit is contained in:
parent
e83ca244af
commit
3c0559a71d
|
@ -15,7 +15,6 @@
|
|||
@import './components/Indicators.less';
|
||||
@import './components/SiteNotice.less';
|
||||
@import './components/Menu.less';
|
||||
@import './components/TabWatchstarLink.less';
|
||||
@import './components/MenuDropdown.less';
|
||||
@import './components/MenuPortal.less';
|
||||
@import './components/SearchBox.less';
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
@import '../variables.less';
|
||||
@import 'mediawiki.mixins.less';
|
||||
|
||||
/* Variants and Actions */
|
||||
/**
|
||||
* Targets:
|
||||
* - language variants, Actions menus
|
||||
* - more menu, user menu
|
||||
* - ULS button in sticky header
|
||||
*/
|
||||
.emptyPortlet .vector-menu-heading,
|
||||
.vector-menu-dropdown .vector-menu-heading,
|
||||
.mw-interlanguage-selector {
|
||||
display: flex;
|
||||
color: @color-base--subtle;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
background: url( images/arrow-down.svg ) 100% 50% no-repeat;
|
||||
width: unit( 16 / @font-size-tabs / @font-size-browser, em );
|
||||
height: unit( 16 / @font-size-tabs / @font-size-browser, em );
|
||||
// Modify the color of the image from the default #202122 to approx. #404244 to match the text.
|
||||
opacity: 0.84;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @color-base;
|
||||
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vector-menu-dropdown {
|
||||
direction: ltr;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
.vector-menu-heading {
|
||||
color: @color-base--subtle;
|
||||
position: relative;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
background-image: url( images/arrow-down.svg );
|
||||
background-position: 100% 50%;
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
top: unit( 10 / @font-size-tabs / @font-size-browser, em );
|
||||
right: 8px;
|
||||
bottom: 0;
|
||||
width: unit( 16 / @font-size-tabs / @font-size-browser, em );
|
||||
// Modify the color of the image from the default #202122 to approx. #404244 to match the text.
|
||||
opacity: 0.84;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
color: @color-base;
|
||||
|
||||
&:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The menu itself.
|
||||
.vector-menu-content {
|
||||
background-color: @background-color-base;
|
||||
|
@ -46,7 +46,7 @@
|
|||
// Match the width of the dropdown "heading" (the tab)
|
||||
min-width: 100%;
|
||||
position: absolute;
|
||||
top: 2.5em;
|
||||
top: 100%;
|
||||
left: -@border-width-base;
|
||||
margin: 0;
|
||||
border: @border-width-base @border-style-base @border-color-base;
|
||||
|
@ -117,9 +117,7 @@
|
|||
.vector-menu-dropdown-noicon {
|
||||
.vector-menu-heading {
|
||||
// `padding-top` needs to scale with font-size.
|
||||
padding-top: 1.25em;
|
||||
padding-left: 8px;
|
||||
padding-right: unit( 24 / @font-size-tabs / @font-size-browser, em );
|
||||
padding: 1.25em 8px 6px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
line-height: 1.125em;
|
||||
|
||||
li {
|
||||
span:not( .mw-ui-icon ) {
|
||||
a:not( .mw-ui-icon ) {
|
||||
font-size: @font-size-tabs;
|
||||
}
|
||||
|
||||
|
@ -51,12 +51,6 @@
|
|||
#mw-head .vector-menu-dropdown .vector-menu-heading {
|
||||
// Tab separator: Outer end (right in LTR) border of "Actions" menu.
|
||||
background-position: right bottom;
|
||||
float: left;
|
||||
height: unit( 40 / @font-size-tabs / @font-size-browser, em );
|
||||
margin: 0 -@border-width-base 0 0;
|
||||
// `padding-right` >= `1px` effectively moves the "background border" outside of the element to
|
||||
// act like a real border. It is necessary for `.vector-menu-dropdown .vector-menu-content-list` dropdown to align well.
|
||||
// 0.5em equals `8px` at computed `font-size` of `14px` as visually harmonically with
|
||||
// `padding-left` in `.vector-menu-dropdown .vector-menu-heading a`
|
||||
padding-right: unit( 24 / @font-size-tabs / @font-size-browser, em );
|
||||
float: left;
|
||||
}
|
||||
|
|
|
@ -95,3 +95,26 @@
|
|||
// Contain gradient to 1px × 100% size and draw from top to bottom-left or -right corner.
|
||||
background-size: @border-width-base 100%;
|
||||
}
|
||||
|
||||
#mw-head .vector-menu-dropdown .vector-menu-heading {
|
||||
// Tab separator: Outer end (right in LTR) border of "Actions" menu.
|
||||
background-position: right bottom;
|
||||
}
|
||||
|
||||
.vector-menu-dropdown-noicon {
|
||||
.vector-menu-heading {
|
||||
// `padding-top` needs to scale with font-size.
|
||||
padding-top: 1.25em;
|
||||
padding-left: 8px;
|
||||
padding-right: 8px;
|
||||
font-size: @font-size-tabs;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
// Add focus state to legacy menu dropdown buttons (i.e. p-variants, p-cactions)
|
||||
.vector-menu-checkbox:focus + .vector-menu-heading {
|
||||
// Simulate browser focus ring
|
||||
outline: dotted 1px; // Firefox style
|
||||
outline: auto -webkit-focus-ring-color; // Webkit style
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@import '../variables.less';
|
||||
@import '../../common/variables.less';
|
||||
@import 'mediawiki.mixins.less';
|
||||
@import 'mediawiki.mixins.rotation.less';
|
||||
|
||||
|
@ -33,30 +33,30 @@
|
|||
}
|
||||
|
||||
#ca-unwatch.icon a:before {
|
||||
background-image: url( images/unwatch-icon.svg );
|
||||
background-image: url( ../common/images/unwatch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-unwatch.mw-watchlink-temp.icon a:before {
|
||||
background-image: url( images/unwatch-temp-icon.svg );
|
||||
background-image: url( ../common/images/unwatch-temp-icon.svg );
|
||||
}
|
||||
|
||||
#ca-watch.icon a:before {
|
||||
background-image: url( images/watch-icon.svg );
|
||||
background-image: url( ../common/images/watch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-unwatch.icon a:hover:before,
|
||||
#ca-unwatch.icon a:focus:before {
|
||||
background-image: url( images/unwatch-icon-hl.svg );
|
||||
background-image: url( ../common/images/unwatch-icon-hl.svg );
|
||||
}
|
||||
|
||||
#ca-unwatch.mw-watchlink-temp.icon a:hover:before,
|
||||
#ca-unwatch.mw-watchlink-temp.icon a:focus:before {
|
||||
background-image: url( images/unwatch-temp-icon-hl.svg );
|
||||
background-image: url( ../common/images/unwatch-temp-icon-hl.svg );
|
||||
}
|
||||
|
||||
#ca-watch.icon a:hover:before,
|
||||
#ca-watch.icon a:focus:before {
|
||||
background-image: url( images/watch-icon-hl.svg );
|
||||
background-image: url( ../common/images/watch-icon-hl.svg );
|
||||
}
|
||||
|
||||
// Loading watchstar link class.
|
|
@ -12,6 +12,7 @@
|
|||
@import './components/MenuTabs.less';
|
||||
@import './components/SearchBox.less';
|
||||
@import './components/Sidebar.less';
|
||||
@import './components/TabWatchstarLink.less';
|
||||
@import './components/UserLinks.less';
|
||||
|
||||
// Overrides
|
||||
|
|
|
@ -18,11 +18,6 @@
|
|||
}
|
||||
|
||||
.vector-menu-heading {
|
||||
// stylelint-disable-next-line plugin/no-unsupported-browser-features
|
||||
font-size: initial;
|
||||
// reset padding styles in MenuDropdown.less with right padding for arrow.
|
||||
padding-right: 30px;
|
||||
padding-left: 8px;
|
||||
// Prevent select of span text "X languages"
|
||||
user-select: none;
|
||||
// Remove opacity on language button (it applies to more menu because of label color).
|
||||
|
@ -33,10 +28,6 @@
|
|||
font-size: @font-size-base;
|
||||
}
|
||||
|
||||
&:after {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
// T291286: Temporarily use progressive ULS style
|
||||
&.mw-ui-progressive.mw-ui-quiet {
|
||||
.mw-ui-icon:before {
|
||||
|
@ -98,25 +89,3 @@
|
|||
#p-lang-btn.mw-portlet-empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#p-lang-btn-sticky-header {
|
||||
@button-padding: 12px;
|
||||
@arrow-width: 18px;
|
||||
position: relative;
|
||||
padding-right: ~'calc( @{button-padding} + @{arrow-width} )';
|
||||
white-space: nowrap;
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
background-image: url( ../common/images/arrow-down.svg );
|
||||
background-position: 100% 50%;
|
||||
background-repeat: no-repeat;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: @button-padding;
|
||||
bottom: 0;
|
||||
width: @arrow-width;
|
||||
// Modify the color of the image from the default #202122 to approx. #404244 to match the text.
|
||||
opacity: 0.84;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,56 +10,52 @@
|
|||
float: left;
|
||||
padding-left: @border-width-base;
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
white-space: nowrap;
|
||||
margin: 0;
|
||||
|
||||
// Make first and last elements flush with edge of header.
|
||||
&:first-child {
|
||||
margin-left: -8px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* focus and hover have outlines. Text underline interferes with bottom border */
|
||||
li a:focus,
|
||||
li a:hover {
|
||||
.mw-list-item a:focus,
|
||||
.mw-list-item a:hover {
|
||||
text-decoration: none;
|
||||
border-bottom: @border-width-base @border-style-base;
|
||||
}
|
||||
|
||||
.new a,
|
||||
.new a:visited {
|
||||
.mw-list-item.new a,
|
||||
.mw-list-item.new a:visited {
|
||||
color: @color-link-new;
|
||||
}
|
||||
|
||||
.selected a,
|
||||
.selected a:visited {
|
||||
.mw-list-item.selected a,
|
||||
.mw-list-item.selected a:visited {
|
||||
color: @color-link-selected;
|
||||
border-bottom: @border-width-base @border-style-base;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tab link appearance, applies to
|
||||
* - <a> inside vector-menu-tabs (e.g. read, edit, view, history)
|
||||
* - vector-menu-dropdown headings (e.g. more menu, language variants, gadgets)
|
||||
*/
|
||||
.vector-menu-tabs li a,
|
||||
.vector-article-toolbar .vector-menu-heading {
|
||||
display: block;
|
||||
position: relative;
|
||||
// Top bottom padding to increase clickable area.
|
||||
padding-top: 18px;
|
||||
padding-bottom: 7px;
|
||||
// left & right margin separate bottom border between words,
|
||||
// bottom margin makes link border overlap toolbar border.
|
||||
margin: 0 8px -1px 8px;
|
||||
cursor: pointer;
|
||||
border-bottom: @border-width-base @border-style-base transparent;
|
||||
* Tab list item appearance. Applies to both <li>'s inside .vector-menu-tabs
|
||||
* and dropdown menus inside the article toolbar
|
||||
*/
|
||||
.vector-menu-tabs .mw-list-item,
|
||||
.mw-article-toolbar-container .vector-menu-dropdown {
|
||||
float: left;
|
||||
white-space: nowrap;
|
||||
margin: 0 @padding-horizontal-tabs;
|
||||
|
||||
// target links inside of .vector-tab-menu
|
||||
// and dropdown menu headings inside the article toolbar.
|
||||
// NOTE: Consider adding a single selector to define both items,
|
||||
// since they both appear beside each other in the article toolbar.
|
||||
& > a,
|
||||
.vector-menu-heading {
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
// Top & bottom padding to increase clickable area.
|
||||
padding: 18px 0 7px 0;
|
||||
// bottom margin to overlap border with toolbar border.
|
||||
margin-bottom: -1px;
|
||||
cursor: pointer;
|
||||
border-bottom: @border-width-base @border-style-base transparent;
|
||||
// max-height & box-sizing to make link, watchstar & dropdown height consistent.
|
||||
// NOTE: Was 40px instead of 41, but changed to avoid visual regressions.
|
||||
max-height: unit( 41 / @font-size-tabs / @font-size-browser, em );
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
@import '../../common/variables.less';
|
||||
@import 'mediawiki.mixins.less';
|
||||
@import 'mediawiki.mixins.rotation.less';
|
||||
|
||||
/* Watch/Unwatch Icon Styling */
|
||||
/* Only use icon if the menu item is not collapsed into the "More" dropdown
|
||||
* (in which case it is inside `.vector-menu-dropdown` instead of `.vector-menu-tabs`). */
|
||||
.vector-menu-tabs {
|
||||
@size-watchlink-icon: unit( 16 / @font-size-tabs / @font-size-browser, em );
|
||||
|
||||
.mw-watchlink.icon a {
|
||||
overflow: hidden;
|
||||
text-indent: -99999px;
|
||||
color: transparent;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: @size-watchlink-icon;
|
||||
height: @size-watchlink-icon;
|
||||
}
|
||||
}
|
||||
|
||||
#ca-unwatch.icon a:before {
|
||||
background-image: url( ../common/images/unwatch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-unwatch.mw-watchlink-temp.icon a:before {
|
||||
background-image: url( ../common/images/unwatch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-watch.icon a:before {
|
||||
background-image: url( ../common/images/unwatch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-unwatch.icon a:hover:before,
|
||||
#ca-unwatch.icon a:focus:before {
|
||||
background-image: url( ../common/images/unwatch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-unwatch.mw-watchlink-temp.icon a:hover:before,
|
||||
#ca-unwatch.mw-watchlink-temp.icon a:focus:before {
|
||||
background-image: url( ../common/images/unwatch-icon.svg );
|
||||
}
|
||||
|
||||
#ca-watch.icon a:hover:before,
|
||||
#ca-watch.icon a:focus:before {
|
||||
background-image: url( ../common/images/watch-icon-hl.svg );
|
||||
}
|
||||
|
||||
// Loading watchstar link class.
|
||||
#ca-unwatch.icon .loading:before,
|
||||
#ca-watch.icon .loading:before {
|
||||
.rotation( 700ms );
|
||||
/* Suppress the hilarious rotating focus outline on Firefox */
|
||||
outline: 0;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
}
|
|
@ -178,20 +178,13 @@
|
|||
}
|
||||
|
||||
.vector-user-menu-logged-in .vector-menu-heading {
|
||||
// FIXME: Ideally this variable should be accessible from mediawiki.skin.variables
|
||||
// Remove it when we can.
|
||||
@icon-padding-md: unit( 12 / @font-size-browser, em );
|
||||
@icon-arrow-size: unit( 12px / @font-size-browser, em );
|
||||
padding-right: @icon-padding-md + @icon-arrow-size;
|
||||
// override user menu (.mw-ui-icon) fixed width,
|
||||
// so chevron beside icon is visible.
|
||||
width: auto;
|
||||
|
||||
// and override again to ensure the user icon is 20px wide.
|
||||
&:before {
|
||||
color: #54595d;
|
||||
}
|
||||
|
||||
&:after {
|
||||
background-position: 100% 0%;
|
||||
top: @icon-padding-md + ( @icon-arrow-size / 2 );
|
||||
right: @icon-arrow-size;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,6 @@ body {
|
|||
/* Main column */
|
||||
.mw-body,
|
||||
#mw-data-after-content,
|
||||
#left-navigation,
|
||||
.mw-footer {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
@ -156,11 +155,12 @@ body {
|
|||
|
||||
#left-navigation {
|
||||
float: left;
|
||||
margin-left: -@padding-horizontal-tabs;
|
||||
}
|
||||
|
||||
#right-navigation {
|
||||
float: right;
|
||||
|
||||
margin-right: -@padding-horizontal-tabs;
|
||||
// Any dropdowns inside the right navigation in modern Vector (e.g. "more" menu).
|
||||
// should be right-aligned to prevent horizontal scrolling.
|
||||
.vector-menu-content {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
@import './components/Header.less';
|
||||
@import './components/MenuTabs.less';
|
||||
@import './components/StickyHeader.less';
|
||||
@import './components/TabWatchstarLink.less';
|
||||
@import './components/TableOfContents.less';
|
||||
@import './components/TableOfContentsCollapsed.less';
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import mustache from 'mustache';
|
|||
import { menuTemplate as vectorTabsTemplate } from './Menu.stories.data';
|
||||
import { namespaceTabsData, pageActionsData } from './MenuTabs.stories.data';
|
||||
import '../resources/skins.vector.styles/components/MenuTabs.less';
|
||||
import '../resources/skins.vector.styles/TabWatchstarLink.less';
|
||||
import '../resources/skins.vector.styles/components/TabWatchstarLink.less';
|
||||
|
||||
export default {
|
||||
title: 'MenuTabs'
|
||||
|
|
Loading…
Reference in a new issue