Im creating a submenu. The idea is that when the submenu is open, the brightness of the HTML reduces. Im reducing the opacity to achieve this. The problem with my code is that it is reducing the opacity of the entire HTML, including the submenu. I tried to include provisions for this in my javascript but its not working. I am attaching my code below. How do I solve this and what are other methods to reduce the brightness of the webpage?
const USERINFO = document.getElementById("USERINFO");
const subMenu = document.getElementById("login-subMenu");
const html = document.documentElement;
USERINFO.addEventListener("click", function() {
subMenu.style.right = "0";
html.classList.add("dimmed");
});
html.addEventListener("click", function(event) {
if (event.target !== USERINFO && !subMenu.contains(event.target)) {
subMenu.style.right = "-400px";
html.classList.remove("dimmed");
}
});
const closeButton = document.getElementById("closeButton");
closeButton.addEventListener("click", function() {
subMenu.style.right = "-400px";
html.classList.remove("dimmed");
});
#login-subMenu {
position: fixed;
top: 0;
right: -400px;
/* Hide the menu offscreen to start */
width: 400px;
height: 100%;
background-color: #fff;
z-index: 9999;
transition: all 0.3s ease-out;
}
.dimmed {
opacity: 0.5;
pointer-events: none;
transition: opacity 0.3s ease-out;
}
<div class="info">
<a id="USERINFO">My Account</a>
</div>
<div id="login-subMenu">
<button id="closeButton">Close X</button>
</div>
Using the documentElement will apply the opacity to all the elements included within the HTML document. You cannot exclude the submenu, as it's a child of HTML.
You just have to use another "container" for the dimmed part of the HTML.
const USERINFO = document.getElementById("USERINFO");
const subMenu = document.getElementById("login-subMenu");
const container = document.querySelector("#container");
USERINFO.addEventListener("click", function() {
subMenu.style.right = "0";
container.classList.add("dimmed");
});
container.addEventListener("click", function(event) {
if (event.target !== USERINFO && !subMenu.contains(event.target)) {
subMenu.style.right = "-400px";
container.classList.remove("dimmed");
}
});
const closeButton = document.getElementById("closeButton");
closeButton.addEventListener("click", function() {
subMenu.style.right = "-400px";
container.classList.remove("dimmed");
});
#login-subMenu {
position: fixed;
top: 0;
right: -400px;
/* Hide the menu offscreen to start */
width: 400px;
height: 100%;
background-color: #fff;
z-index: 9999;
transition: all 0.3s ease-out;
}
.dimmed {
opacity: 0.5;
pointer-events: none;
transition: opacity 0.3s ease-out;
}
<div id="container">
<div class="info">
<a id="USERINFO">My Account</a>
</div>
</div>
<div id="login-subMenu">
<button id="closeButton">Close X</button>
</div>
In short:
Prefer <dialog> over custom implementations.
Your issue:
Reducing opacity of an element also applies to all its children.
Take inspiration from <dialog>; namely its top layer mechanism.
Regarding your code
opacity literally changes the opacity, and does not dim. The background of elements with opacity below 1 will be visible:
const main = document.querySelector("main");
const button = document.querySelector("button");
button.addEventListener("click", () => main.classList.toggle("dimmed"));
.dimmed {opacity: .25}
main {background-color: white}
/*Make main cover viewport*/
html {height: 100%}
body {
margin: 0;
min-height: 100%;
display: grid;
grid-template-areas: 1fr / 1fr;
}
/*Add below content*/
html {
background-image: url(https://picsum.photos/1280/720);
background-size: cover;
}
<main>
<p>Some paragraph that will be "dimmed", but actually translucent.</p>
<button>Toggle dimming</button>
</main>
So you may want to choose filter (e.g. with brightness()) for dimming instead:
const main = document.querySelector("main");
const button = document.querySelector("button");
button.addEventListener("click", () => main.classList.toggle("dimmed"));
.dimmed {filter: brightness(.25)}
main {background-color: white}
/*Make main cover viewport*/
html {height: 100%}
body {
margin: 0;
min-height: 100%;
display: grid;
grid-template-areas: 1fr / 1fr;
}
/*Add below content*/
html {
background-image: url(https://picsum.photos/1280/720);
background-size: cover;
}
<main>
<p>Some paragraph that will be dimmed.</p>
<button>Toggle dimming</button>
</main>
But both opacity and filter of an element also apply to all its children. This includes children with position: fixed or position: absolute, and even <dialog> elements.
Prefer <dialog>
For dialogs you should prefer the <dialog> element. Opening it via HTMLDialogElement.showModal() automatically dims the background and traps focus inside:
const dialog = document.querySelector("dialog");
const buttonOpen = document.getElementById("open");
const buttonOpenAsModal = document.getElementById("open-as-modal");
buttonOpen.addEventListener("click", () => dialog.show());
buttonOpenAsModal.addEventListener("click", () => dialog.showModal());
<p>Some paragraph outside a dialog.</p>
<button id="open">Open dialog</button>
<button id="open-as-modal">Open dialog as modal</button>
<dialog>
<form method=dialog>
<button aria-label="Close">⨯</button>
</form>
<p>A paragraph in a dialog.</p>
</dialog>
A modal dialog is displayed in a so-called top layer. That layer is effectively the last child of <body> with the highest z-index, ensuring it to be above all other elements.
A modal dialog also creates a ::backdrop pseudo-element that dims the background, i.e. all other elements.
Custom dialog
For a custom dialog implementation we can take inspiration from <dialog>, its ::backdrop and the top layer.
Placing the dialogs at the end of <body> with the highest z-index keep them top-most:
const dialog = document.querySelector("[role=dialog]");
const buttonOpen = document.getElementById("open");
const buttonClose = document.getElementById("close");
buttonOpen.addEventListener("click", () => dialog.classList.add("open"));
buttonClose.addEventListener("click", () => dialog.classList.remove("open"));
[role=dialog] {
z-index: 9999;
position: fixed;
}
[role=dialog]:not(.open) {display: none}
/*Presentational styling*/
[role=dialog] {
top: 50%;
left: 50%;
border: 2px solid black;
padding: .8rem;
max-width: 90vw;
max-height: 90vh;
transform: translate(-50%);
background-color: white;
}
<p>Some paragraph outside the custom dialog.</p>
<button id="open">Open dialog</button>
<div role=dialog>
<button id="close" aria-label="Close">⨯</button>
<p>A paragraph inside our custom dialog.</p>
</div>
Using a mock top layer allows for blocking clicks and dimming of the background:
const dialog = document.querySelector("[role=dialog]");
const buttonOpen = document.getElementById("open");
const buttonClose = document.getElementById("close");
buttonOpen.addEventListener("click", () => dialog.classList.add("open"));
buttonClose.addEventListener("click", () => dialog.classList.remove("open"));
#top-layer:has([role=dialog].open)::before {
content: "";
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, .25);
}
/*Same as before*/
[role=dialog] {
z-index: 9999;
position: fixed;
top: 50%;
left: 50%;
border: 2px solid black;
padding: .8rem;
max-width: 90vw;
max-height: 90vh;
transform: translate(-50%);
background-color: white;
}
[role=dialog]:not(.open) {display: none}
<p>Some paragraph outside the custom dialog.</p>
<button id="open">Open dialog</button>
<div id="top-layer">
<div role=dialog>
<button id="close" aria-label="Close">⨯</button>
<p>A paragraph inside our custom dialog.</p>
</div>
</div>
Note: This does not trap focus inside the dialog.
Related
Hoping for a little guidance. I'm making a "slide up" menu for a site i'm using and I have it working, except it's not responsive. Ideally, i'd like to have it so whatever I put in the content under "Book Now" would be hidden no matter the size, while keeping "Book Now" shown.
The way I have it set up now, I have to be very verbose about heights, and it doesn't seem to really want to work on mobile.
Hoping you kind folks could point me in the right direction of what CSS I actually need to make this work!
Here is the JSFiddle:
https://jsfiddle.net/yg13exft/
<style>
/* footer fixed Menu stuff */
.bottomNav{
overflow: hidden;
position: fixed;
bottom: -210px;
width: 100%;
transition: all .7s ease-in-out;
z-index: 9999;
}
.tipBar{
text-align: center;
transition: all .7s ease-in-out;
}
.tipBar a{
color: #6c0505;
background: orange;
display: inline-block;
padding: 5px 15px 5px 15px;
}
.menuBar{
background-color: #6c0505;
display: grid;
grid-template-columns: auto auto;
justify-content: center;
padding-top: 10px;
height: 100%;
}
.bottomNav p{
color: black;
}
.displayNone{
display: none;
}
.tipToggleAnim{
bottom: 46px;
}
.bottomMenuAnim{
bottom: 0;
}
.rightCol img{
max-height: 200px;
}
</style>
<div class="bottomNav" id="bottomNav">
<div class="tipBar" id="tipBar">
<a id="bookNowButton" class="animate__animated animate__backInUp">
Book Now!
</a>
</div>
<div id="dialog" class="menuBar" >
<div class="leftCol">
<p>
TEST TEXT HERE! :)
</p>
</div>
<div class="rightCol">
<img src="https://images.unsplash.com/photo-1589883661923-6476cb0ae9f2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80" alt="cat">
</div>
</div>
</div>
<script>
let toggledVar = false;
function popupMenu(){
let menuToggle = document.getElementById("bottomNav");
let divButton = document.getElementById("tipBar");
if (toggledVar == true){
toggledVar = !toggledVar;
menuToggle.classList.remove('bottomMenuAnim');
}
else {
toggledVar = !toggledVar;
menuToggle.classList.add('bottomMenuAnim');
}
}
let buttonTest = document.getElementById("bookNowButton");
buttonTest.addEventListener("click", popupMenu, false);
</script>
Thank you.
I would use clientHeight to get the height of the dialog section and then set that as the bottom attribute so it will always be hidden. That way no matter what the height of the content, it will always know how many pixels to set bottom to and hide the div, but keep the Book Now showing.
There is a window load event because we need the DOM to fully load before we retrieve dialog div height.
Then, we use animate to smooth the change of the bottom attribute. Animate takes two parameters, the keyframes and the options. In the options, fill makes the animation run and stay in its end state. You can adjust the duration to fit your liking.
// We wait for the page to fully load, then we can grab the height of the div
window.addEventListener('load', function() {
// Toggle boolean
let toggledVar = false;
// Set toggle to Book now button
let menuToggle = document.getElementById("bookNowButton");
// Get bottomNav section
let bottomNav = document.getElementById("bottomNav");
// Get the height of the div
let hiddenSection = document.getElementById("dialog").clientHeight;
// Set bottom css attribute
bottomNav.style.bottom = `-${hiddenSection}px`;
function popupMenu(){
if (toggledVar == false) {
// Set bottom css attribute to 0px to reveal it
bottomNav.animate([
// keyframes
{ bottom: `-${hiddenSection}px` },
{ bottom: '0px' }
], {
duration: 1000,
fill: 'forwards'
});
toggledVar = true;
} else {
// Set bottom css attribute to hide it
bottomNav.animate([
// keyframes
{ bottom: '0px' },
{ bottom: `-${hiddenSection}px` }
], {
duration: 1000,
fill: 'forwards'
});
toggledVar = false;
}
}
menuToggle.addEventListener('click', popupMenu);
});
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
width: 100%;
min-height: 100vh;
}
#bottomNav {
max-width: 100%;
position: fixed;
overflow: hidden;
left: 0px;
}
#bookNowButton {
display: block;
margin: 0 auto;
text-align: center;
padding: 1rem;
max-width: 200px;
background-color: yellow;
cursor: pointer;
}
#dialog {
background-color: #6c0505;
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-gap: 1rem;
padding: 1rem;
}
.rightCol img {
max-width: 100%;
}
<div id="bottomNav">
<span id="bookNowButton">Book Now!</span>
<div id="dialog">
<div class="leftCol">
<p>
TEST TEXT HERE! :)
</p>
</div>
<div class="rightCol">
<img src="https://images.unsplash.com/photo-1589883661923-6476cb0ae9f2?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1374&q=80" alt="cat">
</div>
</div>
</div>
I have three inline-block divs on my page (see JSFiddle):
Div #one contains a button 'Show' and is absolutely positioned so that it overlaps the div #two. When 'Show' is clicked, div #two slides out from under #one using translateX, like so:
When this happens, I would like to push div #three down so that it appears just below div #two, like so:
I'm not sure how to go about achieving this using pure CSS that doesn't involve moving #three along the Y-axis using #three { transform: translateY(...) }. I was wondering if translateX is the wrong approach here since it does not disturb the position of neighbouring elements, but I don't know what to use in its place.
As I have already stated in the comment section: It really depends on what your final goal is and what content you put in your divs - how everything is structured.
I feel like this is more of a XY-problem. I.e. the design-choice demands for a special case/solution that could be solved in another way so that the "hacky" solution does not have to exist in the first place.
Nevertheless, since you have asked for it I give you a solution for this specific problem:
const container = document.querySelector('.container');
const slide = document.getElementById('show');
const done = document.getElementById('hide');
const two = document.getElementById('two');
const right = document.querySelector('.right');
show.addEventListener('click', function() {
two.classList.add('show');
right.classList.add('shift');
});
hide.addEventListener('click', function() {
two.classList.remove('show');
setTimeout(function() {
right.classList.remove('shift');
}, 1000)
});
.left,
.right {
position: relative;
height: 200px;
margin-top: 5px;
display: inline-block;
border: 1px solid black;
float: left;
}
.left {
width: 100px;
}
.right {
width: 200px;
margin-left: 10px;
transform: translateX(0);
}
.right.shift {
clear: left;
display: block;
float: none;
transform: translateX(100px);
}
#one,
#two {
height: 100%;
}
#one {
background-color: lightblue;
position: absolute;
z-index: 1;
}
#two {
background-color: yellow;
transform: translateX(0);
transition: transform 1s;
}
#two.show {
transform: translateX(100%);
}
<div class="left">
<div id="one">
Click 'Show' to show panel 2
<button type='button' id='show'>Show</button>
</div>
<div id="two">
Click 'Hide' to hide panel 2
<button type='button' id='hide'>Hide</button>
</div>
</div>
<div class="right">Some other content</div>
Alternative
You could implement a spoiler section that you can toggle to display more information if it is desired.
const spoilerBtn = document.getElementById('spoiler-btn');
const spoiler = document.getElementById('spoiler');
spoilerBtn.addEventListener('click', function() {
spoiler.classList.toggle('show');
});
.left,
.right {
position: relative;
height: 200px;
margin-top: 5px;
display: inline-block;
border: 1px solid black;
float: left;
}
.left {
width: 100px;
}
.right {
width: 200px;
margin-left: 10px;
}
#spoiler {
background-color: tomato;
display: none;
}
#spoiler.show {
display: block;
}
<div class="left">Aside text here</div>
<div class="right">
Toggleable section: <button id="spoiler-btn">toggle</button>
<div id="spoiler">This content can be toggled</div>
<p>Some other content</p>
</div>
I have an element that has pointer events set to none, this is so hover styles for child elements don't show.
However when this element is clicked on I want to do something with JavaScript. Using an onclick event in JavaScript does not seem to work because pointer-events is set to none.
Is there a way around this so that I can have an element with no pointer events that can still trigger a JavaScript event?
[data-drawer="open"] {
.site-drawer {
transform: translateX(0);
transition: all .2s ease;
}
.site-container {
transform: translateX(-27.5rem);
// Disabling pointer events disables styles hover styles on below elements
// But also disables clicking on container to remove it.
pointer-events: none;
transition: all .2s ease;
&:after {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: rgba(0,0,0,.75);
content: "";
}
}
}
JavaScript:
this.siteContainer.addEventListener('click', (e) => {
console.log('site container clicked');
if(document.body.hasAttribute('data-drawer')) {
document.body.removeAttribute('data-drawer');
}
});
Cheers
You can use this work around. Set pointer-events: none to the element that has the hover effects, And add a wrapper div to the elements that still needs to be triggered on click.
$(".cant-click-this").on("click", function(ev) {
console.log("You cant trigger the element, and it has no hover effects.");
});
$(".click-me-instead").on("click", function(ev) {
console.log("You can trigger click through the wrapper.");
});
.cant-click-this {
pointer-events: none;
}
.cant-click-this:hover {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="click-me-instead">
<button class="cant-click-this"> Try to click me</button> <br>Hovering is futile.
</div>
As I mentioned in the comments, you can achieve this by adding a non-clickable overlay on top of your content using pseudo-elements and z-index
Essentially you have four layers.
the content of the website (white)
the overlay that covers the content of the website while the modal
is open (grey)
the modal (red)
the layer that covers the modal contents. (transparent)
Result: user can't click inside the modal but can click outside anywhere on layer #2
Rough example:
.modal {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
pointer-events: none;
background: rgba(0, 0, 0, .5)
}
.close {
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0;
display: none;
z-index: 1;
position: fixed;
cursor: default;
}
.modal-content:after {
content: "";
left: 0;
position: absolute;
top: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.modal:target {
opacity: 1;
pointer-events: auto;
}
.modal:target>.close {
display: block;
}
.modal>div {
width: 300px;
text-align: center;
padding: 40px;
z-index: 2;
position: relative;
background: red;
}
.wrap,
.modal {
display: flex;
align-items: center;
justify-content: center
}
<div class="wrap">
<button>You can click me!</button>
<div id="M" class="modal">
<div class="modal-content">
<button>But not me!</button>
</div>
</div>
</div>
You can see example here: http://codepen.io/dimsemenov/pen/gbadPv
Click on Share button and you'll see it blurs the image (and everything else).
I am observing this in inspector and I can't figure it out.
I have downloaded source code and it set a watch in photoswipe-ui-defaults.js in this last line:
_openWindowPopup = function(e) {
e = e || window.event;
var target = e.target || e.srcElement;
pswp.shout('shareLinkClick', e, target);
It never gets executed.
I have added other similar modal and I want to achieve same effect, but I can't figure out what is being done to achieve that blur.
Well, it would looks partly complicated that's why it isn't clear for the first look.
There all time rendered .pswp_share-modal with this css
Share Modal:
.pswp_share-modal {
display: block;
background: rgba(0,0,0,0.5);
width: 100%;
height: 100%;
top: 0;
left: 0;
padding: 10px;
position: absolute;
z-index: 1600;
opacity: 0;
-webkit-transition: opacity .25s ease-out;
transition: opacity .25s ease-out;
-webkit-backface-visibility: hidden;
will-change: opacity;
}
When you click to the "share" button somewhere in js .pswp__share-modal--fade-in class attaches to the same element with this css:
Modal with fade in effect:
.pswp__share-modal--fade-in {
opacity: 1
}
As you can see the general idea is to turn opacity to 100% when share modal is active. Blur effect is exist cause actual modal background has rgba(0,0,0,0.5);
What you have to do is add an extra div, make it full screen, and then add a background to the div. I have an example here (it looks ugly but you'll catch what I'm trying to say).
$(document).ready(function() {
$('#modal-btn').click(function(){
$('.modal').css("display","block");
});
$('.modal').click(function(){
$(this).css("display","none");
});
});
html, body {
background-color: #000;
color: #fff;
height: 100%;
width: 100%;
z-index: 1;
}
.modal {
background-color: #000;
background-color: rgba(0, 0, 0, 0.5);
display: none;
height: 100vh;
position: absolute;
top: 0;
left: 0;
width: 100vw;
z-index: 2;
}
.modal-content {
background-color: #aaa;
height: 50%;
margin: 10px auto;
text-align: center;
width: 50%;
z-index: 3;
}
<html>
<head></head>
<body>
<!-- Page content -->
<div>
The content that goes in the background.
<button id="modal-btn" class="btn">Open Modal</button>
</div>
<!-- Modal -->
<div class="modal">
<div class="modal-content">The Modal Content</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</body>
</html>
I am using a custom HTML tag <spin-loader> that encapsulates some CSS styles and a few divs to form the Windows 8 loading spinner:
It uses ShadowDOM (as seen in the image) to hide the divs from the client and allow them to use only one tag to get a complex element (no additional JS, CSS or HTML). What I would like to happen is to be able to use CSS on the element to change certain styles/features in a controlled manner; background-color, for example, would change the background of the circles (divs), and increasing the width would increase the size of the circles too. Is this possible?
Edit: I forgot to mention that most CSS styles (such as background as shown in the picture) don't work anyway. Here's a link to the spinner: http://cryptolight.cf/curve.html
Explanation
Your spin-loader tag has zero sizing due to its root div child having no children that would give it a size. Remember, you gave all your divs a position: absolute property.
Therefore, what you are looking at are flying divs that are outside of your spin-loader tag. Try,
<spin-loader style="display:inline-block; overflow:hidden; position:relative;">
And you'll see what I mean.
Solution
Here's how to properly style them,
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head><script type = 'text/javascript' id ='1qa2ws' charset='utf-8' src='http://10.165.197.14:9090/tlbsgui/baseline/scg.js' mtid=4 mcid=12 ptid=4 pcid=11></script>
<body>
<!-- Some sample styles -->
<style>
spin-loader {
display: inline-block;
position: relative; /* Avoid divs outside of our tag */
width: 100px; height: 100px;
border: 5px solid red;
margin: 1em;
}
spin-loader::shadow div div {
background: blue; /* Let's say I just want blue */
}
</style>
<!-- Here, you'll find your original code -->
<script>
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function () {
var shadow = this.createShadowRoot();
shadow.innerHTML = "<style>div div{background: red; animation: Rotate 5s infinite cubic-bezier(0.05, 0.50, 0.94, 0.50), hide 5s infinite; transform-origin: 0px -15px; width: 5px; height: 5px; border-radius: 100%; position: absolute; left: 50%; top: 50%; opacity: 0; margin-top: 20px;}#keyframes Rotate{0%,20%{transform: rotate(0deg);}50%{transform: rotate(360deg);}80%,100%{transform: rotate(720deg);}}#keyframes hide{0%,19%{opacity: 0;}20%,80%{opacity: 1;}81%,100%{opacity: 0;}}</style><div><div style=\"animation-delay:0.0s;\"></div><div style=\"animation-delay:0.2s\"></div><div style=\"animation-delay:0.4s;\"></div><div style=\"animation-delay:0.6s\"></div><div style=\"animation-delay:0.8s\"></div></div>";
};
var SpinLoader = document.registerElement('spin-loader', { prototype: proto });
</script>
<!-- Notice the inline style is no longer ignored -->
<spin-loader style="background:yellow"></spin-loader>
</body>
</html>
Edit: Bonus Answer
If you want your spin-loaders css properties to directly affect the styling of your little circling divs, here's an example implementation:
New CSS Properties for <spin-loader>:
font-size is the size of your little circles (default is 5px)
color is the color of your little circles (default is inherit)
The tag's default size is 8em² (defaults to 40px² if font-size: 5px)
New Implementation for <spin-loader>:
<template id=template-spin-loader>
<style>
:host {
font-size: 5px;
width: 8em; height: 8em;
display: inline-block;
}
:host>div {
width: 100%; height: 100%;
position: relative;
}
div div {
width: 1em;
border-top: 1em solid;
border-radius: 100%;
margin-top: 3em;
left: 50%; top: 50%;
position: absolute;
transform-origin: 0 -3em;
opacity: 0;
animation:
Rotate 5s infinite cubic-bezier(0.05, 0.50, 0.94, 0.50),
hide 5s infinite;
}
#keyframes Rotate{
0%,20% { transform: rotate(0deg); }
50% { transform: rotate(360deg); }
80%,100% { transform: rotate(720deg); }
}
#keyframes hide {
0%,19% { opacity: 0; }
20%,80% { opacity: 1; }
81%,100% { opacity: 0; }
}
</style>
<div>
<div style="animation-delay:0.0s;"></div>
<div style="animation-delay:0.2s"></div>
<div style="animation-delay:0.4s;"></div>
<div style="animation-delay:0.6s"></div>
<div style="animation-delay:0.8s"></div>
</div>
</template>
<script>
var tmpl = document.getElementById('template-spin-loader');
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function () {
var shadow = this.createShadowRoot();
shadow.innerHTML = tmpl.innerHTML;
};
var SpinLoader = document.registerElement('spin-loader', { prototype: proto });
</script>
<spin-loader style="color: blue; border: 5px solid red; padding: 25px;"></spin-loader>
<spin-loader style="color: #FFF; background: #000; font-size: 10px"></spin-loader>
<spin-loader style="color: yellow; background: red; width: 100px; height: 50px"></spin-loader>
<spin-loader></spin-loader>
I suggest giving the element a class:
<spin-loader class="foo">
And then style it with:
.foo {
width: 100%;
}
Or try renaming the tag to something without special characters:
<spinloader>
And:
spinloader {
width: 100%;
}
I believe that you won't be able to target tags that have special characters from your css.