Pseudo-element and pseudo-class in component - css

I'm trying to style a native component.
These two work:
:host::-webkit-scrollbar-thumb {}
:host(:hover) {}
but I don't know how to fix the following one:
:host::-webkit-scrollbar-thumb:hover {}
I tried to put the parentheses in different places to no avail.
EDIT: SAMPLE CODE
The sample code below uses the Shadow DOM and the styles are attached to it.
This is only supported in Chrome, which is not a problem for me since I'm writing an Electron app.
Note that
:host::-webkit-scrollbar-thumb:hover {
background: black;
}
doesn't work, while
<style>
#elem::-webkit-scrollbar-thumb:hover {
background: black;
}
</style>
does.
The last one is a workaround as it breaks encapsulation. In a complex app built from components, that's highly undesirable.
Here's the sample code WHICH WORKS ONLY IN CHROME:
JSFiddle
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<style>
#elem::-webkit-scrollbar-thumb:hover {
background: black;
}
</style>
<script>
const css = `
:host {
position: absolute;
overflow: auto;
left: 20px;
top: 20px;
width: 200px;
height: 50px;
}
:host::-webkit-scrollbar {
width: 10px;
background-color: rgb(36, 106, 153);
}
:host::-webkit-scrollbar-track {
background-color: rgb(36, 106, 153);
border-radius: 4px;
}
:host::-webkit-scrollbar-thumb {
background: linear-gradient(rgb(253, 253, 134), rgb(165, 224, 243));
border-radius: 4px;
border: solid 1px rgb(6, 115, 193);
}
:host::-webkit-scrollbar-thumb:hover {
background: black;
}
`;
function f() {
const span = document.createElement('span');
span.append('fdsasdfafsdafsdafdsadfsadfsadfsadfsafdsadsadasdsa');
const root = document.createElement('div');
root.append(span);
root.id = 'elem';
const shadowRoot = root.attachShadow({ mode: 'open' });
shadowRoot.append(...root.childNodes);
const styleSheet = new CSSStyleSheet;
styleSheet.replaceSync(css);
shadowRoot.adoptedStyleSheets = [styleSheet];
const body = document.getElementsByTagName('body')[0];
body.appendChild(root);
}
window.onload = () => {
f();
};
</script>
</head>
<body></body>
</html>

:host selects the host of the shadowDOM. Maybe instead of applying styles on the host through the shadowDOM, try directly applying the css to the element the normal way.
So if your host is called .someElement, then .someElement::-webkit-scrollbar-thumb:hover should work. Or just see if you're able to change all scrollbar-thumbs with *::-webkit-scrollbar-thumb:hover

The best solution I could come up with is to avoid :host altogether by wrapping the content of the component in an additional div so that that can be regarded as a virtual root, and we can apply the styles to that instead of the real root.
Encapsulation is preserved and everything works just fine. We just have a redundant div.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
<script>
const css = `
#virtroot {
position: absolute;
overflow: auto;
left: 20px;
top: 20px;
width: 200px;
height: 50px;
}
#virtroot::-webkit-scrollbar {
width: 10px;
background-color: rgb(36, 106, 153);
}
#virtroot::-webkit-scrollbar-track {
background-color: rgb(36, 106, 153);
border-radius: 4px;
}
#virtroot::-webkit-scrollbar-thumb {
background: linear-gradient(rgb(253, 253, 134), rgb(165, 224, 243));
border-radius: 4px;
border: solid 1px rgb(6, 115, 193);
}
#virtroot::-webkit-scrollbar-thumb:hover {
background: black;
}
`;
function f() {
const span = document.createElement('span');
span.append('fdsasdfafsdafsdafdsadfsadfsadfsadfsafdsadsadasdsa');
const root = document.createElement('div');
const div = document.createElement('div');
root.append(div);
div.append(span);
div.id = 'virtroot';
const shadowRoot = root.attachShadow({ mode: 'open' });
shadowRoot.append(...root.childNodes);
const styleSheet = new CSSStyleSheet;
styleSheet.replaceSync(css);
shadowRoot.adoptedStyleSheets = [styleSheet];
const body = document.getElementsByTagName('body')[0];
body.appendChild(root);
}
window.onload = () => {
f();
};
</script>
</head>
<body></body>
</html>

