Split LESS into more granular files, Vimeo fixes

This commit is contained in:
Sam Potts 2017-10-28 20:14:33 +11:00
parent dd9d5c8898
commit 3d50936b47
36 changed files with 1171 additions and 1055 deletions

View File

@ -1,7 +1,7 @@
{
"useTabs": false,
"tabWidth": 4,
"printWidth": 160,
"printWidth": 120,
"singleQuote": true,
"trailingComma": "es5"
}

View File

@ -1,7 +1,7 @@
{
"plyr": {
"less": {
"plyr.css": "src/less/plyr.less"
"plyr.css": "src/less/bundle.less"
},
"scss": {
"plyr.css": "src/scss/plyr.scss"

2
demo/dist/demo.css vendored

File diff suppressed because one or more lines are too long

2
demo/dist/error.css vendored

File diff suppressed because one or more lines are too long

View File

@ -10,12 +10,10 @@
vertical-align: middle;
align-items: center;
padding: (@spacing-base * 0.75);
border-radius: @border-radius-base;
box-shadow: 0 1px 1px fade(#000, 10%);
background: #fff;
border: 0;
color: @gray;
user-select: none;
font-weight: @font-weight-bold;
@ -56,7 +54,6 @@
right: 100%;
top: 50%;
transform: translateY(-50%);
border: @arrow-size solid transparent;
border-right-color: #fff;
border-left-width: 0;

View File

@ -7,8 +7,8 @@ header {
text-align: center;
p {
.font-size(@font-size-large);
margin-bottom: (@spacing-base * 1.5);
.font-size(@font-size-large);
}
@media @mq-md {

View File

@ -14,6 +14,7 @@ video {
border-radius: @border-radius-base;
box-shadow: 0 2px 5px fade(#000, 20%);
}
.plyr__video-wrapper::after {
content: '';
pointer-events: none;

View File

@ -7,6 +7,7 @@
0% {
opacity: 0;
}
100% {
opacity: 1;
}

View File

@ -3,27 +3,27 @@
// ==========================================================================
@font-face {
font-family: "Avenir";
src: url("https://cdn.plyr.io/static/fonts/avenir-medium.woff2") format("woff2"),
url("https://cdn.plyr.io/static/fonts/avenir-medium.woff") format("woff");
font-family: 'Avenir';
src: url('https://cdn.plyr.io/static/fonts/avenir-medium.woff2') format('woff2'),
url('https://cdn.plyr.io/static/fonts/avenir-medium.woff') format('woff');
font-style: normal;
font-weight: @font-weight-base;
font-display: swap;
}
@font-face {
font-family: "Avenir";
src: url("https://cdn.plyr.io/static/fonts/avenir-bold.woff2") format("woff2"),
url("https://cdn.plyr.io/static/fonts/avenir-bold.woff") format("woff");
font-family: 'Avenir';
src: url('https://cdn.plyr.io/static/fonts/avenir-bold.woff2') format('woff2'),
url('https://cdn.plyr.io/static/fonts/avenir-bold.woff') format('woff');
font-style: normal;
font-weight: @font-weight-bold;
font-display: swap;
}
@font-face {
font-family: "Avenir";
src: url("https://cdn.plyr.io/static/fonts/avenir-black.woff2?v=3") format("woff2"),
url("https://cdn.plyr.io/static/fonts/avenir-black.woff?v=3") format("woff");
font-family: 'Avenir';
src: url('https://cdn.plyr.io/static/fonts/avenir-black.woff2?v=3') format('woff2'),
url('https://cdn.plyr.io/static/fonts/avenir-black.woff?v=3') format('woff');
font-style: normal;
font-weight: @font-weight-heavy;
font-display: swap;

View File

@ -189,7 +189,7 @@ pre {
*/
q {
quotes: "\201C" "\201D" "\2018" "\2019";
quotes: '\201C' '\201D' '\2018' '\2019';
}
/**
@ -322,9 +322,9 @@ select {
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
html input[type='button'],
input[type='reset'],
input[type='submit'] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
@ -343,8 +343,8 @@ html input[disabled] {
* 2. Remove excess padding in IE 8/9/10.
*/
input[type="checkbox"],
input[type="radio"] {
input[type='checkbox'],
input[type='radio'] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
@ -355,7 +355,7 @@ input[type="radio"] {
* (include `-moz` to future-proof).
*/
input[type="search"] {
input[type='search'] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
@ -367,8 +367,8 @@ input[type="search"] {
* on OS X.
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
input[type='search']::-webkit-search-cancel-button,
input[type='search']::-webkit-search-decoration {
-webkit-appearance: none;
}

View File

@ -5,5 +5,5 @@
@screen-sm: 480px;
@screen-md: 768px;
@mq-sm: ~"only screen and (min-width: @{screen-sm}) ";
@mq-md: ~"only screen and (min-width: @{screen-md}) ";
@mq-sm: ~'only screen and (min-width: @{screen-sm}) ';
@mq-md: ~'only screen and (min-width: @{screen-md}) ';

View File

@ -12,8 +12,8 @@ body {
line-height: @line-height-base;
color: @color-text;
font-weight: @font-weight-base;
.font-smoothing();
text-shadow: 0 1px 1px fade(#000, 15%);
.font-smoothing();
}
button,
@ -27,6 +27,7 @@ p,
small {
margin: 0 0 @spacing-base;
}
small {
display: block;
.font-size(@font-size-small);

View File

@ -5,6 +5,7 @@
.color--vimeo {
color: @color-vimeo;
}
.color--youtube {
color: @color-youtube;
}

2
dist/plyr.css vendored

File diff suppressed because one or more lines are too long

2
dist/plyr.js vendored

File diff suppressed because one or more lines are too long

View File

@ -304,6 +304,7 @@
hideControls: 'plyr--hide-controls',
isIos: 'plyr--is-ios',
isTouch: 'plyr--is-touch',
uiSupported: 'plyr--full-ui',
menu: {
value: 'plyr__menu__value',
badge: 'plyr__badge',
@ -468,54 +469,58 @@
name: name,
version: majorVersion,
isIE: isIE,
isOldIE: isIE && majorVersion <= 9,
isFirefox: isFirefox,
isChrome: isChrome,
isSafari: isSafari,
isWebkit: 'WebkitAppearance' in document.documentElement.style,
isIPhone: /(iPhone|iPod)/gi.test(navigator.platform),
isIos: /(iPad|iPhone|iPod)/gi.test(navigator.platform),
isSupported: !(isIE && majorVersion <= 9),
};
},
// Check for support
// Basic functionality vs full UI
checkSupport: function(type, inline) {
var basic = false;
var full = false;
var api = false;
var ui = false;
var browser = utils.getBrowser();
var playsInline = browser.isIPhone && inline && support.inline;
switch (type) {
case 'video':
basic = support.video;
full = basic && !browser.isOldIE && (!browser.isIPhone || playsInline);
api = support.video;
ui = api && browser.isSupported && (!browser.isIPhone || playsInline);
break;
case 'audio':
basic = support.audio;
full = basic && !browser.isOldIE;
api = support.audio;
ui = api && browser.isSupported;
break;
case 'youtube':
basic = support.video;
full = basic && !browser.isOldIE && (!browser.isIPhone || playsInline);
api = true;
ui = api && browser.isSupported && (!browser.isIPhone || playsInline);
break;
case 'vimeo':
api = true;
ui = false;
break;
case 'soundcloud':
basic = true;
full = !browser.isOldIE && !browser.isIos;
api = true;
ui = browser.isSupported;
break;
default:
basic = support.audio && support.video;
full = basic && !browser.isOldIE;
api = support.audio && support.video;
ui = api && browser.isSupported;
}
return {
basic: basic,
full: full,
api: api,
ui: ui,
};
},
@ -1371,7 +1376,7 @@
}
// Trap focus inside container
function focusTrap() {
function trapFocus() {
var tabbables = getElements('input:not([disabled]), button:not([disabled])');
var first = tabbables[0];
var last = tabbables[tabbables.length - 1];
@ -1455,9 +1460,14 @@
}
var styleSheet = player.elements.styleSheet.sheet;
var percentage = (range.value / range.max) * 100;
var percentage = range.value / range.max * 100;
var selector = '#' + range.id + '::-webkit-slider-runnable-track';
var styles = '{ background-image: linear-gradient(to right, currentColor ' + percentage + '%, transparent ' + percentage + '%) }';
var styles =
'{ background-image: linear-gradient(to right, currentColor ' +
percentage +
'%, transparent ' +
percentage +
'%) }';
var index = -1;
// Find old rule if it exists
@ -1761,7 +1771,6 @@
}
// Play Pause button
// TODO: This should be a toggle button really?
if (utils.inArray(player.config.controls, 'play')) {
controls.appendChild(createButton('play'));
controls.appendChild(createButton('pause'));
@ -2369,7 +2378,7 @@
// Setup fullscreen
function setupFullscreen() {
if (!player.supported.full || player.type === 'audio' || !player.config.fullscreen.enabled) {
if (!player.supported.ui || player.type === 'audio' || !player.config.fullscreen.enabled) {
return;
}
@ -2390,12 +2399,17 @@
utils.toggleState(player.elements.buttons.fullscreen, false);
}
// Setup focus trap
focusTrap();
// Trap focus in container
trapFocus();
}
// Setup captions
function setupCaptions() {
// Requires UI support
if (!player.supported.ui) {
return;
}
// Set default language if not set
if (!utils.is.empty(player.storage.language)) {
player.captions.language = player.storage.language;
@ -2531,6 +2545,10 @@
// Get current selected caption language
function getLanguage() {
if (!player.supported.ui) {
return null;
}
if (!support.textTracks || utils.is.empty(player.captions.tracks)) {
return player.config.i18n.none;
}
@ -2563,6 +2581,11 @@
// Set the current caption
function setCaption(caption) {
// Requires UI
if (!player.supported.ui) {
return;
}
if (utils.is.htmlElement(player.elements.captions)) {
var content = utils.createElement('span');
@ -2759,11 +2782,17 @@
}
// Toggle style hook
function toggleStyleHook() {
function addStyleHook() {
utils.toggleClass(
player.elements.container,
player.config.selectors.container.replace('.', ''),
player.supported.full
true
);
utils.toggleClass(
player.elements.container,
player.config.classNames.uiSupported,
player.supported.ui
);
}
@ -2790,7 +2819,7 @@
}
// If there's a play button, set label
if (player.supported.full) {
if (player.supported.ui) {
if (utils.is.htmlElement(player.elements.buttons.play)) {
player.elements.buttons.play.setAttribute('aria-label', label);
}
@ -2865,7 +2894,6 @@
return;
}
if (player.supported.full) {
// Add type class
utils.toggleClass(
player.elements.container,
@ -2883,6 +2911,7 @@
);
}
if (player.supported.ui) {
// Check for picture-in-picture support
utils.toggleClass(
player.elements.container,
@ -3028,7 +3057,7 @@
// When embeds are ready
function embedReady() {
// Setup the UI and call ready if full support
if (player.supported.full) {
if (player.supported.ui) {
setupInterface();
ready();
}
@ -3045,7 +3074,7 @@
videoId: videoId,
playerVars: {
autoplay: player.config.autoplay ? 1 : 0, // Autoplay
controls: player.supported.full ? 0 : 1, // Only show controls if not fully supported
controls: player.supported.ui ? 0 : 1, // Only show controls if not fully supported
rel: 0, // No related vids
showinfo: 0, // Hide info
iv_load_policy: 3, // Hide annotations
@ -3120,7 +3149,7 @@
player.config.title = instance.getVideoData().title;
// Set the tabindex
if (player.supported.full) {
if (player.supported.ui) {
player.media.setAttribute('tabindex', -1);
}
@ -3300,7 +3329,7 @@
player.embed.on('loaded', function() {
// Fix keyboard focus issues
// https://github.com/sampotts/plyr/issues/317
if (utils.is.htmlElement(player.embed.element) && player.supported.full) {
if (utils.is.htmlElement(player.embed.element) && player.supported.ui) {
player.embed.element.setAttribute('tabindex', -1);
}
});
@ -3345,6 +3374,7 @@
}
// Soundcloud ready
// TODO: Document
function soundcloudReady() {
/* jshint validthis: true */
player.embed = window.SC.Widget(this);
@ -3568,7 +3598,7 @@
// Update volume UI and storage
function updateVolume() {
// Update the <input type="range"> if present
if (player.supported.full) {
if (player.supported.ui) {
var value = player.media.muted ? 0 : player.media.volume;
if (player.elements.inputs.volume) {
@ -3585,7 +3615,7 @@
utils.toggleClass(player.elements.container, player.config.classNames.muted, player.media.muted);
// Update checkbox for mute state
if (player.supported.full && player.elements.buttons.mute) {
if (player.supported.ui && player.elements.buttons.mute) {
utils.toggleState(player.elements.buttons.mute, player.media.muted);
}
}
@ -3645,7 +3675,7 @@
// Update <progress> elements
function updateProgress(event) {
if (!player.supported.full) {
if (!player.supported.ui) {
return;
}
@ -3732,7 +3762,7 @@
// Show the duration on metadataloaded
function displayDuration() {
if (!player.supported.full) {
if (!player.supported.ui) {
return;
}
@ -3911,9 +3941,9 @@
utils.toggleClass(
player.elements.container,
player.config.classNames.captions.active,
player.captions.enabled
player.supported.ui && player.captions.enabled
);
toggleStyleHook();
addStyleHook();
// Set new sources for html5
if (utils.inArray(types.html5, player.type)) {
@ -3937,7 +3967,7 @@
// If HTML5 or embed but not fully supported, setupInterface and call ready now
if (
utils.inArray(types.html5, player.type) ||
(utils.inArray(types.embed, player.type) && !player.supported.full)
(utils.inArray(types.embed, player.type) && !player.supported.ui)
) {
// Setup interface
setupInterface();
@ -4385,7 +4415,9 @@
// Handle user exiting fullscreen by escaping etc
if (support.fullscreen) {
utils.on(document, fullscreen.eventType, function(event) { player.toggleFullscreen(event); });
utils.on(document, fullscreen.eventType, function(event) {
player.toggleFullscreen(event);
});
}
}
@ -4427,7 +4459,7 @@
utils.on(player.media, 'waiting canplay seeked', checkLoading);
// Click video
if (player.config.clickToPlay && player.type !== 'audio') {
if (player.supported.ui && player.config.clickToPlay && player.type !== 'audio') {
// Re-fetch the wrapper
var wrapper = getElement('.' + player.config.classNames.video);
@ -4552,8 +4584,12 @@
// Setup the UI
function setupInterface() {
// Re-attach media element listeners
// TODO: Use event bubbling
mediaListeners();
// Don't setup interface if no support
if (!player.supported.full) {
if (!player.supported.ui) {
warn('Basic support only', player.type);
// Remove controls
@ -4574,7 +4610,7 @@
// Inject custom controls
injectControls();
// Re-attach listeners
// Re-attach control listeners
listeners();
}
@ -4583,9 +4619,6 @@
return;
}
// Media element listeners
mediaListeners();
// Remove native controls
toggleNativeControls();
@ -4650,7 +4683,7 @@
// Bail if disabled or no basic support
// You may want to disable certain UAs etc
if (!utils.checkSupport().basic) {
if (!utils.checkSupport().api) {
error('Setup failed: no support');
return;
}
@ -4722,8 +4755,8 @@
// Check for support again but with type
player.supported = utils.checkSupport(player.type, player.config.inline);
// If no native support, bail
if (!player.supported.basic) {
// If no support for even API, bail
if (!player.supported.api) {
error('Setup failed: no support');
return;
}
@ -4735,10 +4768,10 @@
player.elements.container = utils.wrap(media, utils.createElement('div'));
// Allow focus to be captured
player.elements.container.setAttribute('tabindex', 0);
// player.elements.container.setAttribute('tabindex', 0);
// Add style hook
toggleStyleHook();
addStyleHook();
// Debug info
log(player.browser.name + ' ' + player.browser.version);
@ -4757,7 +4790,7 @@
// If embed but not fully supported, setupInterface (to avoid flash of controls) and call ready now
if (
utils.inArray(types.html5, player.type) ||
(utils.inArray(types.embed, player.type) && !player.supported.full)
(utils.inArray(types.embed, player.type) && !player.supported.ui)
) {
// Setup UI
setupInterface();
@ -5304,7 +5337,7 @@
var player = this;
// If there's no full support, or there's no caption toggle
if (!player.supported.full || !player.elements.buttons.captions) {
if (!player.supported.ui || !player.elements.buttons.captions) {
return;
}
@ -5406,7 +5439,11 @@
player.fullscreen.active = !player.fullscreen.active;
// Add class hook
utils.toggleClass(player.elements.container, player.config.classNames.fullscreen.fallback, player.fullscreen.active);
utils.toggleClass(
player.elements.container,
player.config.classNames.fullscreen.fallback,
player.fullscreen.active
);
// Make sure we don't lose scroll position
if (player.fullscreen.active) {
@ -5483,7 +5520,7 @@
var player = this;
// Don't hide if config says not to, it's audio, or not ready or loading
if (!player.config.hideControls || player.type === 'audio') {
if (!player.supported.ui || !player.config.hideControls || player.type === 'audio') {
return;
}

48
src/less/base.less Normal file
View File

@ -0,0 +1,48 @@
// --------------------------------------------------------------
// Base styling
// --------------------------------------------------------------
// Base
.plyr {
position: relative;
max-width: 100%;
min-width: 200px;
overflow: hidden;
font-family: @plyr-font-family;
font-weight: @plyr-font-weight-normal;
direction: ltr;
text-shadow: none;
// Media elements
video,
audio {
width: 100%;
height: auto;
vertical-align: middle;
border-radius: inherit;
}
}
// Full UI only
.plyr--full-ui {
& when(@plyr-border-box = true) {
// border-box everything
// http://paulirish.com/2012/box-sizing-border-box-ftw/
&,
*,
*::after,
*::before {
box-sizing: border-box;
}
}
& when(@plyr-touch-action = true) {
// Fix 300ms delay
a,
button,
input,
label {
touch-action: manipulation;
}
}
}

29
src/less/bundle.less Normal file
View File

@ -0,0 +1,29 @@
// ==========================================================================
// Plyr styles
// https://github.com/sampotts/plyr
// TODO: Review use of BEM classnames
// ==========================================================================
@import 'settings';
@import 'lib/animation';
@import 'lib/mixins';
@import 'base';
@import 'components/badges';
@import 'components/buttons';
@import 'components/captions';
@import 'components/controls';
@import 'components/embed';
@import 'components/menus';
@import 'components/progress';
@import 'components/sliders';
@import 'components/times';
@import 'components/tooltips';
@import 'components/video';
@import 'components/volume';
@import 'states/fullscreen';
@import 'utils/hidden';

View File

@ -0,0 +1,11 @@
// --------------------------------------------------------------
// Badges
// --------------------------------------------------------------
.plyr__badge {
padding: 1px 4px;
border-radius: 2px;
background: @plyr-menu-color;
color: @plyr-menu-bg;
font-size: @plyr-font-size-tiny;
}

View File

@ -0,0 +1,89 @@
.plyr__control {
position: relative;
display: inline-block;
flex-shrink: 0;
overflow: visible; // IE11
vertical-align: middle;
padding: @plyr-control-padding;
border: 0;
background: transparent;
border-radius: 3px;
cursor: pointer;
transition: background 0.3s ease, color 0.3s ease, opacity 0.3s ease;
color: inherit;
svg {
width: @plyr-control-icon-size;
height: @plyr-control-icon-size;
display: block;
fill: currentColor;
pointer-events: none;
}
// Hide toggle icons by default
.icon--exit-fullscreen,
.icon--muted,
.icon--captions-on {
display: none;
}
// Default focus
&:focus {
outline: 0;
}
}
// Audio styles
.plyr--audio .plyr__control {
&.tab-focus,
&:hover,
&[aria-expanded='true'] {
background: @plyr-audio-control-bg-hover;
color: @plyr-audio-control-color-hover;
}
}
// Large play button (video only)
.plyr__play-large {
display: none;
position: absolute;
z-index: 1;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: ceil(@plyr-control-spacing * 1.25);
background: fade(@plyr-video-control-bg-hover, 80%);
border: 3px solid currentColor;
border-radius: 100%;
box-shadow: 0 1px 1px fade(#000, 15%);
color: @plyr-video-control-color;
transition: all 0.3s ease;
svg {
position: relative;
left: 2px;
width: 20px;
height: 20px;
display: block;
fill: currentColor;
pointer-events: none;
}
&:hover,
&:focus {
background: @plyr-video-control-bg-hover;
}
&:focus {
outline: 1px dotted fade(@plyr-video-control-color, 50%);
}
}
.plyr--full-ui.plyr--video .plyr__play-large {
display: inline-block;
}
.plyr--playing .plyr__play-large {
opacity: 0;
visibility: hidden;
}

View File

@ -0,0 +1,57 @@
// --------------------------------------------------------------
// Captions
// --------------------------------------------------------------
// Hide default captions
.plyr--full-ui video::-webkit-media-text-track-container {
display: none;
}
.plyr__captions {
display: none;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: @plyr-control-spacing;
transform: translateY(-(@plyr-control-spacing * 4));
transition: transform 0.3s ease;
color: @plyr-captions-color;
font-size: @plyr-font-size-captions-small;
text-align: center;
span {
border-radius: 2px;
padding: 0.2em 0.5em;
background: @plyr-captions-bg;
box-decoration-break: clone;
line-height: 170%;
white-space: pre-wrap;
// Firefox adds a <div> when using getCueAsHTML()
div {
display: inline;
}
}
span:empty {
display: none;
}
@media (min-width: @plyr-bp-screen-sm) {
padding: (@plyr-control-spacing * 2);
font-size: @plyr-font-size-captions-base;
}
@media (min-width: @plyr-bp-screen-md) {
font-size: @plyr-font-size-captions-medium;
}
}
.plyr--captions-active .plyr__captions {
display: block;
}
.plyr--hide-controls .plyr__captions {
transform: translateY(-(@plyr-control-spacing * 1.5));
}

View File

@ -0,0 +1,127 @@
// --------------------------------------------------------------
// Controls
// --------------------------------------------------------------
// Hide native controls
.plyr ::-webkit-media-controls {
display: none;
}
// Playback controls
.plyr__controls {
display: flex;
align-items: center;
text-align: center;
// Spacing
> .plyr__control,
.plyr__progress,
.plyr__time,
.plyr__menu {
margin-left: (@plyr-control-spacing / 2);
&:first-child,
&:first-child + [data-plyr='pause'] {
margin-left: 0;
}
}
.plyr__volume {
margin-left: (@plyr-control-spacing / 2);
}
@media (min-width: @plyr-bp-screen-sm) {
> .plyr__control,
.plyr__progress,
.plyr__time,
.plyr__menu {
margin-left: @plyr-control-spacing;
}
> .plyr__control + .plyr__control,
.plyr__menu + .plyr__control,
> .plyr__control + .plyr__menu {
margin-left: (@plyr-control-spacing / 2);
}
}
}
// Video controls
.plyr--video .plyr__controls {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
padding: (@plyr-control-spacing * 3.5) (@plyr-control-spacing + 2) @plyr-control-spacing;
background: linear-gradient(fade(@plyr-video-controls-bg, 0%), fade(@plyr-video-controls-bg, 70%));
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
color: @plyr-video-control-color;
transition: all 0.4s ease-in-out;
.plyr__control {
svg {
filter: drop-shadow(0 1px 1px fade(#000, 15%));
}
// Hover and tab focus
&.tab-focus,
&:hover,
&[aria-expanded='true'] {
background: @plyr-video-control-bg-hover;
color: @plyr-video-control-color-hover;
}
}
}
// Hide controls
.plyr--video.plyr--hide-controls .plyr__controls {
opacity: 0;
transform: translateY(100%);
pointer-events: none;
}
// Audio controls
.plyr--audio .plyr__controls {
padding: @plyr-control-spacing;
border-radius: inherit;
background: @plyr-audio-controls-bg;
border: @plyr-audio-controls-border;
color: @plyr-audio-control-color;
}
// States
.plyr__controls [data-plyr='pause'] {
display: none;
}
.plyr--playing .plyr__controls [data-plyr='play'] {
display: none;
}
.plyr--playing .plyr__controls [data-plyr='pause'] {
display: inline-block;
}
// Change icons on state change
.plyr--muted .plyr__control .icon--muted,
.plyr--captions-active .plyr__control .icon--captions-on {
display: block;
& + svg {
display: none;
}
}
// Some options are hidden by default
.plyr [data-plyr='captions'],
.plyr [data-plyr='pip'],
.plyr [data-plyr='airplay'],
.plyr [data-plyr='fullscreen'] {
display: none;
}
.plyr--captions-enabled [data-plyr='captions'],
.plyr--pip-supported [data-plyr='pip'],
.plyr--airplay-supported [data-plyr='airplay'],
.plyr--fullscreen-enabled [data-plyr='fullscreen'] {
display: inline-block;
}

View File

@ -0,0 +1,23 @@
// --------------------------------------------------------------
// Embedded players
// YouTube, Vimeo, etc
// --------------------------------------------------------------
.plyr__video-embed {
padding-bottom: 56.25%; /* 16:9 */
height: 0;
iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
user-select: none;
}
}
// To allow mouse events to be captured if full support
.plyr--full-ui .plyr__video-embed iframe {
pointer-events: none;
}

View File

@ -0,0 +1,155 @@
// --------------------------------------------------------------
// Menus
// --------------------------------------------------------------
.plyr__menu {
position: relative;
// Animate the icon
.plyr__control svg {
transition: transform 0.3s ease;
}
.plyr__control[aria-expanded='true'] {
svg {
transform: rotate(45deg);
}
// Hide tooltip
.plyr__tooltip {
display: none;
}
}
// The actual menu container
&__container {
position: absolute;
z-index: 1;
bottom: 100%;
right: -3px;
margin-bottom: 10px;
animation: plyr-popup 0.2s ease;
background: @plyr-menu-bg;
border-radius: 4px;
box-shadow: 0 1px 2px fade(#000, 20%);
white-space: nowrap;
text-align: left;
color: @plyr-menu-color;
font-size: @plyr-font-size-small;
> div {
overflow: hidden;
transition: height 0.35s cubic-bezier(0.4, 0, 0.2, 1), width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
// Arrow
&::after {
content: '';
position: absolute;
top: 100%;
right: 15px;
height: 0;
width: 0;
border: 4px solid transparent;
border-top-color: @plyr-menu-bg;
}
ul {
margin: 0;
padding: @plyr-control-padding;
list-style: none;
overflow: hidden;
}
// Options
.plyr__control {
display: flex;
align-items: center;
width: 100%;
padding: ceil(@plyr-control-padding / 2) (@plyr-control-padding * 2);
color: @plyr-menu-color;
font-weight: @plyr-font-weight-bold;
user-select: none;
&::after {
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
border: 4px solid transparent;
transition: border-color 0.2s ease;
}
&--forward {
padding-right: ceil(@plyr-control-padding * 4);
&::after {
right: 5px;
border-left-color: fade(@plyr-menu-color, 80%);
}
&.tab-focus::after,
&:hover::after {
border-left-color: currentColor;
}
}
&--back {
position: relative;
@horizontal-padding: (@plyr-control-padding * 2);
width: ~'calc(100% - @{horizontal-padding})';
margin: @plyr-control-padding;
margin-bottom: floor(@plyr-control-padding / 2);
padding-left: ceil(@plyr-control-padding * 4);
font-weight: @plyr-font-weight-normal;
&::after {
left: @plyr-control-padding;
border-right-color: fade(@plyr-menu-color, 80%);
}
&::before {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
height: 1px;
overflow: hidden;
margin-top: ceil(@plyr-control-padding / 2);
background: fade(#000, 15%);
box-shadow: 0 1px 0 fade(#fff, 10%);
}
&.tab-focus::after,
&:hover::after {
border-right-color: currentColor;
}
}
}
label.plyr__control {
padding-left: ceil(@plyr-control-padding * 2.5);
input[type='radio'] {
position: relative;
left: -@plyr-control-padding;
}
}
// Option value
.plyr__menu__value {
display: flex;
align-items: center;
margin-left: auto;
padding-left: ceil(@plyr-control-padding * 3.5);
pointer-events: none;
overflow: hidden;
font-weight: @plyr-font-weight-normal;
.plyr__badge {
font-weight: @plyr-font-weight-bold;
}
}
}
}

View File

@ -0,0 +1,110 @@
// --------------------------------------------------------------
// Playback progress
// --------------------------------------------------------------
.plyr__progress {
position: relative;
display: none;
flex: 1;
input[type='range'] {
position: relative;
z-index: 2;
}
// Seek tooltip to show time
.plyr__tooltip {
left: 0;
}
}
.plyr .plyr__progress {
display: inline-block;
}
.plyr__progress--buffer {
position: absolute;
left: 0;
top: 50%;
width: 100%;
height: @plyr-range-track-height;
margin: -(@plyr-range-track-height / 2) 0 0;
padding: 0;
background: transparent;
border: none;
border-radius: 100px;
// WebKit
-webkit-appearance: none;
&::-webkit-progress-bar {
background: transparent;
}
&::-webkit-progress-value {
background: currentColor;
border-radius: 100px;
min-width: @plyr-range-track-height;
}
// Mozilla
&::-moz-progress-bar {
background: currentColor;
border-radius: 100px;
min-width: @plyr-range-track-height;
}
// Microsoft
&::-ms-fill {
border-radius: 100px;
}
}
.plyr__progress--buffer {
&::-webkit-progress-value {
transition: width 0.2s ease;
}
&::-moz-progress-bar {
transition: width 0.2s ease;
}
&::-ms-fill {
transition: width 0.2s ease;
}
}
.plyr--video .plyr__progress--buffer {
box-shadow: 0 1px 1px fade(#000, 15%);
color: @plyr-video-progress-buffered-bg;
}
.plyr--audio .plyr__progress--buffer {
color: @plyr-audio-progress-buffered-bg;
}
// Loading state
.plyr--loading .plyr__progress--buffer {
animation: plyr-progress 1s linear infinite;
background-size: @plyr-progress-loading-size @plyr-progress-loading-size;
background-repeat: repeat-x;
background-image: linear-gradient(
-45deg,
@plyr-progress-loading-bg 25%,
transparent 25%,
transparent 50%,
@plyr-progress-loading-bg 50%,
@plyr-progress-loading-bg 75%,
transparent 75%,
transparent
);
color: transparent;
}
.plyr--video.plyr--loading .plyr__progress--buffer {
background-color: @plyr-video-progress-buffered-bg;
}
.plyr--audio.plyr--loading .plyr__progress--buffer {
background-color: @plyr-audio-progress-buffered-bg;
}

View File

@ -0,0 +1,140 @@
// --------------------------------------------------------------
// Slider inputs - <input type="range">
// --------------------------------------------------------------
// Specificity is for bootstrap compatibility
.plyr--full-ui input[type='range'] {
display: block;
height: (@plyr-range-thumb-height * @plyr-range-thumb-active-scale);
width: 100%;
margin: 0;
padding: 0;
cursor: pointer;
border: none;
background: transparent;
// Used in JS to populate lower fill for WebKit
color: @plyr-range-selected-bg;
// WebKit
-webkit-appearance: none;
&::-webkit-slider-runnable-track {
.plyr-range-track();
}
&::-webkit-slider-thumb {
-webkit-appearance: none;
margin-top: -((@plyr-range-thumb-height - @plyr-range-track-height) / 2);
.plyr-range-thumb();
}
// Mozilla
&::-moz-range-track {
.plyr-range-track();
}
&::-moz-range-thumb {
.plyr-range-thumb();
}
&::-moz-range-progress {
height: @plyr-range-track-height;
background: currentColor;
border-radius: (@plyr-range-track-height / 2);
}
// Microsoft
&::-ms-track {
height: @plyr-range-track-height;
background: transparent;
border: 0;
color: transparent;
}
&::-ms-fill-upper {
.plyr-range-track();
}
&::-ms-fill-lower {
.plyr-range-track();
background: currentColor;
}
&::-ms-thumb {
.plyr-range-thumb();
// For some reason, Edge uses the -webkit margin above
margin-top: 0;
}
&::-ms-tooltip {
display: none;
}
// Focus styles
&:focus {
outline: 0;
}
&::-moz-focus-outer {
border: 0;
}
&.tab-focus {
outline-offset: 3px;
}
// Pressed styles
&:active {
&::-webkit-slider-thumb {
.plyr-range-thumb-active();
}
&::-moz-range-thumb {
.plyr-range-thumb-active();
}
&::-ms-thumb {
.plyr-range-thumb-active();
}
}
}
// Video range inputs
.plyr--full-ui.plyr--video input[type='range'] {
&::-webkit-slider-runnable-track {
background: @plyr-video-range-track-bg;
}
&::-moz-range-track {
background: @plyr-video-range-track-bg;
}
&::-ms-track {
background: @plyr-video-range-track-bg;
}
&.tab-focus {
outline: 1px dotted fade(@plyr-video-control-color, 50%);
}
}
// Audio range inputs
.plyr--full-ui.plyr--audio input[type='range'] {
&::-webkit-slider-runnable-track {
background: @plyr-audio-range-track-bg;
}
&::-moz-range-track {
background: @plyr-audio-range-track-bg;
}
&::-ms-track {
background: @plyr-audio-range-track-bg;
}
&.tab-focus {
outline: 1px dotted fade(@plyr-audio-control-color, 50%);
}
}

View File

@ -0,0 +1,28 @@
// --------------------------------------------------------------
// Time
// --------------------------------------------------------------
.plyr__time {
display: inline-block;
vertical-align: middle;
font-size: @plyr-font-size-small;
}
// Media duration hidden on small screens
.plyr__time + .plyr__time {
display: none;
@media (min-width: @plyr-bp-screen-md) {
display: inline-block;
}
// Add a slash in before
&::before {
content: '\2044';
margin-right: @plyr-control-spacing;
}
}
.plyr--video .plyr__time {
text-shadow: 0 1px 1px fade(#000, 15%);
}

View File

@ -0,0 +1,87 @@
// --------------------------------------------------------------
// Tooltips
// --------------------------------------------------------------
.plyr__tooltip {
position: absolute;
z-index: 2;
bottom: 100%;
margin-bottom: (@plyr-tooltip-padding * 2);
padding: @plyr-tooltip-padding (@plyr-tooltip-padding * 1.5);
pointer-events: none;
opacity: 0;
background: @plyr-tooltip-bg;
border-radius: @plyr-tooltip-radius;
box-shadow: 0 1px 2px fade(#000, 10%);
color: @plyr-tooltip-color;
font-size: @plyr-font-size-small;
font-weight: @plyr-font-weight-normal;
line-height: 1.3;
transform: translate(-50%, 10px) scale(0.8);
transform-origin: 50% 100%;
transition: transform 0.2s 0.1s ease, opacity 0.2s 0.1s ease;
&::before {
// Arrows
content: '';
position: absolute;
width: 0;
height: 0;
left: 50%;
transform: translateX(-50%);
// The background triangle
bottom: -@plyr-tooltip-arrow-size;
border-right: @plyr-tooltip-arrow-size solid transparent;
border-top: @plyr-tooltip-arrow-size solid @plyr-tooltip-bg;
border-left: @plyr-tooltip-arrow-size solid transparent;
z-index: 2;
}
}
// Displaying
.plyr .plyr__control:hover .plyr__tooltip,
.plyr .plyr__control.tab-focus .plyr__tooltip,
.plyr__tooltip--visible {
opacity: 1;
transform: translate(-50%, 0) scale(1);
}
.plyr .plyr__control:hover .plyr__tooltip {
z-index: 3;
}
// First tooltip
.plyr__controls > .plyr__control:first-child .plyr__tooltip,
.plyr__controls > .plyr__control:first-child + .plyr__control .plyr__tooltip {
left: 0;
transform: translate(0, 10px) scale(0.8);
transform-origin: 0 100%;
&::before {
left: (@plyr-control-icon-size / 2) + @plyr-control-padding;
}
}
// Last tooltip
.plyr__controls > .plyr__control:last-child .plyr__tooltip {
right: 0;
transform: translate(0, 10px) scale(0.8);
transform-origin: 100% 100%;
&::before {
left: auto;
right: (@plyr-control-icon-size / 2) + @plyr-control-padding;
transform: translateX(50%);
}
}
.plyr__controls > .plyr__control:first-child,
.plyr__controls > .plyr__control:first-child + .plyr__control,
.plyr__controls > .plyr__control:last-child {
&:hover .plyr__tooltip,
&.tab-focus .plyr__tooltip,
.plyr__tooltip--visible {
transform: translate(0, 0) scale(1);
}
}

View File

@ -0,0 +1,12 @@
// --------------------------------------------------------------
// Video styles
// --------------------------------------------------------------
.plyr__video-wrapper {
position: relative;
background: #000;
border-radius: inherit;
// Require z-index to force border-radius
z-index: 0;
overflow: hidden;
}

View File

@ -0,0 +1,30 @@
// --------------------------------------------------------------
// Volume
// --------------------------------------------------------------
.plyr__volume {
flex: 1;
position: relative;
input[type='range'] {
position: relative;
z-index: 2;
}
@media (min-width: @plyr-bp-screen-sm) {
display: block;
max-width: 60px;
}
@media (min-width: @plyr-bp-screen-md) {
max-width: 100px;
}
}
// 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
.plyr--is-ios .plyr__volume,
.plyr--is-ios [data-plyr='mute'] {
display: none !important;
}

View File

@ -0,0 +1,21 @@
// --------------------------------------------------------------
// Animations
// --------------------------------------------------------------
@keyframes plyr-progress {
to {
background-position: @plyr-progress-loading-size 0;
}
}
@keyframes plyr-popup {
from {
transform: translateY(10px);
opacity: 0.5;
}
to {
transform: translateY(0);
opacity: 1;
}
}

View File

@ -11,6 +11,7 @@
border-radius: (@plyr-range-track-height / 2);
user-select: none;
}
.plyr-range-thumb() {
position: relative;
height: @plyr-range-thumb-height;
@ -22,6 +23,7 @@
box-shadow: @plyr-range-thumb-shadow;
box-sizing: border-box;
}
.plyr-range-thumb-active() {
background: @plyr-range-thumb-active-bg;
border-color: @plyr-range-thumb-active-border-color;
@ -38,10 +40,12 @@
video {
height: 100%;
}
.plyr__video-wrapper {
height: 100%;
width: 100%;
}
.plyr__video-embed {
// Revert overflow change
overflow: visible;

View File

@ -1,957 +0,0 @@
// ==========================================================================
// Plyr styles
// https://github.com/sampotts/plyr
// TODO: break into smaller files and look at use of BEM classnames
// ==========================================================================
@import 'variables';
@import 'mixins';
// Animation
// ---------------------------------------
@keyframes plyr-progress {
to {
background-position: @plyr-progress-loading-size 0;
}
}
@keyframes plyr-popup {
from {
transform: translateY(10px);
opacity: 0.5;
}
to {
transform: translateY(0);
opacity: 1;
}
}
// Styles
// -------------------------------
// Base
.plyr {
position: relative;
max-width: 100%;
min-width: 200px;
overflow: hidden;
font-family: @plyr-font-family;
font-weight: @plyr-font-weight-normal;
direction: ltr;
text-shadow: none;
& when(@plyr-border-box = true) {
// border-box everything
// http://paulirish.com/2012/box-sizing-border-box-ftw/
&,
*,
*::after,
*::before {
box-sizing: border-box;
}
}
& when(@plyr-touch-action = true) {
// Fix 300ms delay
a,
button,
input,
label {
touch-action: manipulation;
}
}
// ARIA
[aria-hidden='true'] {
display: none;
}
// Focus
&:focus {
outline: 0;
}
// Media elements
video,
audio {
width: 100%;
height: auto;
vertical-align: middle;
border-radius: inherit;
}
// Range inputs
// Specificity is for bootstrap compatibility
input[type='range'] {
display: block;
height: (@plyr-range-thumb-height * @plyr-range-thumb-active-scale);
width: 100%;
margin: 0;
padding: 0;
cursor: pointer;
border: none;
background: transparent;
// Used in JS to populate lower fill for WebKit
color: @plyr-range-selected-bg;
// WebKit
-webkit-appearance: none;
&::-webkit-slider-runnable-track {
.plyr-range-track();
}
&::-webkit-slider-thumb {
-webkit-appearance: none;
margin-top: -((@plyr-range-thumb-height - @plyr-range-track-height) / 2);
.plyr-range-thumb();
}
// Mozilla
&::-moz-range-track {
.plyr-range-track();
}
&::-moz-range-thumb {
.plyr-range-thumb();
}
&::-moz-range-progress {
height: @plyr-range-track-height;
background: currentColor;
border-radius: (@plyr-range-track-height / 2);
}
// Microsoft
&::-ms-track {
height: @plyr-range-track-height;
background: transparent;
border: 0;
color: transparent;
}
&::-ms-fill-upper {
.plyr-range-track();
}
&::-ms-fill-lower {
.plyr-range-track();
background: currentColor;
}
&::-ms-thumb {
.plyr-range-thumb();
// For some reason, Edge uses the -webkit margin above
margin-top: 0;
}
&::-ms-tooltip {
display: none;
}
// Focus styles
&:focus {
outline: 0;
}
&::-moz-focus-outer {
border: 0;
}
&.tab-focus {
outline-offset: 3px;
}
// Pressed styles
&:active {
&::-webkit-slider-thumb {
.plyr-range-thumb-active();
}
&::-moz-range-thumb {
.plyr-range-thumb-active();
}
&::-ms-thumb {
.plyr-range-thumb-active();
}
}
}
}
// Video range inputs
.plyr--video input[type='range'] {
&::-webkit-slider-runnable-track {
background: @plyr-video-range-track-bg;
}
&::-moz-range-track {
background: @plyr-video-range-track-bg;
}
&::-ms-track {
background: @plyr-video-range-track-bg;
}
&.tab-focus {
outline: 1px dotted fade(@plyr-video-control-color, 50%);
}
}
// Audio range inputs
.plyr--audio input[type='range'] {
&::-webkit-slider-runnable-track {
background: @plyr-audio-range-track-bg;
}
&::-moz-range-track {
background: @plyr-audio-range-track-bg;
}
&::-ms-track {
background: @plyr-audio-range-track-bg;
}
&.tab-focus {
outline: 1px dotted fade(@plyr-audio-control-color, 50%);
}
}
// Screen reader only elements
.plyr__sr-only {
clip: rect(1px, 1px, 1px, 1px);
overflow: hidden;
// !important is not always needed
& when(@plyr-sr-only-important = true) {
position: absolute !important;
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
}
& when(@plyr-sr-only-important = false) {
position: absolute;
padding: 0;
border: 0;
height: 1px;
width: 1px;
}
}
// Video
.plyr__video-wrapper {
position: relative;
background: #000;
border-radius: inherit;
// Require z-index to force border-radius
z-index: 0;
overflow: hidden;
}
// Container for embeds
.plyr__video-embed {
padding-bottom: 56.25%; /* 16:9 */
height: 0;
iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
user-select: none;
}
// Vimeo hack
> div {
position: relative;
padding-bottom: 200%;
transform: translateY(-35.95%);
}
}
// To allow mouse events to be captured if full support
.plyr .plyr__video-embed iframe {
pointer-events: none;
}
// Captions
// --------------------------------------------------------------
// Hide default captions
.plyr video::-webkit-media-text-track-container {
display: none;
}
.plyr__captions {
display: none;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: @plyr-control-spacing;
transform: translateY(-(@plyr-control-spacing * 4));
transition: transform 0.3s ease;
color: @plyr-captions-color;
font-size: @plyr-font-size-captions-small;
text-align: center;
span {
border-radius: 2px;
padding: 0.2em 0.5em;
background: @plyr-captions-bg;
box-decoration-break: clone;
line-height: 170%;
white-space: pre-wrap;
// Firefox adds a <div> when using getCueAsHTML()
div {
display: inline;
}
}
span:empty {
display: none;
}
@media (min-width: @plyr-bp-screen-sm) {
padding: (@plyr-control-spacing * 2);
font-size: @plyr-font-size-captions-base;
}
@media (min-width: @plyr-bp-screen-md) {
font-size: @plyr-font-size-captions-medium;
}
}
.plyr--captions-active .plyr__captions {
display: block;
}
.plyr--hide-controls .plyr__captions {
transform: translateY(-(@plyr-control-spacing * 1.5));
}
// Controls
// --------------------------------------------------------------
// Hide native controls
.plyr ::-webkit-media-controls {
display: none;
}
// Playback controls
.plyr__controls {
display: flex;
align-items: center;
text-align: center;
// Spacing
> .plyr__control,
.plyr__progress,
.plyr__time,
.plyr__menu {
margin-left: (@plyr-control-spacing / 2);
&:first-child,
&:first-child + [data-plyr='pause'] {
margin-left: 0;
}
}
.plyr__volume {
margin-left: (@plyr-control-spacing / 2);
}
@media (min-width: @plyr-bp-screen-sm) {
> .plyr__control,
.plyr__progress,
.plyr__time,
.plyr__menu {
margin-left: @plyr-control-spacing;
}
> .plyr__control + .plyr__control,
.plyr__menu + .plyr__control,
> .plyr__control + .plyr__menu {
margin-left: (@plyr-control-spacing / 2);
}
}
}
// Buttons
.plyr__control {
position: relative;
display: inline-block;
flex-shrink: 0;
overflow: visible; // IE11
vertical-align: middle;
padding: @plyr-control-padding;
border: 0;
background: transparent;
border-radius: 3px;
cursor: pointer;
transition: background 0.3s ease, color 0.3s ease, opacity 0.3s ease;
color: inherit;
svg {
width: @plyr-control-icon-size;
height: @plyr-control-icon-size;
display: block;
fill: currentColor;
pointer-events: none;
}
// Hide toggle icons by default
.icon--exit-fullscreen,
.icon--muted,
.icon--captions-on {
display: none;
}
// Default focus
&:focus {
outline: 0;
}
}
// Video controls
.plyr--video .plyr__controls {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 2;
padding: (@plyr-control-spacing * 3.5) (@plyr-control-spacing + 2) @plyr-control-spacing;
background: linear-gradient(fade(@plyr-video-controls-bg, 0%), fade(@plyr-video-controls-bg, 70%));
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
color: @plyr-video-control-color;
transition: all 0.4s ease-in-out;
.plyr__control {
svg {
filter: drop-shadow(0 1px 1px fade(#000, 15%));
}
// Hover and tab focus
&.tab-focus,
&:hover,
&[aria-expanded='true'] {
background: @plyr-video-control-bg-hover;
color: @plyr-video-control-color-hover;
}
}
}
// Hide controls
.plyr--video.plyr--hide-controls .plyr__controls {
opacity: 0;
transform: translateY(100%);
pointer-events: none;
}
// Audio controls
.plyr--audio .plyr__controls {
padding: @plyr-control-spacing;
border-radius: inherit;
background: @plyr-audio-controls-bg;
border: @plyr-audio-controls-border;
color: @plyr-audio-control-color;
.plyr__control {
// Hover and tab focus
&.tab-focus,
&:hover,
&[aria-expanded='true'] {
background: @plyr-audio-control-bg-hover;
color: @plyr-audio-control-color-hover;
}
}
}
// Large play button (video only)
.plyr__play-large {
display: none;
position: absolute;
z-index: 1;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: ceil(@plyr-control-spacing * 1.25);
background: fade(@plyr-video-control-bg-hover, 80%);
border: 3px solid currentColor;
border-radius: 100%;
box-shadow: 0 1px 1px fade(#000, 15%);
color: @plyr-video-control-color;
transition: all 0.3s ease;
svg {
position: relative;
left: 2px;
width: 20px;
height: 20px;
display: block;
fill: currentColor;
pointer-events: none;
}
&:hover,
&:focus {
background: @plyr-video-control-bg-hover;
}
&:focus {
outline: 1px dotted fade(@plyr-video-control-color, 50%);
}
}
.plyr .plyr__play-large {
display: inline-block;
}
.plyr--audio .plyr__play-large {
display: none;
}
.plyr--playing .plyr__play-large {
opacity: 0;
visibility: hidden;
}
// States
.plyr__controls [data-plyr='pause'],
.plyr--playing .plyr__controls [data-plyr='play'] {
display: none;
}
.plyr--playing .plyr__controls [data-plyr='pause'] {
display: inline-block;
}
// Change icons on state change
.plyr--muted .plyr__control .icon--muted,
.plyr--captions-active .plyr__control .icon--captions-on {
display: block;
& + svg {
display: none;
}
}
// Some options are hidden by default
.plyr [data-plyr='captions'],
.plyr [data-plyr='pip'],
.plyr [data-plyr='airplay'],
.plyr [data-plyr='fullscreen'] {
display: none;
}
.plyr--captions-enabled [data-plyr='captions'],
.plyr--pip-supported [data-plyr='pip'],
.plyr--airplay-supported [data-plyr='airplay'],
.plyr--fullscreen-enabled [data-plyr='fullscreen'] {
display: inline-block;
}
// Menus
// --------------------------------------------------------------
.plyr__menu {
position: relative;
// Hide tooltip
.plyr__control svg {
transition: transform 0.3s ease;
}
.plyr__control[aria-expanded='true'] {
svg {
transform: rotate(45deg);
}
.plyr__tooltip {
display: none;
}
}
// The actual menu container
&__container {
position: absolute;
z-index: 1;
bottom: 100%;
right: -3px;
margin-bottom: 10px;
animation: plyr-popup 0.2s ease;
background: @plyr-menu-bg;
border-radius: 4px;
box-shadow: 0 1px 2px fade(#000, 20%);
white-space: nowrap;
text-align: left;
color: @plyr-menu-color;
font-size: @plyr-font-size-small;
> div {
overflow: hidden;
transition: height 0.35s cubic-bezier(0.4, 0, 0.2, 1), width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
// Arrow
&::after {
content: '';
position: absolute;
top: 100%;
right: 15px;
height: 0;
width: 0;
border: 4px solid transparent;
border-top-color: @plyr-menu-bg;
}
ul {
margin: 0;
padding: @plyr-control-padding;
list-style: none;
overflow: hidden;
}
// Options
.plyr__control {
display: flex;
align-items: center;
width: 100%;
padding: ceil(@plyr-control-padding / 2) (@plyr-control-padding * 2);
color: @plyr-menu-color;
font-weight: @plyr-font-weight-bold;
user-select: none;
&::after {
content: '';
position: absolute;
top: 50%;
transform: translateY(-50%);
border: 4px solid transparent;
transition: border-color 0.2s ease;
}
&--forward {
padding-right: ceil(@plyr-control-padding * 4);
&::after {
right: 5px;
border-left-color: fade(@plyr-menu-color, 80%);
}
&.tab-focus::after,
&:hover::after {
border-left-color: currentColor;
}
}
&--back {
position: relative;
@horizontal-padding: (@plyr-control-padding * 2);
width: ~'calc(100% - @{horizontal-padding})';
margin: @plyr-control-padding;
margin-bottom: floor(@plyr-control-padding / 2);
padding-left: ceil(@plyr-control-padding * 4);
font-weight: @plyr-font-weight-normal;
&::after {
left: @plyr-control-padding;
border-right-color: fade(@plyr-menu-color, 80%);
}
&::before {
content: '';
position: absolute;
top: 100%;
left: 0;
right: 0;
height: 1px;
overflow: hidden;
margin-top: ceil(@plyr-control-padding / 2);
background: fade(#000, 15%);
box-shadow: 0 1px 0 fade(#fff, 10%);
}
&.tab-focus::after,
&:hover::after {
border-right-color: currentColor;
}
}
}
label.plyr__control {
padding-left: ceil(@plyr-control-padding * 2.5);
input[type='radio'] {
position: relative;
left: -@plyr-control-padding;
}
}
// Option value
.plyr__menu__value {
display: flex;
align-items: center;
margin-left: auto;
padding-left: ceil(@plyr-control-padding * 3.5);
pointer-events: none;
overflow: hidden;
font-weight: @plyr-font-weight-normal;
.plyr__badge {
font-weight: @plyr-font-weight-bold;
}
}
}
}
// Badge
// --------------------------------------------------------------
.plyr__badge {
padding: 1px 4px;
border-radius: 2px;
background: @plyr-menu-color;
color: @plyr-menu-bg;
font-size: 10px;
}
// Tooltips
// --------------------------------------------------------------
.plyr__tooltip {
position: absolute;
z-index: 2;
bottom: 100%;
margin-bottom: (@plyr-tooltip-padding * 2);
padding: @plyr-tooltip-padding (@plyr-tooltip-padding * 1.5);
pointer-events: none;
opacity: 0;
background: @plyr-tooltip-bg;
border-radius: @plyr-tooltip-radius;
box-shadow: 0 1px 2px fade(#000, 10%);
color: @plyr-tooltip-color;
font-size: @plyr-font-size-small;
font-weight: @plyr-font-weight-normal;
line-height: 1.3;
transform: translate(-50%, 10px) scale(0.8);
transform-origin: 50% 100%;
transition: transform 0.2s 0.1s ease, opacity 0.2s 0.1s ease;
&::before {
// Arrows
content: '';
position: absolute;
width: 0;
height: 0;
left: 50%;
transform: translateX(-50%);
// The background triangle
bottom: -@plyr-tooltip-arrow-size;
border-right: @plyr-tooltip-arrow-size solid transparent;
border-top: @plyr-tooltip-arrow-size solid @plyr-tooltip-bg;
border-left: @plyr-tooltip-arrow-size solid transparent;
z-index: 2;
}
}
.plyr .plyr__control:hover .plyr__tooltip,
.plyr .plyr__control.tab-focus .plyr__tooltip,
.plyr__tooltip--visible {
opacity: 1;
transform: translate(-50%, 0) scale(1);
}
.plyr .plyr__control:hover .plyr__tooltip {
z-index: 3;
}
// First tooltip
.plyr__controls > .plyr__control:first-child .plyr__tooltip,
.plyr__controls > .plyr__control:first-child + .plyr__control .plyr__tooltip {
left: 0;
transform: translate(0, 10px) scale(0.8);
transform-origin: 0 100%;
&::before {
left: (@plyr-control-icon-size / 2) + @plyr-control-padding;
}
}
// Last tooltip
.plyr__controls > .plyr__control:last-child .plyr__tooltip {
right: 0;
transform: translate(0, 10px) scale(0.8);
transform-origin: 100% 100%;
&::before {
left: auto;
right: (@plyr-control-icon-size / 2) + @plyr-control-padding;
transform: translateX(50%);
}
}
.plyr__controls > .plyr__control:first-child,
.plyr__controls > .plyr__control:first-child + .plyr__control,
.plyr__controls > .plyr__control:last-child {
&:hover .plyr__tooltip,
&.tab-focus .plyr__tooltip,
.plyr__tooltip--visible {
transform: translate(0, 0) scale(1);
}
}
// Playback progress
// --------------------------------------------------------------
// <progress> element
.plyr__progress {
position: relative;
display: none;
flex: 1;
input[type='range'] {
position: relative;
z-index: 2;
}
// Seek tooltip to show time
.plyr__tooltip {
left: 0;
}
}
.plyr .plyr__progress {
display: inline-block;
}
.plyr__progress--buffer {
position: absolute;
left: 0;
top: 50%;
width: 100%;
height: @plyr-range-track-height;
margin: -(@plyr-range-track-height / 2) 0 0;
padding: 0;
background: transparent;
border: none;
border-radius: 100px;
// WebKit
-webkit-appearance: none;
&::-webkit-progress-bar {
background: transparent;
}
&::-webkit-progress-value {
background: currentColor;
border-radius: 100px;
min-width: @plyr-range-track-height;
}
// Mozilla
&::-moz-progress-bar {
background: currentColor;
border-radius: 100px;
min-width: @plyr-range-track-height;
}
// Microsoft
&::-ms-fill {
border-radius: 100px;
}
}
.plyr__progress--buffer {
&::-webkit-progress-value {
transition: width 0.2s ease;
}
&::-moz-progress-bar {
transition: width 0.2s ease;
}
&::-ms-fill {
transition: width 0.2s ease;
}
}
.plyr--video .plyr__progress--buffer {
box-shadow: 0 1px 1px fade(#000, 15%);
color: @plyr-video-progress-buffered-bg;
}
.plyr--audio .plyr__progress--buffer {
color: @plyr-audio-progress-buffered-bg;
}
// Loading state
.plyr--loading .plyr__progress--buffer {
animation: plyr-progress 1s linear infinite;
background-size: @plyr-progress-loading-size @plyr-progress-loading-size;
background-repeat: repeat-x;
background-image: linear-gradient(
-45deg,
@plyr-progress-loading-bg 25%,
transparent 25%,
transparent 50%,
@plyr-progress-loading-bg 50%,
@plyr-progress-loading-bg 75%,
transparent 75%,
transparent
);
color: transparent;
}
.plyr--video.plyr--loading .plyr__progress--buffer {
background-color: @plyr-video-progress-buffered-bg;
}
.plyr--audio.plyr--loading .plyr__progress--buffer {
background-color: @plyr-audio-progress-buffered-bg;
}
// Time
// --------------------------------------------------------------
.plyr__time {
display: inline-block;
vertical-align: middle;
font-size: @plyr-font-size-small;
}
// Media duration hidden on small screens
.plyr__time + .plyr__time {
display: none;
@media (min-width: @plyr-bp-screen-md) {
display: inline-block;
}
// Add a slash in before
&::before {
content: '\2044';
margin-right: @plyr-control-spacing;
}
}
.plyr--video .plyr__time {
text-shadow: 0 1px 1px fade(#000, 15%);
}
// Volume
// --------------------------------------------------------------
.plyr__volume {
display: none;
}
.plyr .plyr__volume {
flex: 1;
position: relative;
input[type='range'] {
position: relative;
z-index: 2;
}
@media (min-width: @plyr-bp-screen-sm) {
display: block;
max-width: 60px;
}
@media (min-width: @plyr-bp-screen-md) {
max-width: 100px;
}
}
// 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
.plyr--is-ios .plyr__volume,
.plyr--is-ios [data-plyr='mute'] {
display: none !important;
}
// Fullscreen
// --------------------------------------------------------------
.plyr:fullscreen {
.plyr-fullscreen-active();
}
.plyr:-webkit-full-screen {
.plyr-fullscreen-active();
}
.plyr:-moz-full-screen {
.plyr-fullscreen-active();
}
.plyr:-ms-fullscreen {
.plyr-fullscreen-active();
}
// Fallback for unsupported browsers
.plyr--fullscreen-fallback {
.plyr-fullscreen-active();
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10000000;
}

View File

@ -0,0 +1,31 @@
// --------------------------------------------------------------
// Fullscreen
// --------------------------------------------------------------
.plyr:fullscreen {
.plyr-fullscreen-active();
}
.plyr:-webkit-full-screen {
.plyr-fullscreen-active();
}
.plyr:-moz-full-screen {
.plyr-fullscreen-active();
}
.plyr:-ms-fullscreen {
.plyr-fullscreen-active();
}
// Fallback for unsupported browsers
.plyr--fullscreen-fallback {
.plyr-fullscreen-active();
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 10000000;
}

View File

@ -0,0 +1,33 @@
// --------------------------------------------------------------
// Hiding content nicely
// --------------------------------------------------------------
// Attributes
.plyr--full-ui [hidden] {
display: none;
}
.plyr--full-ui [aria-hidden='true'] {
display: none;
}
// Screen reader only elements
.plyr__sr-only {
clip: rect(1px, 1px, 1px, 1px);
overflow: hidden;
// !important is not always needed
& when(@plyr-sr-only-important = true) {
position: absolute !important;
padding: 0 !important;
border: 0 !important;
height: 1px !important;
width: 1px !important;
}
& when(@plyr-sr-only-important = false) {
position: absolute;
padding: 0;
border: 0;
height: 1px;
width: 1px;
}
}