diff --git a/core-blocks/columns/editor.scss b/core-blocks/columns/editor.scss index 6688f057ca73b..39a29d7cc48af 100644 --- a/core-blocks/columns/editor.scss +++ b/core-blocks/columns/editor.scss @@ -1,6 +1,7 @@ // These margins make sure that nested blocks stack/overlay with the parent block chrome // This is sort of an experiment at making sure the editor looks as much like the end result as possible // Potentially the rules here can apply to all nested blocks and enable stacking, in which case it should be moved elsewhere +// Note that when using CSS grid, margins do not collapse on the container .wp-block-columns .editor-block-list__layout { margin-left: 0; margin-right: 0; diff --git a/edit-post/assets/stylesheets/_variables.scss b/edit-post/assets/stylesheets/_variables.scss index c8a14b37c19d0..8cbfd69427501 100644 --- a/edit-post/assets/stylesheets/_variables.scss +++ b/edit-post/assets/stylesheets/_variables.scss @@ -24,11 +24,12 @@ $admin-bar-height-big: 46px; $admin-sidebar-width: 160px; $admin-sidebar-width-big: 190px; $admin-sidebar-width-collapsed: 36px; +$empty-paragraph-height: $text-editor-font-size * 4; // Visuals $shadow-popover: 0 3px 30px rgba( $dark-gray-900, .1 ); $shadow-toolbar: 0 2px 10px rgba( $dark-gray-900, .1 ), 0 0 2px rgba( $dark-gray-900, .1 ); -$shadow-below-only: 0 5px 10px rgba( $dark-gray-900, .1 ), 0 2px 2px rgba( $dark-gray-900, .1 ); +$shadow-below-only: 0 5px 10px rgba( $dark-gray-900, .05 ), 0 2px 2px rgba( $dark-gray-900, .05 ); // Editor Widths $sidebar-width: 280px; diff --git a/edit-post/assets/stylesheets/_z-index.scss b/edit-post/assets/stylesheets/_z-index.scss index a4c704297de97..810b799433bcc 100644 --- a/edit-post/assets/stylesheets/_z-index.scss +++ b/edit-post/assets/stylesheets/_z-index.scss @@ -21,6 +21,7 @@ $z-layers: ( '.editor-block-switcher__menu': 5, '.components-popover__close': 5, '.editor-block-list__insertion-point': 5, + '.editor-inserter-with-shortcuts': 5, '.core-blocks-gallery-item__inline-menu': 20, '.editor-url-input__suggestions': 30, '.edit-post-header': 30, diff --git a/edit-post/components/header/header-toolbar/style.scss b/edit-post/components/header/header-toolbar/style.scss index fd6245e5dd299..41d08213520eb 100644 --- a/edit-post/components/header/header-toolbar/style.scss +++ b/edit-post/components/header/header-toolbar/style.scss @@ -1,4 +1,4 @@ -// hide all action buttons except the inserter on mobile +// Hide all action buttons except the inserter on mobile. .edit-post-header-toolbar > .components-button { display: none; @@ -18,15 +18,25 @@ } } +// Block toolbar when fixed to the top of the screen. .edit-post-header-toolbar__block-toolbar { - // stacked toolbar + // Stack toolbar below Editor Bar. position: absolute; top: $header-height; left: 0; right: 0; background: $white; - border-bottom: 1px solid $light-gray-500; min-height: $block-toolbar-height; + border-bottom: 1px solid $light-gray-500; + + .editor-block-toolbar { + border-left: none; + } + + .editor-block-toolbar .components-toolbar { + border-top: none; + border-bottom: none; + } .is-sidebar-opened & { display: none; @@ -39,8 +49,8 @@ } } - // merge toolbars after this breakpoint - @include break-large { // we should try and lower this breakpoint through an ellipsis overflow feature + // Move toolbar into top Editor Bar. + @include break-large { padding-left: $item-spacing; position: static; left: auto; diff --git a/edit-post/components/visual-editor/style.scss b/edit-post/components/visual-editor/style.scss index 709b39468a323..1a08f6eb0694d 100644 --- a/edit-post/components/visual-editor/style.scss +++ b/edit-post/components/visual-editor/style.scss @@ -2,6 +2,7 @@ position: relative; padding: 50px 0; + .editor-default-block-appender__content, // The default appender should match a single paragraph. &, & p { font-family: $editor-font; @@ -49,11 +50,28 @@ margin-right: -$block-side-ui-width; } - &[data-align="full"] > .editor-block-contextual-toolbar, - &[data-align="wide"] > .editor-block-contextual-toolbar { // Don't affect nested block toolbars. - max-width: $content-width + $parent-block-padding; // Add 1px border left and right. - margin-left: auto; - margin-right: auto; + // Center the block toolbar on wide and full-wide blocks. + // Use specific selector to not affect nested block toolbars. + &[data-align="wide"] > .editor-block-list__block-edit > .editor-block-contextual-toolbar, + &[data-align="full"] > .editor-block-list__block-edit > .editor-block-contextual-toolbar { + width: calc( 100% + #{ $parent-block-padding + $parent-block-padding + $border-width + $border-width } ); + height: 0px; // This collapses the container to an invisible element without margin. + text-align: center; + + .editor-block-toolbar { + max-width: $content-width + $block-padding + $block-padding; + width: 100%; + position: relative; + } + } + + // The centering math changes when a fullwide image doesn't have block padding. + &[data-align="full"] > .editor-block-list__block-edit > .editor-block-contextual-toolbar { + width: calc( 100% + #{ $block-padding + $block-padding } ); + + .editor-block-toolbar { + max-width: $content-width - $border-width - $border-width; + } } } diff --git a/editor/components/block-list/block.js b/editor/components/block-list/block.js index fb03d7b7d0c4a..2195223e3ff55 100644 --- a/editor/components/block-list/block.js +++ b/editor/components/block-list/block.js @@ -402,7 +402,8 @@ export class BlockListBlock extends Component { // Empty paragraph blocks should always show up as unselected. const showEmptyBlockSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock; const showSideInserter = ( isSelected || isHovered ) && isEmptyDefaultBlock; - const shouldAppearSelected = ! showSideInserter && ( isSelected || hasSelectedInnerBlock ) && ! isTypingWithinBlock; + const shouldAppearSelected = ! showSideInserter && isSelected && ! isTypingWithinBlock; + const shouldAppearSelectedParent = ! showSideInserter && hasSelectedInnerBlock && ! isTypingWithinBlock; // We render block movers and block settings to keep them tabbale even if hidden const shouldRenderMovers = ( isSelected || hoverArea === 'left' ) && ! showEmptyBlockSideInserter && ! isMultiSelecting && ! isMultiSelected && ! isTypingWithinBlock; const shouldRenderBlockSettings = ( isSelected || hoverArea === 'right' ) && ! isMultiSelecting && ! isMultiSelected && ! isTypingWithinBlock; @@ -421,6 +422,7 @@ export class BlockListBlock extends Component { const wrapperClassName = classnames( 'editor-block-list__block', { 'has-warning': ! isValid || !! error, 'is-selected': shouldAppearSelected, + 'is-selected-parent': shouldAppearSelectedParent, 'is-multi-selected': isMultiSelected, 'is-hovered': isHovered && ! isEmptyDefaultBlock, 'is-shared': isSharedBlock( blockType ), @@ -514,7 +516,6 @@ export class BlockListBlock extends Component { /> ) } { shouldShowBreadcrumb && } - { shouldShowContextualToolbar && } { isFirstMultiSelected && } - + { shouldShowContextualToolbar && } { isValid && mode === 'visual' && ( .editor-block-list__block-edit:before, &.is-selected > .editor-block-list__block-edit:before { // use opacity to work in various editor styles outline: $border-width solid $dark-opacity-light-500; - top: -$block-padding; - bottom: -$block-padding; .is-dark-theme & { outline-color: $light-opacity-light-500; @@ -403,7 +405,7 @@ // Mover and settings above > .editor-block-mover, > .editor-block-settings-menu { - top: -$block-side-ui-width - $border-width; // This moves the menu up by the height of the button + border. + top: -$block-side-ui-width - $block-padding - $border-width; bottom: auto; min-height: 0; height: auto; @@ -416,11 +418,11 @@ } > .editor-block-mover { - left: 10px; + left: $parent-block-padding; } > .editor-block-settings-menu { - right: 10px; + right: $parent-block-padding; width: $block-side-ui-width * 2; flex-direction: row; } @@ -528,7 +530,7 @@ /** - * Left and right side UI + * Left and right side UI, & Unified toolbar on Mobile */ .editor-block-list__block { @@ -537,12 +539,17 @@ > .editor-block-settings-menu, > .editor-block-mover { position: absolute; - top: 0; width: $block-side-ui-width + $block-side-ui-clearance; height: 100%; // stretch to fill half of the available space to increase hoverable area max-height: $block-side-ui-width * 4; // stretch to fill half of the available space to increase hoverable area } + // Position depending on whether selected or not. + > .editor-block-settings-menu, + > .editor-block-mover { + top: -$block-padding - $border-width; + } + // Elevate when selected or hovered @include break-small() { &.is-multi-selected, @@ -606,11 +613,13 @@ .editor-block-list__block-mobile-toolbar { display: flex; flex-direction: row; - margin-top: $item-spacing + $block-toolbar-height; // Make room for the height of the block toolbar above. + margin-top: $item-spacing + $block-toolbar-height - $block-padding; // Make room for the height of the block toolbar above. margin-right: -$block-padding; - margin-bottom: -$block-padding - $border-width; margin-left: -$block-padding; border-top: $border-width solid $light-gray-500; + height: $block-toolbar-height; + + transform: translateY( #{ $block-padding + $border-width } ); @include break-small() { display: none; @@ -618,7 +627,7 @@ // Show a shadow below the selected block to imply separation. box-shadow: $shadow-below-only; - @include break-mobile() { + @include break-small() { box-shadow: none; } @@ -674,6 +683,7 @@ /** * In-Canvas Inserter */ + .editor-block-list .editor-inserter { margin: $item-spacing; cursor: move;/* Fallback for IE/Edge < 14 */ @@ -703,13 +713,15 @@ } position: absolute; - top: 0; bottom: auto; left: 0; right: 0; - height: $block-padding * 2; // Matches the whole empty space between two blocks + height: $block-padding * 2; // Matches the whole empty space between two blocks. justify-content: center; + // Position above block. + top: -$block-padding; + // Show a clickable plus. .editor-block-list__insertion-point-button { margin-top: -4px; @@ -785,10 +797,10 @@ /** - * Block Toolbar + * Block Toolbar when contextual. */ - .editor-block-list__block .editor-block-contextual-toolbar { +.editor-block-list__block .editor-block-contextual-toolbar { position: sticky; z-index: z-index( '.editor-block-contextual-toolbar' ); white-space: nowrap; @@ -798,29 +810,23 @@ // Position toolbar below the block on mobile. position: absolute; - bottom: $block-toolbar-height; - left: $block-padding; - right: $block-padding; + bottom: $block-toolbar-height - $block-padding; + left: 0; + right: 0; - @include break-small() { - top: -$border-width; - } + // Paint the borders on the toolbar itself on mobile. + border-top: 1px solid $light-gray-500; + .components-toolbar { + border-top: none; + border-bottom: none; - // Position the contextual toolbar above the block. - @include break-mobile() { - position: relative; - top: auto; - bottom: auto; - left: auto; - right: auto; - margin-top: -$block-toolbar-height - $border-width; - margin-bottom: $block-padding + $border-width; + } - // IE11 does not support `position: sticky`. - @supports (position: sticky) { - position: sticky; - // Avoid appearance of double border when toolbar sticks at the top of the editor. - top: -$border-width; + @include break-small() { + border-top: none; + .components-toolbar { + border-top: 1px solid $light-gray-500; + border-bottom: 1px solid $light-gray-500; } } @@ -836,13 +842,13 @@ margin-right: -$block-padding - $border-width; @include break-small() { - margin-left: -$parent-block-padding - $block-side-ui-width - $border-width; - margin-right: -$parent-block-padding - $block-side-ui-width - $border-width; + margin-left: -$parent-block-padding - $border-width; + margin-right: -$parent-block-padding - $border-width; // Position toolbar for nested contexts. .editor-block-list__block & { - margin-left: -$block-padding - $block-side-ui-width - $border-width; - margin-right: -$block-padding - $block-side-ui-padding - $border-width; + margin-left: -$block-padding - $border-width; + margin-right: -$block-padding - $border-width; } // Except for wide elements, this causes a horizontal scrollbar. @@ -856,13 +862,47 @@ & > * { pointer-events: auto; } +} + +// Enable toolbar footprint collapsing +.editor-block-contextual-toolbar { + // Position the contextual toolbar above the block. + .editor-block-list__block & { + @include break-small() { + bottom: auto; + left: auto; + right: auto; + box-shadow: none; + + // IE11 does not support `position: sticky`. + @supports ( position: sticky ) { + position: sticky; + } + + // Move the block toolbar out of the flow using translate. + transform: translateY( -$block-toolbar-height -$block-padding -$border-width ); + + // Compensate for translate, so the sticky sticks to the top. + top: $block-toolbar-height + $block-padding; + + // This is an important one. Because the toolbar is sticky, it's part of the flow. + // It behaves as relative, in other words, until it reaches an edge and then behaves as fixed. + // But by applying a float, we take it out of this flow. The benefit is that we don't need to compensate for margins. + // In turn, this allows margins on sibling elements to collapse to parent elements. + float: left; + } + } + .editor-block-list__block[data-align="right"] & { + @include break-small() { + float: right; + } + } } +// Position the block toolbar when contextual. .editor-block-contextual-toolbar .editor-block-toolbar { width: 100%; - background: $white; - border: $border-width solid $light-gray-500; // Hide right border on desktop, where the .components-toolbar instead has a right border. @include break-small() { @@ -870,8 +910,10 @@ } // This prevents floats from messing up the position. - position: absolute; - left: 0; + @include break-small() { + position: absolute; + left: 0; + } .editor-block-list__block[data-align="right"] & { left: auto; @@ -883,21 +925,19 @@ } } + /** * Hover label */ - .editor-block-list__breadcrumb { + +.editor-block-list__breadcrumb { position: absolute; line-height: 1; z-index: z-index( '.editor-block-list__breadcrumb' ); - // Position in the top right of the border - right: -$block-side-ui-clearance; - - @include break-small() { - right: -$block-parent-side-ui-clearance; - } - top: 0; + // Position in the top right of the border. + right: -$block-parent-side-ui-clearance; + top: -$block-padding - $border-width; // Nested .editor-block-list__block-edit & { diff --git a/editor/components/block-mover/style.scss b/editor/components/block-mover/style.scss index ddea50def9bfd..eca87d7c7c6b6 100644 --- a/editor/components/block-mover/style.scss +++ b/editor/components/block-mover/style.scss @@ -1,4 +1,6 @@ .editor-block-mover { + min-height: $empty-paragraph-height; + opacity: 0; &.is-visible { diff --git a/editor/components/block-settings-menu/style.scss b/editor/components/block-settings-menu/style.scss index dfad9afba418d..9d1f5226f9e5f 100644 --- a/editor/components/block-settings-menu/style.scss +++ b/editor/components/block-settings-menu/style.scss @@ -1,4 +1,6 @@ .editor-block-settings-menu { + min-height: $empty-paragraph-height; + line-height: 1; opacity: 0; diff --git a/editor/components/block-toolbar/style.scss b/editor/components/block-toolbar/style.scss index 1fedaad2e9d6f..dee5d69ddf12a 100644 --- a/editor/components/block-toolbar/style.scss +++ b/editor/components/block-toolbar/style.scss @@ -2,7 +2,6 @@ display: inline-flex; flex-grow: 1; width: 100%; - background: $white; overflow: auto; // Allow horizontal scrolling on mobile. position: relative; @@ -11,8 +10,14 @@ overflow: inherit; } + // Show a left border on the parent container. + border-left: $border-width solid $light-gray-500; + + // The component is born with a border, but we only need some of them. .components-toolbar { - border: none; + border: 0; + border-top: $border-width solid $light-gray-500; + border-bottom: $border-width solid $light-gray-500; // Add a right border to show as separator in the block toolbar. border-right: $border-width solid $light-gray-500; diff --git a/editor/components/default-block-appender/style.scss b/editor/components/default-block-appender/style.scss index 3a5c27b33580e..1b0ec86de0d87 100644 --- a/editor/components/default-block-appender/style.scss +++ b/editor/components/default-block-appender/style.scss @@ -1,26 +1,19 @@ -$empty-paragraph-height: $text-editor-font-size * 4; - .editor-default-block-appender { input[type=text].editor-default-block-appender__content { // needs specificity border: none; background: none; box-shadow: none; display: block; - margin: 0; + margin-left: 0; + margin-right: 0; max-width: none; // fixes a bleed issue from the admin - padding: $block-padding; - font-size: $editor-font-size; - font-family: $editor-font; cursor: text; width: 100%; - font-family: $editor-font; outline: 1px solid transparent; transition: 0.2s outline; - // match the height of an empty paragraph - // to prevent margins from collapsing we add 1px padding top and bottom to both .editor-block-list__block and .editor-block-list__block-edit (coming to a total of 4px extra) - // @todo: revisit when we allow margins to collapse - height: $empty-paragraph-height + 4px; + // Emulate the dimensions of a paragraph block. + padding: 0 #{ $block-padding + $border-width }; // use opacity to work in various editor styles color: $dark-opacity-300; @@ -30,7 +23,7 @@ $empty-paragraph-height: $text-editor-font-size * 4; } } - // Show quick insertion icons faded until hover + // Show quick insertion icons faded until hover. .editor-inserter-with-shortcuts { opacity: .5; transition: opacity 0.2s; @@ -49,7 +42,7 @@ $empty-paragraph-height: $text-editor-font-size * 4; opacity: 1; } - // Show the inserter if mousing over or there is a tip + // Show the inserter if mousing over or there is a tip. &:not( .has-tip ) { .editor-inserter__toggle:not( [aria-expanded="true"] ) { opacity: 0; @@ -60,18 +53,32 @@ $empty-paragraph-height: $text-editor-font-size * 4; } } - // Dropzone + // Dropzone. .components-drop-zone__content-icon { display: none; } } -// Left side inserter icon +// Quick shortcuts, left and right. +.editor-block-list__empty-block-inserter, // Empty paragraph +.editor-default-block-appender .editor-inserter, // Empty appender +.editor-inserter-with-shortcuts { // Right side quick shortcuts + position: absolute; + top: 0; + + // Change the size of the buttons to match that of the default paragraph height. + .components-icon-button { + width: $block-side-ui-width; + height: $block-side-ui-width; + padding: 4px; + margin-right: 12px; + } +} + +// Left side. .editor-block-list__empty-block-inserter, .editor-default-block-appender .editor-inserter { - position: absolute; - top: $item-spacing; - right: $item-spacing; // show on the right on mobile + right: $item-spacing; // Show to the right on mobile. @include break-small { left: -$block-side-ui-width - $block-padding - $block-side-ui-clearance; @@ -87,7 +94,6 @@ $empty-paragraph-height: $text-editor-font-size * 4; border-radius: 50%; width: $block-side-ui-width; height: $block-side-ui-width; - top: 4px; padding: 4px; // use opacity to work in various editor styles @@ -101,12 +107,11 @@ $empty-paragraph-height: $text-editor-font-size * 4; } } -// Quick block insertion icons on the right +// Quick block insertion icons on the right side. .editor-inserter-with-shortcuts { - position: absolute; - top: $item-spacing; right: $block-padding; - display: none; + display: none; // Don't show on mobile. + z-index: z-index( '.editor-inserter-with-shortcuts' ); // Elevate above the sibling inserter. @include break-small { right: 0;