Related

How to style VideoJS with Next.js

I am building a react video component based on VideoJS and I used to style VideoJS player using a stylesheet of mine but since I import it as recommended by Next.js documentation, some class targeting seem not to work properly and my custom CSS does not apply to .video-js css components.
This works:
.video {
font-family: 'Inter', -apple-system, Helvetica;
font-weight: bold;
}
.video *:before {
text-shadow: 1px 1px 7px rgba(10, 10, 10, 0.5);
}
This doesn't work:
/* Big play button */
.video .vjs-big-play-button {
height: 2em;
width: 2em;
font-size: 5em;
line-height: 2em;
border: none !important;
border-radius: 9999px;
}
My VideoPlayer component:
import { useCallback, useEffect, useState } from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css'
import styles from '../styles/video-player.module.css';
function VideoPlayer(props) {
const [videoEl, setVideoEl] = useState(null);
const onVideo = useCallback((el) => {
setVideoEl(el)
}, [])
useEffect(() => {
if (videoEl == null) return
const player = videojs(videoEl, props)
return () => {
player.dispose()
}
}, [props, videoEl])
return (
<div data-vjs-player>
<video className={`video-js ${styles.video} vjs-big-play-centered`} ref={onVideo}/>
</div>
)
}
export default VideoPlayer;
As I mentioned, I used to style video.js player this way and it always worked perfectly until I switched to Next.js. Even stranger, the .video class doesn't appear in the browser's developer tools when inspecting the page.
Is there a way I could apply my custom styling properly with Next.js ?
So after looking for a workaround, I found that styling my custom video component in my global.scss file would actually work. I don't particularly know why specifically but here's how you can do:
This is my global.scss file:
/* Base styling */
/* .class { ... } */
/* VideoJS styling -> */
.video-js.video {
* {
& :before {
text-shadow: 1px 1px 7px rgba(10, 10, 10, 0.5);
}
}
&:hover {
.vjs-big-play-button {
background-color: rgba(255, 255, 255, 1);
}
}
.vjs-big-play-button {
height: initial;
width: initial;
font-size: 5em;
line-height: 6.15rem;
padding: 1em;
border: none;
border-radius: 9999px;
background-color: rgba(255, 255, 255, 0.8);
& :before {
margin: 0;
padding: 0;
}
}
.vjs-control-bar {
width: 90%;
min-height: 5em;
margin: 2rem auto;
padding: 0 1em;
border-radius: 1em;
}
}
So you won't have to import '../styles/video-player/module.scss' in VideoPlayer React component

How to style :root without !important using proper specificity

