uikit
Version:
UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.
330 lines (255 loc) • 7.55 kB
text/less
// Name: Off-canvas
// Description: Component to create an off-canvas sidebar
//
// Component: `uk-offcanvas`
//
// Sub-objects: `uk-offcanvas-bar`
// `uk-offcanvas-container`
// `uk-offcanvas-page`
//
// Adopted: `uk-offcanvas-close`
//
// Modifiers: `uk-offcanvas-flip`
// `uk-offcanvas-bar-animation`
// `uk-offcanvas-reveal`
// `uk-offcanvas-overlay`
// `uk-offcanvas-container-animation`
//
// States: `uk-open`
//
// ========================================================================
// Variables
// ========================================================================
@offcanvas-z-index: @global-z-index;
@offcanvas-bar-width: 270px;
@offcanvas-bar-padding-vertical: 20px;
@offcanvas-bar-padding-horizontal: 20px;
@offcanvas-bar-background: @global-secondary-background;
@offcanvas-bar-color-mode: light;
@offcanvas-bar-width-s: 350px;
@offcanvas-bar-padding-vertical-s: @global-gutter;
@offcanvas-bar-padding-horizontal-s: @global-gutter;
@offcanvas-close-position: 5px;
@offcanvas-close-padding: 5px;
@offcanvas-close-position-s: 10px;
@offcanvas-overlay-background: rgba(0,0,0,0.1);
/* ========================================================================
Component: Off-canvas
========================================================================== */
/*
* 1. Hide by default
* 2. Set position
*/
.uk-offcanvas {
/* 1 */
display: none;
/* 2 */
position: fixed;
top: 0;
bottom: 0;
left: 0;
z-index: @offcanvas-z-index;
}
/*
* Flip modifier
*/
.uk-offcanvas-flip .uk-offcanvas {
right: 0;
left: auto;
}
/* Bar
========================================================================== */
/*
* 1. Set position
* 2. Size and style
* 3. Allow scrolling
*/
.uk-offcanvas-bar {
--uk-inverse: @offcanvas-bar-color-mode;
/* 1 */
position: absolute;
top: 0;
bottom: 0;
left: -@offcanvas-bar-width;
/* 2 */
box-sizing: border-box;
width: @offcanvas-bar-width;
padding: @offcanvas-bar-padding-vertical @offcanvas-bar-padding-horizontal;
background: @offcanvas-bar-background;
/* 3 */
overflow-y: auto;
.hook-offcanvas-bar();
}
/* Phone landscape and bigger */
@media (min-width: @breakpoint-small) {
.uk-offcanvas-bar {
left: -@offcanvas-bar-width-s;
width: @offcanvas-bar-width-s;
padding: @offcanvas-bar-padding-vertical-s @offcanvas-bar-padding-horizontal-s;
}
}
// Color Mode
.uk-offcanvas-bar:extend(.uk-light all) when (@offcanvas-bar-color-mode = light) {}
.uk-offcanvas-bar:extend(.uk-dark all) when (@offcanvas-bar-color-mode = dark) {}
/* Flip modifier */
.uk-offcanvas-flip .uk-offcanvas-bar {
left: auto;
right: -@offcanvas-bar-width;
}
/* Tablet landscape and bigger */
@media (min-width: @breakpoint-small) {
.uk-offcanvas-flip .uk-offcanvas-bar { right: -@offcanvas-bar-width-s; }
}
/*
* Open
*/
.uk-open > .uk-offcanvas-bar { left: 0; }
.uk-offcanvas-flip .uk-open > .uk-offcanvas-bar {
left: auto;
right: 0;
}
/*
* Slide Animation (Used in slide and push mode)
*/
.uk-offcanvas-bar-animation { transition: left 0.3s ease-out; }
.uk-offcanvas-flip .uk-offcanvas-bar-animation { transition-property: right; }
/*
* Reveal Animation
* 1. Set position
* 2. Clip the bar
* 3. Animation
* 4. Reset position
*/
.uk-offcanvas-reveal {
/* 1 */
position: absolute;
top: 0;
bottom: 0;
left: 0;
/* 2 */
width: 0;
overflow: hidden;
/* 3 */
transition: width 0.3s ease-out;
}
.uk-offcanvas-reveal .uk-offcanvas-bar {
/* 4 */
left: 0;
}
.uk-offcanvas-flip .uk-offcanvas-reveal .uk-offcanvas-bar {
/* 4 */
left: auto;
right: 0;
}
.uk-open > .uk-offcanvas-reveal { width: @offcanvas-bar-width; }
/* Tablet landscape and bigger */
@media (min-width: @breakpoint-small) {
.uk-open > .uk-offcanvas-reveal { width: @offcanvas-bar-width-s; }
}
/*
* Flip modifier
*/
.uk-offcanvas-flip .uk-offcanvas-reveal {
right: 0;
left: auto;
}
/* Close
* Adopts `uk-close`
========================================================================== */
.uk-offcanvas-close {
position: absolute;
z-index: @offcanvas-z-index;
top: @offcanvas-close-position;
right: @offcanvas-close-position;
padding: @offcanvas-close-padding;
.hook-offcanvas-close();
}
/* Tablet landscape and bigger */
@media (min-width: @breakpoint-small) {
.uk-offcanvas-close {
top: @offcanvas-close-position-s;
right: @offcanvas-close-position-s;
}
}
/*
* Remove margin from adjacent element
*/
.uk-offcanvas-close:first-child + * { margin-top: 0; }
/* Overlay
========================================================================== */
/*
* Overlay the whole page. Needed for the `::before`
* 1. Using `100vw` so no modification is needed when off-canvas is flipped
* 2. Allow for closing with swipe gesture on devices with pointer events.
*/
.uk-offcanvas-overlay {
/* 1 */
width: 100vw;
/* 2 */
touch-action: none;
}
/*
* 1. Mask the whole page
* 2. Fade-in transition
*/
.uk-offcanvas-overlay::before {
/* 1 */
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: @offcanvas-overlay-background;
/* 2 */
opacity: 0;
transition: opacity 0.15s linear;
.hook-offcanvas-overlay();
}
.uk-offcanvas-overlay.uk-open::before { opacity: 1; }
/* Prevent scrolling
========================================================================== */
/*
* Prevent horizontal scrollbar when the content is slide-out
* Has to be on the `html` element too to make it work on the `body`
* 1. `clip` is needed for `position: sticky` elements to keep their position
*/
.uk-offcanvas-page,
.uk-offcanvas-container {
overflow-x: hidden;
/* 1 */
overflow-x: clip;
}
/* Container
========================================================================== */
/*
* Prepare slide-out animation (Used in reveal and push mode)
* Using `position: left` instead of `transform` because position `fixed` elements like sticky navbars
* lose their fixed state and behaves like `absolute` within a transformed container
* 1. Provide a fixed width and prevent shrinking
*/
.uk-offcanvas-container {
position: relative;
left: 0;
transition: left 0.3s ease-out;
/* 1 */
box-sizing: border-box;
width: 100%;
}
/*
* Activate slide-out animation
*/
:not(.uk-offcanvas-flip).uk-offcanvas-container-animation { left: @offcanvas-bar-width; }
.uk-offcanvas-flip.uk-offcanvas-container-animation { left: -@offcanvas-bar-width; }
/* Tablet landscape and bigger */
@media (min-width: @breakpoint-small) {
:not(.uk-offcanvas-flip).uk-offcanvas-container-animation { left: @offcanvas-bar-width-s; }
.uk-offcanvas-flip.uk-offcanvas-container-animation { left: -@offcanvas-bar-width-s; }
}
// Hooks
// ========================================================================
.hook-offcanvas-misc();
.hook-offcanvas-bar() {}
.hook-offcanvas-close() {}
.hook-offcanvas-overlay() {}
.hook-offcanvas-misc() {}