mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-30 02:15:49 +00:00
2adab440a5
Replacing Less mixin calls of `.transition()`, deprecated since MW 1.37, with CSS property, but constituent properties. This has been an outcome of recent discussions around design tokens, which will be simpler to define, more modular, and better scoped. See T304443 for further information. Also clarifying, aligning comments. Bug: T308351 Change-Id: Iab9d04c9a9f31f3842d076ce8fd8bf6e3534fc89
400 lines
13 KiB
Plaintext
400 lines
13 KiB
Plaintext
/**
|
|
* Vector modern layout styles for screen
|
|
*
|
|
* Layout rules divide the page into sections and how VectorComponents should be arranged in the skin.
|
|
* The rules here should only define the layout, not color or typography.
|
|
*/
|
|
|
|
@import '../../common/variables.less';
|
|
@import 'mediawiki.mixins.less';
|
|
|
|
@selector-workspace-container-sidebar-open: ~'.mw-checkbox-hack-checkbox:checked ~ .mw-workspace-container';
|
|
@selector-workspace-container-sidebar-closed: ~'.mw-checkbox-hack-checkbox:not( :checked ) ~ .mw-workspace-container';
|
|
|
|
// Sidebar
|
|
@width-grid-column-one: 11em;
|
|
|
|
// Adjust the left position of the sidebar to align it with the sidebar menu button,
|
|
// in the header, while ensuring the background gradient still extends to the edge of the screen.
|
|
// note: the 1px comes from the transparent border of the sidebar button.
|
|
@padding-left-sidebar:
|
|
@margin-horizontal-sidebar-button-icon +
|
|
unit( @border-width-base / @font-size-browser, em );
|
|
|
|
// Layout containers
|
|
|
|
// Page container
|
|
|
|
@min-width-page-container--padded: @max-width-page-container + ( 2 * @padding-horizontal-page-container ); // 106.875em
|
|
|
|
// Content containers
|
|
|
|
@max-width-workspace-container: unit( 1514px / @font-size-browser, em ); // 99.75em @ 16
|
|
@max-width-content-container: unit( 960px / @font-size-browser, em ); // 60em @ 16
|
|
|
|
// Note this uses variables defined in mediawiki.skin.variables so that VisualEditor can read them
|
|
// see T259331.
|
|
@padding-content: @padding-top-content @padding-horizontal-content 1.5em;
|
|
// We want ~60px of space between the end of the sidebar and the start of the
|
|
// content container for aesthetic reasons. The sidebar is already displaced
|
|
// -30px so we simply add 30px of space to the width of the sidebar.
|
|
@margin-start-content: @width-grid-column-one + unit( 8px / @font-size-browser, em ); // 11.5em @ 16
|
|
|
|
// Tabs
|
|
|
|
@height-tabs: 2.5em; // Keep in sync with .vector-menu-tabs height.
|
|
|
|
// Breakpoints
|
|
|
|
// This determines the maximum width breakpoint at which
|
|
// the content will have a fixed start margin applied to it when the sidebar
|
|
// is open. The content can shift its position when the sidebar is open/closed
|
|
// at or below this breakpoint and will maintain its position above this breakpoint.
|
|
@max-width-margin-start-content:
|
|
(2 * @margin-start-content ) +
|
|
( 2 * @padding-horizontal-page-container ) +
|
|
@max-width-content-container;
|
|
// 23em + 3.75em + 60em = 86.75em @ 16
|
|
|
|
// Defines the minimum viewport width, at which point the layout will not get any
|
|
// smaller and will start horizontal scrolling instead.
|
|
@min-width-supported:
|
|
unit( 500px / @font-size-browser, em ) -
|
|
( 2 * @padding-horizontal-page-container-wide );
|
|
// 31.25em - 3.75em = 27.5em @ 16
|
|
@border-color-sidebar: @background-color-secondary--modern;
|
|
@background-color-secondary--modern: #f8f9fa;
|
|
@background-color-page-container: @background-color-base;
|
|
|
|
body {
|
|
background-color: @background-color-secondary--modern;
|
|
color: @color-base;
|
|
// Vertical scrollbar always visible.
|
|
overflow-y: scroll;
|
|
}
|
|
|
|
.mw-body,
|
|
.parsoid-body {
|
|
direction: ltr;
|
|
padding: @padding-content;
|
|
}
|
|
|
|
.mw-body {
|
|
border-top: @border-width-base @border-style-base transparent;
|
|
/* Merge the border with tabs' one (in their background image) */
|
|
margin-top: -@border-width-base;
|
|
padding: @padding-content;
|
|
|
|
.firstHeading {
|
|
/* Change the default from mediawiki.skinning CSS to let indicators float into heading area */
|
|
overflow: visible;
|
|
}
|
|
}
|
|
|
|
.mw-header {
|
|
// allow z-index to apply so search results overlay article
|
|
position: relative;
|
|
z-index: @z-index-header;
|
|
}
|
|
|
|
/* Main column */
|
|
.mw-body,
|
|
#mw-data-after-content,
|
|
#left-navigation,
|
|
.mw-footer {
|
|
margin-left: 0;
|
|
}
|
|
|
|
/* Content */
|
|
.mw-indicators {
|
|
z-index: @z-index-indicators;
|
|
}
|
|
|
|
.mw-body-header {
|
|
.mixin-clearfix();
|
|
}
|
|
|
|
.mw-body .mw-portlet-lang {
|
|
float: right;
|
|
}
|
|
|
|
.vector-body {
|
|
position: relative;
|
|
z-index: @z-index-base;
|
|
}
|
|
|
|
// Prevents margin collapsing on first element (typically a <p>) of content.
|
|
// Custom because .mixin-clearfix() automatically appends :after to the selector
|
|
// and doesn't prevent margin collapsing.
|
|
.vector-body:before {
|
|
content: '';
|
|
display: table;
|
|
}
|
|
|
|
/* Navigation Containers */
|
|
.mw-article-toolbar-container {
|
|
// Clear the floats on #left-navigation and #right-navigation.
|
|
.mixin-clearfix();
|
|
// We want to keep the max-width of the article-toolbar-container the
|
|
// same max-width as the article page's content container in order to
|
|
// prevent it from moving when going from an article page to a
|
|
// history/special page.
|
|
max-width: @max-width-content-container;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
|
|
.skin-vector-disable-max-width & {
|
|
max-width: none;
|
|
}
|
|
}
|
|
|
|
#left-navigation {
|
|
float: left;
|
|
}
|
|
|
|
#right-navigation {
|
|
float: right;
|
|
|
|
// Any dropdowns inside the right navigation in modern Vector (e.g. "more" menu).
|
|
// should be right-aligned to prevent horizontal scrolling.
|
|
.vector-menu-content {
|
|
left: auto;
|
|
right: -@border-width-base;
|
|
}
|
|
}
|
|
|
|
#mw-panel {
|
|
position: absolute;
|
|
top: 0;
|
|
// Sidebar is displaced from the workspace container so that the
|
|
// sidebar is flush with the edge of the screen at small widths.
|
|
left: -@padding-horizontal-page-container;
|
|
z-index: @z-index-sidebar;
|
|
|
|
@media ( min-width: @width-breakpoint-desktop-wide ) {
|
|
left: -@padding-horizontal-page-container-wide;
|
|
}
|
|
}
|
|
|
|
// Update positioning when TOC is enabled
|
|
.vector-toc-enabled #mw-panel {
|
|
position: static;
|
|
float: left;
|
|
}
|
|
|
|
.mw-table-of-contents-container {
|
|
position: sticky;
|
|
float: left;
|
|
clear: both;
|
|
// Defaults to -2em to account for the TOC's top margin
|
|
// ensuring the TOC is 1.5em (24px) from the top of the viewport
|
|
// unless .mw-sticky-header-element overrides it.
|
|
top: calc( 1.5em - @top-margin-sidebar-toc_title_inline );
|
|
}
|
|
|
|
.parsoid-body {
|
|
padding: @padding-content;
|
|
}
|
|
|
|
#p-namespaces {
|
|
background-image: none;
|
|
padding-left: 0;
|
|
}
|
|
|
|
.mw-footer {
|
|
border-top: @border-base;
|
|
padding: 0.75em;
|
|
}
|
|
|
|
// Container logic.
|
|
.mw-page-container {
|
|
// Setting position and z-index is important as it allows overlays appended to the body tag
|
|
// to position themselves over the Vector interface. This forms another stacking context for
|
|
// elements placed inside this element
|
|
position: relative;
|
|
z-index: 0;
|
|
max-width: @max-width-page-container;
|
|
// Fill the viewport even if the content height is small. This also helps
|
|
// mitigate a long sidebar overflowing the page container (T257518).
|
|
min-height: 100%;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
// Use non-zero padding to disable margin collapse.
|
|
// Be careful not to use overflow-y: scroll here (see T270146 and T271868)
|
|
padding: 0.05px ( @padding-horizontal-page-container / 2 );
|
|
background-color: @background-color-page-container;
|
|
// Set a min-width to make explicit we do not support anything below this threshold.
|
|
// For devices too small, they should be more useable with horizontal scrolling.
|
|
// e.g. Portrait on an iPad
|
|
min-width: @min-width-supported;
|
|
|
|
@media ( min-width: @width-breakpoint-desktop ) {
|
|
padding-left: @padding-horizontal-page-container;
|
|
padding-right: @padding-horizontal-page-container;
|
|
}
|
|
|
|
@media ( min-width: @width-breakpoint-desktop-wide ) {
|
|
padding-left: @padding-horizontal-page-container-wide;
|
|
padding-right: @padding-horizontal-page-container-wide;
|
|
}
|
|
}
|
|
|
|
.skin--responsive .mw-page-container {
|
|
min-width: auto;
|
|
}
|
|
|
|
// Used as a container for absolutely positioned elements.
|
|
.mw-page-container-inner {
|
|
position: relative;
|
|
}
|
|
|
|
.mw-workspace-container {
|
|
max-width: @max-width-workspace-container;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
// The sidebar is absolutely positioned relative to the
|
|
// mw-workspace-container.
|
|
position: relative;
|
|
|
|
&.mw-footer-container {
|
|
// T264679: There are elements (e.g. discussion tool popovers) in the main
|
|
// content container that we want to appear on top of the footer. We set the
|
|
// footer container to have static positioning instead of relative
|
|
// positioning (applied by .mw-workspace-container) to enable this.
|
|
position: static;
|
|
}
|
|
}
|
|
|
|
.mw-content-container {
|
|
display: flow-root;
|
|
max-width: @max-width-content-container;
|
|
margin-left: auto;
|
|
margin-right: auto;
|
|
|
|
// For container logic specific to special pages and history pages.
|
|
.skin-vector-disable-max-width & {
|
|
// Allow the max-width of content on history/special pages to be wider than
|
|
// the max-width of content on article pages.
|
|
// Note, we don't disable the max-width on .mw-article-toolbar-container intentionally
|
|
// to support easier navigation between tabs.
|
|
// See T293441 for further information on that.
|
|
max-width: none;
|
|
}
|
|
}
|
|
|
|
.mw-footer-container {
|
|
padding-top: 50px;
|
|
padding-bottom: 82px;
|
|
}
|
|
|
|
// We want it to appear like the sidebar is going into/coming out of
|
|
// `.mw-page-container`, but we can't use `overflow: hidden` on
|
|
// `.mw-page-container` because that will cut off the sidebar. Therefore, we
|
|
// calculate the maximum distance from the start of `mw-page-container` to the
|
|
// start of the sidebar.
|
|
#mw-sidebar-checkbox:not( :checked ) ~ .mw-workspace-container .mw-sidebar {
|
|
.transform( translateX( -( @max-width-page-container - @max-width-workspace-container ) / 2 ) );
|
|
}
|
|
|
|
// Hide sidebar entirely when the checkbox is disabled and the TOC is enabled
|
|
.vector-toc-enabled #mw-sidebar-checkbox:not( :checked ) ~ .mw-workspace-container .mw-sidebar {
|
|
display: none;
|
|
}
|
|
|
|
// Responsive overrides.
|
|
@media ( min-width: @min-width-page-container--padded ) {
|
|
.mw-page-container {
|
|
border-left: 1px solid @border-color-sidebar;
|
|
border-right: 1px solid @border-color-sidebar;
|
|
}
|
|
}
|
|
|
|
// Adjusts the content when sidebar is open regardless of the viewport width.
|
|
@{selector-workspace-container-sidebar-open} .mw-content-container {
|
|
// For container logic specific to special pages and history pages.
|
|
.skin-vector-disable-max-width & {
|
|
margin-left: @margin-start-content;
|
|
}
|
|
}
|
|
|
|
@media ( max-width: @max-width-margin-start-content ) {
|
|
// Adjusts the content and mw-article-toolbar-container.
|
|
@{selector-workspace-container-sidebar-open} .mw-content-container,
|
|
@{selector-workspace-container-sidebar-open} .mw-article-toolbar-container {
|
|
margin-left: @margin-start-content;
|
|
}
|
|
|
|
// Increase margin when TOC is enabled
|
|
.vector-toc-enabled @{selector-workspace-container-sidebar-open} .mw-content-container,
|
|
.vector-toc-enabled @{selector-workspace-container-sidebar-open} .mw-article-toolbar-container {
|
|
margin-left: @margin-toc-start-content;
|
|
}
|
|
|
|
// Specificity needed to disable the default animations at lower resolutions.
|
|
.vector-animations-ready .mw-sidebar {
|
|
// Remove sidebar transition at smaller widths.
|
|
transition: none;
|
|
}
|
|
}
|
|
|
|
.skin-vector-toc-experiment-control .mw-table-of-contents-container,
|
|
.skin-vector-toc-experiment-unsampled .mw-table-of-contents-container {
|
|
display: none;
|
|
}
|
|
|
|
// Cannot use display: none on legacy TOC because it needs to be accessible
|
|
// to scrollObserver for the TOC A/B test (T303297)
|
|
// Instead we hide the contents of the legacy TOC and reset it's styles
|
|
// See I3f247730fa1c399e6d2e4d866677703fc24e8c58
|
|
.skin-vector-toc-experiment-treatment #toc {
|
|
padding: 0;
|
|
border: 0;
|
|
}
|
|
|
|
.skin-vector-toc-experiment-treatment #toc > * {
|
|
display: none;
|
|
}
|
|
|
|
// Update article page's content container when
|
|
// TOC is visible and when TOC is enabled and the sidebar is open.
|
|
//
|
|
// T306366: When the TOC AB test is enabled, both the old and new TOC are in the
|
|
// HTML but only one is actually visible. Prevent the left margin from undesirably
|
|
// applying if bucketed into the control or unsampled groups which won't show
|
|
// the new TOC.
|
|
.skin-vector-disable-max-width .vector-toc-enabled @{selector-workspace-container-sidebar-open} .mw-content-container,
|
|
body:not( .skin-vector-toc-experiment-control ):not( .skin-vector-toc-experiment-unsampled ) .vector-toc-visible .mw-workspace-container .mw-content-container,
|
|
body:not( .skin-vector-toc-experiment-control ):not( .skin-vector-toc-experiment-unsampled ) .vector-toc-visible .mw-workspace-container .mw-article-toolbar-container,
|
|
.vector-toc-enabled @{selector-workspace-container-sidebar-open} .mw-content-container,
|
|
.vector-toc-enabled @{selector-workspace-container-sidebar-open} .mw-article-toolbar-container {
|
|
@media ( min-width: @width-breakpoint-desktop ) {
|
|
margin-left: @margin-toc-start-content;
|
|
}
|
|
|
|
@media ( min-width: @width-breakpoint-desktop-wide ) {
|
|
margin-left: @margin-toc-start-content-wide;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Makes the sidebar full screen at lower resolutions.
|
|
*/
|
|
@media ( max-width: @width-breakpoint-tablet ) {
|
|
@{selector-workspace-container-sidebar-open} {
|
|
#mw-panel {
|
|
width: 100%;
|
|
position: relative;
|
|
left: 0;
|
|
float: none;
|
|
}
|
|
|
|
// !important as we always want to disable the margin-left on these elements
|
|
// Using !important is cleaner than having to rely on specificity involved :checked elements
|
|
.mw-content-container,
|
|
.mw-article-toolbar-container {
|
|
// stylelint-disable-next-line declaration-no-important
|
|
margin-left: 0 !important;
|
|
}
|
|
}
|
|
}
|