Inside a Custom Element because border-color is set on the parent page, I can not make border-color work without resorting to !important
:host([player="O"]) {
color: var(--color2);
border-color: var(--color2) !important;
}
The selector works fine, the color is set,
so it is a Specificity issue
Question: Is it possible without !important ?
Working snipppet:
window.customElements.define('game-toes', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({
mode: 'open'
});
shadowRoot.innerHTML = 'Toes';
shadowRoot.appendChild(document.querySelector('#Styles').content.cloneNode(true));
}
});
:root {
--boardsize: 40vh;
--color1: green;
--color2: red;
}
game-toes {
width: var(--boardsize);
height: var(--boardsize);
border: 10px solid grey;
background: lightgrey;
display: inline-block;
}
<TEMPLATE id="Styles">
<STYLE>
:host {
display: inline-block;
font-size:2em;
}
:host([player="X"]) {
color: var(--color1);
border-color: var(--color1);
}
:host([player="O"]) {
color: var(--color2);
border-color: var(--color2) !important;
}
</STYLE>
</TEMPLATE>
<game-toes player="X"></game-toes>
<game-toes player="O"></game-toes>
qomponents
You are using CSS variable so you can still rely on them like this:
window.customElements.define('game-toes', class extends HTMLElement {
constructor() {
super();
let shadowRoot = this.attachShadow({
mode: 'open'
});
shadowRoot.innerHTML = 'Toes';
shadowRoot.appendChild(document.querySelector('#Styles').content.cloneNode(true));
}
});
:root {
--boardsize: 40vh;
--color1: green;
--color2: red;
}
game-toes {
width: var(--boardsize);
height: var(--boardsize);
border: 10px solid var(--playercolor,grey);
color:var(--playercolor,#000);
background: lightgrey;
display: inline-block;
}
<TEMPLATE id="Styles">
<STYLE>
:host {
display: inline-block;
font-size:2em;
}
:host([player="X"]) {
--playercolor: var(--color1);
}
:host([player="O"]) {
--playercolor: var(--color2);
}
</STYLE>
</TEMPLATE>
<game-toes player="X"></game-toes>
<game-toes player="O"></game-toes>
<game-toes ></game-toes>
As a complement to #Temani excellent answer: it happened because the element CSS style for <games-toes> will supersede the shadow root :host style.
According to Google's presentation:
Outside styles always win over styles defined in shadow DOM. For example, if the user writes the selector fancy-tabs { width: 500px; }, it will trump the component's rule: :host { width: 650px;}

Huge Google Maps Controls (Possible Bug?)

I first noticed that my Google Maps Controls were disproportionally large on my own web app (seen below).
Initially I thought some of my CSS was playing with Google's CSS on the controls; however, visiting Google's own webpage told me this incident was not isolated to me...
Below is a map on their documentation: https://developers.google.com/maps/documentation/javascript/examples/control-positioning
The large controls appear on every page of their documentation for me as well. I tried different machines and different browsers (Chrome and Firefox).
I also tried other sites that used the Google Maps API and saw a similar phenomenon in some cases.
Is anyone else experiencing the same issues?
Looks like google have now acknowledged this and have provided a (currently un-documented) feature to change the UI scaling by passing in a "controlSize" when creating the map.
See comment from Google here.
JSFiddle here (from comment above).
Sample code:
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8,
controlSize: 32,
});
}
Note: 40 is the default currently (and corresponds to the large controls that this question is about). I've found 25 to be about the same as the previous controls.
Update:
As of v3.36 this is a documented feature, see here
Turns out this isn't a bug. See more here:
Aug 13, 2018 03:56PM Reported Issue Google Maps JavaScript API weekly
channel (3.34) will be using the larger control UI.
As we are seeing increases of touch operations on various devices, we
adjusted the control UI to fit for both finger touches and mouse
clicks.
It's possible to opt out of this by loading the API with v=quarterly,
v=3, v=3.33 or v=3.32. Note: requests to retired version will receive
the default channel, see 1.
If you have any requests or other issues concerning the new control UI
please let us know.
1 https://issuetracker.google.com/112519576
Use v=quarterly, v=3, v=3.33 or v=3.32 when loading the API to use smaller controls.
EDIT:
Refer to answer from #Jonny van Beek on how to scale Google map's controls to the size of your choosing.
Refer to answers from #garethdn and #Peter (below) to find out how to replace Google's large controls with your own custom controls.
Refer to #Dutchmanjonny's post (below) for latest and correct solution to this problem.
For those that are reluctant to opt out by specifying older versions of the API, creating custom controls is relatively straight forward. The following will create two button elements to zoom in and out.
defaultMapOptions: google.maps.MapOptions = {
// Hide Google's default zoom controls
zoomControl: false
};
initializeMap(el: HTMLElement, options?: google.maps.MapOptions): google.maps.Map {
let opts = Object.assign({}, this.defaultMapOptions, options);
let map = new google.maps.Map(el, opts);
let zoomControlsDiv = document.createElement('div');
// Add a class to the container to allow you to refine the position of the zoom controls
zoomControlsDiv.classList.add('google-map-custom-zoom-controls');
this.createCustomZoomControls(zoomControlsDiv, map);
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(zoomControlsDiv);
return map;
}
createCustomZoomControls(controlDiv: HTMLDivElement, map: google.maps.Map) {
let zoomInControlUI: HTMLButtonElement = document.createElement('button');
let zoomOutControlUI: HTMLButtonElement = document.createElement('button');
let zoomControls: HTMLButtonElement[] = [zoomInControlUI, zoomOutControlUI];
// List of classes to be applied to each zoom control
let buttonClasses: string[] = ['btn', 'btn-primary', 'btn-sm'];
zoomInControlUI.innerHTML = `&plus;`;
zoomOutControlUI.innerHTML = `−`;
zoomControls.forEach(zc => {
zc.classList.add(...buttonClasses);
controlDiv.appendChild(zc);
});
google.maps.event.addDomListener(zoomInControlUI, 'click', () => map.setZoom(map.getZoom() + 1));
google.maps.event.addDomListener(zoomOutControlUI, 'click', () => map.setZoom(map.getZoom() - 1));
}
let map = this.initializeMap(myGoogleMapContainerElement);
After the backlash, Google has now published an example for how to replace the default (big) controls: https://developers.google.com/maps/documentation/javascript/examples/control-replacement
Here is the code as published by Google:
<!DOCTYPE html>
<html>
<head>
<title>Replacing Default Controls</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.gm-style .controls {
font-size: 28px; /* this adjusts the size of all the controls */
background-color: white;
box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
box-sizing: border-box;
border-radius: 2px;
cursor: pointer;
font-weight: 300;
height: 1em;
margin: 6px;
text-align: center;
user-select: none;
padding: 2px;
width: 1em;
}
.gm-style .controls button {
border: 0;
background-color: white;
color: rgba(0, 0, 0, 0.6);
}
.gm-style .controls button:hover {
color: rgba(0, 0, 0, 0.9);
}
.gm-style .controls.zoom-control {
display: flex;
flex-direction: column;
height: auto;
}
.gm-style .controls.zoom-control button {
font: 0.85em Arial;
margin: 1px;
padding: 0;
}
.gm-style .controls.maptype-control {
display: flex;
flex-direction: row;
width: auto;
}
.gm-style .controls.maptype-control button {
display: inline-block;
font-size: 0.5em;
margin: 0 1px;
padding: 0 6px;
}
.gm-style .controls.maptype-control.maptype-control-is-map .maptype-control-map {
font-weight: 700;
}
.gm-style .controls.maptype-control.maptype-control-is-satellite .maptype-control-satellite {
font-weight: 700;
}
.gm-style .controls.fullscreen-control button {
display: block;
font-size: 1em;
height: 100%;
width: 100%
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon {
border-style: solid;
height: 0.25em;
position:absolute;
width: 0.25em;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen- control-top-left {
border-width: 2px 0 0 2px;
left: 0.1em;
top: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-top-left {
border-width: 0 2px 2px 0;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-top-right {
border-width: 2px 2px 0 0;
right: 0.1em;
top: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-top-right {
border-width: 0 0 2px 2px;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-bottom-left {
border-width: 0 0 2px 2px;
left: 0.1em;
bottom: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-bottom-left {
border-width: 2px 2px 0 0;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-bottom-right {
border-width: 0 2px 2px 0;
right: 0.1em;
bottom: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-bottom-right {
border-width: 2px 0 0 2px;
}
</style>
</head>
<body>
<div id="map"></div>
<!-- Hide controls until they are moved into the map. -->
<div style="display:none">
<div class="controls zoom-control">
<button class="zoom-control-in" title="Zoom In">+</button>
<button class="zoom-control-out" title="Zoom Out">−</button>
</div>
<div class="controls maptype-control maptype-control-is-map">
<button class="maptype-control-map"
title="Show road map">Map</button>
<button class="maptype-control-satellite"
title="Show satellite imagery">Satellite</button>
</div>
<div class="controls fullscreen-control">
<button title="Toggle Fullscreen">
<div class="fullscreen-control-icon fullscreen-control-top-left"></div>
<div class="fullscreen-control-icon fullscreen-control-top-right"></div>
<div class="fullscreen-control-icon fullscreen-control-bottom-left"></div>
<div class="fullscreen-control-icon fullscreen-control-bottom-right"></div>
</button>
</div>
</div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.querySelector('#map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8,
disableDefaultUI: true,
});
initZoomControl(map);
initMapTypeControl(map);
initFullscreenControl(map);
}
function initZoomControl(map) {
document.querySelector('.zoom-control-in').onclick = function() {
map.setZoom(map.getZoom() + 1);
};
document.querySelector('.zoom-control-out').onclick = function() {
map.setZoom(map.getZoom() - 1);
};
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(
document.querySelector('.zoom-control'));
}
function initMapTypeControl(map) {
var mapTypeControlDiv = document.querySelector('.maptype-control');
document.querySelector('.maptype-control-map').onclick = function() {
mapTypeControlDiv.classList.add('maptype-control-is-map');
mapTypeControlDiv.classList.remove('maptype-control-is-satellite');
map.setMapTypeId('roadmap');
};
document.querySelector('.maptype-control-satellite').onclick =
function() {
mapTypeControlDiv.classList.remove('maptype-control-is-map');
mapTypeControlDiv.classList.add('maptype-control-is-satellite');
map.setMapTypeId('hybrid');
};
map.controls[google.maps.ControlPosition.LEFT_TOP].push(
mapTypeControlDiv);
}
function initFullscreenControl(map) {
var elementToSendFullscreen = map.getDiv().firstChild;
var fullscreenControl = document.querySelector('.fullscreen-control');
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(
fullscreenControl);
fullscreenControl.onclick = function() {
if (isFullscreen(elementToSendFullscreen)) {
exitFullscreen();
} else {
requestFullscreen(elementToSendFullscreen);
}
};
document.onwebkitfullscreenchange =
document.onmsfullscreenchange =
document.onmozfullscreenchange =
document.onfullscreenchange = function() {
if (isFullscreen(elementToSendFullscreen)) {
fullscreenControl.classList.add('is-fullscreen');
} else {
fullscreenControl.classList.remove('is-fullscreen');
}
};
}
function isFullscreen(element) {
return (document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement) == element;
}
function requestFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullScreen) {
element.msRequestFullScreen();
}
}
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msCancelFullScreen) {
document.msCancelFullScreen();
}
}
</script>
<script src="https://maps.googleapis.com/maps/api/js? key=YOUR_API_KEY&callback=initMap"
async defer></script>
</body>
</html>
Here is what did it for me:
.gm-bundled-control
,.gm-style-mtc
,.gm-fullscreen-control{
transform: scale(.7);
}
Makes the controls 30% smaller.
I added some css and that's it.
/* Fix +/- zoom buttons design */
#map .gm-bundled-control-on-bottom {
right: 30px !important;
bottom: 116px !important;
}
#map .gm-bundled-control-on-bottom > div:first-child {
top: 44px !important;
}
#map .gmnoprint > .gmnoprint > div {
height: 60px !important;
width: 30px !important;
}
#map .gmnoprint > .gmnoprint > div > div { /* seperator */
width: 22.5px !important;
margin: 0px 3.75px !important;
}
#map .gmnoprint > .gmnoprint button {
width: 30px !important;
height: 30px !important;
}
#map .gmnoprint > .gmnoprint button img {
height: 13.5px !important;
width: 13.5px !important;
margin: 6.75px 8.25px 9.75px !important;
}
and this is for the yellow man button:
/* yellow person button design*/
#map .gm-svpc {
width: 30px !important;
height: 30px !important;
}
#map .gm-svpc img:nth-child(1), #map .gm-svpc img:nth-child(2){
width: 13.5px !important;
height: 22.5px !important;
left: -7px !important;
top: -12px !important;
}
#map .gm-svpc img:nth-child(3) {
width: 24px !important;
height: 30px !important;
}
and for last the MAP|Satellite buttons design
/* MAP|Satellite buttons design*/
#map .gm-style-mtc > div:nth-child(1) {
padding: 0px 9px !important;
height: 30px !important;
font-size: 15px !important;
}
#map .gm-style-mtc > div:nth-child(2) {
top: 30px !important;
}
#map .gm-style-mtc > div:nth-child(2) > div {
padding: 2px 4px 2px 2px !important;
font-size: 14px !important;
}

