// ========================================================================== // Plyr styles // https://github.com/selz/plyr // ========================================================================== // Variables // ------------------------------- // Colors @blue: #3498DB; @gray-dark: #343F4A; @gray: #565D64; @gray-light: #6B7D86; @gray-lighter: #CBD0D3; @off-white: #D6DADD; // Font sizes @font-size-small: 14px; @font-size-base: 16px; @font-size-large: ceil((@font-size-base * 1.5)); // Controls @control-spacing: 10px; @controls-bg: #fff; @control-bg-hover: @blue; .contrast-control-color(@controls-bg); .contrast-control-color-hover(@control-bg-hover); // Tooltips @tooltip-bg: @controls-bg; @tooltip-color: @control-color; @tooltip-padding: @control-spacing; @tooltip-arrow-size: 5px; @tooltip-radius: 3px; // Progress @progress-bg: rgba(red(@gray), green(@gray), blue(@gray), .2); @progress-playing-bg: @blue; @progress-buffered-bg: rgba(red(@gray), green(@gray), blue(@gray), .25); @progress-loading-size: 40px; @progress-loading-bg: rgba(0,0,0, .15); // Volume @volume-track-height: 6px; @volume-track-bg: darken(@controls-bg, 10%); @volume-thumb-height: (@volume-track-height * 2); @volume-thumb-width: (@volume-track-height * 2); @volume-thumb-bg: @control-color; @volume-thumb-bg-focus: @control-bg-hover; // Breakpoints @bp-control-split: 560px; // When controls split into left/right @bp-captions-large: 768px; // When captions jump to the larger font size // Animation // --------------------------------------- @keyframes progress { to { background-position: @progress-loading-size 0; } } // Mixins // ------------------------------- // Contrast .contrast-control-color(@color: "") when (lightness(@color) >= 65%) { @control-color: @gray-light; } .contrast-control-color(@color: "") when (lightness(@color) < 65%) { @control-color: @gray-lighter; } .contrast-control-color-hover(@color: "") when (lightness(@color) >= 65%) { @control-color-hover: @gray; } .contrast-control-color-hover(@color: "") when (lightness(@color) < 65%) { @control-color-hover: #fff; } // Font smoothing .font-smoothing(@mode: on) when (@mode = on) { -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; } .font-smoothing(@mode: on) when (@mode = off) { -moz-osx-font-smoothing: auto; -webkit-font-smoothing: subpixel-antialiased; } // Contain floats: nicolasgallagher.com/micro-clearfix-hack/ .clearfix() { zoom: 1; &:before, &:after { content: ""; display: table; } &:after { clear: both; } } // Tab focus styles .tab-focus() { outline: thin dotted #000; outline-offset: 0; } // styling .volume-thumb() { height: @volume-thumb-height; width: @volume-thumb-width; background: @volume-thumb-bg; border: 0; border-radius: (@volume-thumb-height / 2); transition: background .3s ease; cursor: ew-resize; } .volume-track() { height: @volume-track-height; background: @volume-track-bg; border: 0; border-radius: (@volume-track-height / 2); } .seek-thumb() { background: transparent; border: 0; width: (@control-spacing * 2); height: @control-spacing; } .seek-track() { background: none; border: 0; } // Screen reader only // ------------------------------- .sr-only { position: absolute !important; clip: rect(1px, 1px, 1px, 1px); padding: 0 !important; border: 0 !important; height: 1px !important; width: 1px !important; overflow: hidden; } // Styles // ------------------------------- // Base .player { position: relative; max-width: 100%; min-width: 290px; // border-box everything // http://paulirish.com/2012/box-sizing-border-box-ftw/ &, *, *::after, *::before { box-sizing: border-box; } // For video &-video-wrapper { position: relative; } video, audio { width: 100%; height: auto; vertical-align: middle; } // For embeds &-video-embed { padding-bottom: 56.25%; /* 16:9 */ height: 0; iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; } } // Captions &-captions { display: none; position: absolute; bottom: 0; left: 0; width: 100%; padding: 20px; min-height: 2.5em; color: #fff; font-size: @font-size-base; font-weight: 600; text-shadow: -1px -1px 0 @gray, 1px -1px 0 @gray, -1px 1px 0 @gray, 1px 1px 0 @gray; text-align: center; .font-smoothing(); @media (min-width: @bp-captions-large) { font-size: @font-size-large; } } &.captions-active &-captions { display: block; } // Player controls &-controls { .clearfix(); .font-smoothing(); position: relative; padding: @control-spacing; background: @controls-bg; line-height: 1; text-align: center; box-shadow: 0 1px 1px rgba(red(@gray-dark), green(@gray-dark), blue(@gray-dark), .2); // Layout &-right { display: block; margin: @control-spacing auto 0; } @media (min-width: @bp-control-split) { &-left { float: left; } &-right { float: right; margin-top: 0; } } input + label, button { display: inline-block; vertical-align: middle; margin: 0 2px; padding: (@control-spacing / 2) @control-spacing; transition: background .3s ease, color .3s ease, opacity .3s ease; border-radius: 3px; cursor: pointer; svg { width: 18px; height: 18px; display: block; fill: currentColor; transition: fill .3s ease; } } input + label, .inverted:checked + label { opacity: .5; } button, .inverted + label, input:checked + label { color: @control-color; opacity: 1; } button { border: 0; background: transparent; overflow: hidden; } // Specificity for overriding .inverted button:focus, button:hover, [type="checkbox"]:focus + label, [type="checkbox"] + label:hover { background: @control-bg-hover; color: @control-color-hover; opacity: 1; } button:focus, input:focus + label { outline: 0; } .icon-exit-fullscreen, .icon-muted, .icon-captions-on { display: none; } .player-time { display: inline-block; vertical-align: middle; margin-left: @control-spacing; color: @control-color; font-weight: 600; font-size: @font-size-small; .font-smoothing(); } // Media duration hidden on small screens .player-time + .player-time { display: none; @media (min-width: @bp-control-split) { display: inline-block; } // Add a slash in before &::before { content: "\2044"; margin-right: @control-spacing; } } } // Tooltips &-tooltip { visibility: hidden; position: absolute; z-index: 2; bottom: 100%; margin-bottom: @tooltip-padding; padding: @tooltip-padding (@tooltip-padding * 1.5); opacity: 0; background: @tooltip-bg; border-radius: @tooltip-radius; color: @tooltip-color; font-size: @font-size-small; line-height: 1.5; font-weight: 600; transform: translate(-50%, (@tooltip-padding * 3)) scale(0); transform-origin: 50% 100%; transition: transform .2s .1s ease, opacity .2s .1s ease; &::after { content: ""; display: block; position: absolute; left: 50%; bottom: -@tooltip-arrow-size; margin-left: -@tooltip-arrow-size; width: 0; height: 0; transition: inherit; border-style: solid; border-width: @tooltip-arrow-size @tooltip-arrow-size 0 @tooltip-arrow-size; border-color: @controls-bg transparent transparent; } } label:hover .player-tooltip, input.tab-focus:focus + label .player-tooltip, button:hover .player-tooltip, button.tab-focus:focus .player-tooltip { visibility: visible; opacity: 1; transform: translate(-50%, 0) scale(1); } label:hover .player-tooltip, button:hover .player-tooltip { z-index: 3; } // Player progress // element &-progress { position: absolute; bottom: 100%; left: 0; right: 0; width: 100%; height: @control-spacing; background: @progress-bg; &-buffer[value], &-played[value], &-seek[type=range] { position: absolute; left: 0; top: 0; width: 100%; height: @control-spacing; margin: 0; padding: 0; vertical-align: top; -webkit-appearance: none; -moz-appearance: none; border: none; background: transparent; } &-buffer[value], &-played[value] { &::-webkit-progress-bar { background: transparent; } // Inherit from currentColor; &::-webkit-progress-value { background: currentColor; } &::-moz-progress-bar { background: currentColor; } } &-played[value] { z-index: 2; color: @progress-playing-bg; } &-buffer[value] { color: @progress-buffered-bg; } // Seek control // element // Specificity is for bootstrap compatibility &-seek[type=range] { z-index: 4; cursor: pointer; outline: 0; // Webkit &::-webkit-slider-runnable-track { .seek-track(); } &::-webkit-slider-thumb { -webkit-appearance: none; .seek-thumb(); } // Mozilla &::-moz-range-track { .seek-track(); } &::-moz-range-thumb { -moz-appearance: none; .seek-thumb(); } // Microsoft &::-ms-track { color: transparent; .seek-track(); } &::-ms-fill-lower, &::-ms-fill-upper { .seek-track(); } &::-ms-thumb { .seek-thumb(); } &:focus { outline: 0; } &::-moz-focus-outer { border: 0; } } } // Loading state &.loading .player-progress-buffer { animation: progress 1s linear infinite; background-size: @progress-loading-size @progress-loading-size; background-repeat: repeat-x; background-color: @progress-buffered-bg; background-image: linear-gradient( -45deg, @progress-loading-bg 25%, transparent 25%, transparent 50%, @progress-loading-bg 50%, @progress-loading-bg 75%, transparent 75%, transparent); color: transparent; } // States &-controls [data-player='pause'], &.playing .player-controls [data-player='play'] { display: none; } &.playing .player-controls [data-player='pause'] { display: inline-block; } // Volume control // element // Specificity is for bootstrap compatibility &-volume[type=range] { display: inline-block; vertical-align: middle; -webkit-appearance: none; -moz-appearance: none; width: 100px; margin: 0 @control-spacing 0 0; padding: 0; cursor: pointer; background: transparent; border: none; // Webkit &::-webkit-slider-runnable-track { .volume-track(); } &::-webkit-slider-thumb { -webkit-appearance: none; margin-top: -((@volume-thumb-height - @volume-track-height) / 2); .volume-thumb(); } // Mozilla &::-moz-range-track { .volume-track(); } &::-moz-range-thumb { .volume-thumb(); } // Microsoft &::-ms-track { height: @volume-track-height; background: transparent; border-color: transparent; border-width: ((@volume-thumb-height - @volume-track-height) / 2) 0; color: transparent; } &::-ms-fill-lower, &::-ms-fill-upper { .volume-track(); } &::-ms-thumb { .volume-thumb(); } &:focus { outline: 0; &::-webkit-slider-thumb { background: @volume-thumb-bg-focus; } &::-moz-range-thumb { background: @volume-thumb-bg-focus; } &::-ms-thumb { background: @volume-thumb-bg-focus; } } } // Hide sound controls on iOS // It's not supported to change volume using JavaScript: // https://developer.apple.com/library/safari/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html &.ios &-volume, &.ios [data-player='mute'], &.ios [data-player='mute'] + label, &-audio.ios &-controls-right { display: none; } // Center buttons so it looks less odd &-audio.ios &-controls-left { float: none; } // Audio specific styles // Position the progress within the container &-audio .player-controls { padding-top: (@control-spacing * 2); } &-audio .player-progress { bottom: auto; top: 0; background: @off-white; } // Full screen mode &-fullscreen, &.fullscreen-active { position: fixed; top: 0; left: 0; right: 0; bottom: 0; height: 100%; width: 100%; z-index: 10000000; background: #000; video { height: 100%; } .player-video-wrapper { height: 100%; width: 100%; } .player-controls { position: absolute; bottom: 0; left: 0; right: 0; } // Hide controls when playing in full screen &.fullscreen-hide-controls.playing { .player-controls { transform: translateY(100%) translateY(@control-spacing / 2); transition: transform .3s .2s ease; } &.player-hover .player-controls { transform: translateY(0); } .player-captions { bottom: (@control-spacing / 2); transition: bottom .3s .2s ease; } } // Captions .player-captions, &.fullscreen-hide-controls.playing.player-hover .player-captions { top: auto; bottom: 90px; @media (min-width: @bp-control-split) { bottom: 60px; } } } // Change icons on state change &.fullscreen-active .icon-exit-fullscreen, &.muted .player-controls .icon-muted, &.captions-active .player-controls .icon-captions-on { display: block; & + svg { display: none; } } // Some options are hidden by default [data-player='captions'], [data-player='captions'] + label, [data-player='fullscreen'], [data-player='fullscreen'] + label { display: none; } &.captions-enabled [data-player='captions'], &.captions-enabled [data-player='captions'] + label, &.fullscreen-enabled [data-player='fullscreen'], &.fullscreen-enabled [data-player='fullscreen'] + label { display: inline-block; } }