How to style paper-input with certain mixins (polymer 2)?

I'm trying to style a paper-input based on a design I got. I used some of the custom proprieties described here , but not all of them work.
I have problems using --paper-input-container-label and --paper-input-container-input-focus.
Maybe I try to use them the wrong way or it requires some extra steps.
Here is my code
<link rel="import" href="../polymer/polymer-element.html">
<link rel="import" href="../paper-input/paper-input.html">
<link rel="import" href="../paper-input/paper-input-container.html">
<link rel="import" href="../iron-icons/iron-icons.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<dom-module id="first-element">
<template>
<style>
paper-input {
--paper-input-container-color: rgb(64, 64, 64);
--paper-input-container-focus-color: rgb(64, 64, 64);
--paper-input-container: {
border: none;
padding: 0px;
}
--paper-font-subhead: {
font-size: 100%;
}
--paper-input-container-underline-focus: {
display: none;
}
--paper-input-container-underline: {
display: none;
}
--paper-input-container-input: {
height: 24px;
line-height: 20px;
padding: 0 4px;
border: 1px solid rgb(194, 198, 199);
}
--paper-input-container-input-focus: {
border-color:red;
}
--paper-input-container-label {
font-weight: bold;
}
--paper-input-container-invalid-color: red;
}
:host {
display: block;
}
</style>
<paper-input always-float-label label="Floating label"></paper-input>
<paper-input label="username">
<iron-icon icon="icons:accessible" slot="prefix"></iron-icon>
<div slot="suffix">#email.com</div>
</paper-input>
</template>
<script>
class FirstElement extends Polymer.Element {
static get is() { return 'first-element'; }
static get properties() {
return {
prop1: {
type: String,
value: 'first-element'
}
};
}
}
window.customElements.define(FirstElement.is, FirstElement);
</script>
</dom-module>
I am not sure what result you are expecting so it is hard to help you, but one thing I am sure it's your style tag is so messy. And you need to write a semi-colon after mixins because they are like css properties and every css properties are semi-colon separated.
Try your code like that :
<style>
:host {
display: block;
}
paper-input {
--paper-input-container-color: rgb(64, 64, 64);
--paper-input-container-focus-color: rgb(64, 64, 64);
--paper-input-container: {
border: none;
padding: 0px;
};
--paper-font-subhead: {
font-size: 100%;
};
--paper-input-container-underline-focus: {
display: none;
};
--paper-input-container-underline: {
display: none;
};
--paper-input-container-input: {
height: 24px;
line-height: 20px;
padding: 0 4px;
border: 1px solid rgb(194, 198, 199);
};
--paper-input-container-input-focus: {
border-color: red;
};
--paper-input-container-label: {
font-weight: bold;
};
--paper-input-container-invalid-color: red;
}
</style>
Another thing, you are trying to style the border color of the input on focus but also you are setting display to none which doesn't make sense. You have to remove display: none and add border-color: red; to --paper-input-container-underline-focus if you want to style the color.

How to make a top arrow on an Electron window?

I'm going off the Tray Window issue on Electron's Github, which shows how to make a window centered on the tray. Some of the screenshots over there show people with a tray window and a top arrow indicating the tray, like so. But I'm only getting something like this. Here's the code (main.js):
var ids = [];
const {BrowserWindow,app,Tray} = require('electron');
var trayIcon = null;
const TRAY_ARROW_HEIGHT = 50; //px
const WINDOW_WIDTH = 400;
app.on('ready', function() {
const {screen} = require('electron')
window = new BrowserWindow({
width: WINDOW_WIDTH,
height: 420,
title: 'Hello World',
resizable: true,
frame: false,
transparent: true,
show: false
});
window.loadURL(`file://${__dirname}/main.html`);
window.on('close', function () {
window = null;
});
trayIcon = new Tray('tray.png');
trayIcon.on('click', function() {
var cursorPosition = screen.getCursorScreenPoint();
window.setPosition(cursorPosition.x - WINDOW_WIDTH/2, TRAY_ARROW_HEIGHT);
window.show();
window.focus();
});
window.on('blur', function() {
window.hide();
})
});
And main.html:
html class="arrow_box">
<head>
<style>
.arrow_box {
position: relative;
background: #88b7d5;
border: 4px solid #c2e1f5;
}
.arrow_box:after, .arrow_box:before {
bottom: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.arrow_box:after {
border-color: rgba(136, 183, 213, 0);
border-bottom-color: #88b7d5;
border-width: 30px;
margin-left: -30px;
}
.arrow_box:before {
border-color: rgba(194, 225, 245, 0);
border-bottom-color: #c2e1f5;
border-width: 36px;
margin-left: -36px;
}
</style>
</head>
<body>
<div>This should have an arrow</div>
</body>
</html>
Changing the size of the border on .arrow-box to match the border-width in .arrow_box:after will show the arrow for you.
.arrow_box {
position: relative;
background: #88b7d5;
border: 30px solid #c2e1f5;
}

Resources