I'm trying to make an upvote/downvote the same way that it's done on SO and Reddit, from what I can see they use arrow images as backgrounds and then position it, but I'm a CSS newbie and I need someone to walk me through it.
You could do it by adding a different picture to the background, one for every state of the button. There is however a cleaner, easier, more modern way of achieving this result: Sprites.
A sprite is an image that is saved as a part of a larger image. One of the biggest advantages of using sprites is the reduction of round-trips to the server for all the images to just one request for the Sprites. The element to display a picture has the image as background. The background is moved relative to the element so the element displays only part of the image. Like when you move a photo-frame over a poster (or in this case: moving the poster under the frame)
At SO they make an image that contains all the states for the button. They give the element for the button (a span in this case) a fixed width and height and add the background to it with CSS. Then toggle a class for the state (on or off) with javascript on the click event. Now the only thing you have to do in CSS is change the position of the background with CSS classes:
for (const btn of document.querySelectorAll('.vote')) {
btn.addEventListener('click', event => {
event.currentTarget.classList.toggle('on');
});
}
.vote {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('http://i.stack.imgur.com/iqN2k.png');
background-position: 0 -25px;
}
.vote.on {
background-position: 0 2px;
}
Click to vote (using sprites): <span class="sprite vote"> </span>
You can easily add more states to the sprites like 'hover' and 'active' just the same way. SO even puts all the images for the whole page in a single image. You can verify this with firebug or the Chrome developer tools. Look for 'sprites.png'.
Update (2020)
It's been 10 years since I answered this question and in this time,
the landscape has changed. Now you can use inline svg as well to achieve this effect. I've updated the code snippet to use svg. This is how stackoverflow currently does this.
It works by toggling the color property of a surrounding span element on button click. The span element contains an inline svg image of an arrow. The fill property of the path that makes up the arrow is initialized with currentColor, which instructs it to take whatever is the current text color.
for (const btn of document.querySelectorAll('.vote')) {
btn.addEventListener('click', event => {
event.currentTarget.classList.toggle('on');
});
}
.vote {
display: inline-block;
cursor: pointer;
color: #687074
}
.vote.on {
color: #f48024
}
Click to vote (using svg):
<span class="vote">
<svg width="36" height="36">
<path d="M2 10h32L18 26 2 10z" fill="currentColor"></path>
</svg>
</span>
You can do it by using two simple images ... design two images in some image editors like Photoshop, if u don't have MSPaint...
CSS code is
#voting{
width:30px;
height:40px;
}
.upvote{
width:30px;
height: 20px;
cursor: pointer;
}
.downvote{
width:30px;
height: 20px;
background: url('downvote.jpg') 0 0 no-repeat;
cursor: pointer;
}
HTML code :
<div id="voting">
<div class="upvote"></div>
<div class="downvote"></div>
</div>
I'm doing project on django, and I'm trying to implement up-vote and down-vote on many posts, I've taken #Jan's code partly and finished it.
vote.html
<span onclick="like_function({{user_answer.pk}})" id="like-{{user_answer.pk}}" class="vote_up_off"></span>
<div id="counter-{{user_answer.pk}}">0</div>
<span onclick="dislike_function({{user_answer.pk}})" id="dislike-{{user_answer.pk}}" class="vote_down_off"></span>
vote.css
/* like dislike button */
.vote_up_off {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url(' https://i.stack.imgur.com/nxBdX.png');
background-position: 0 -25px;
margin-left: 5px;
}
.vote_up_on {
background-position: 0 2px;
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('https://i.stack.imgur.com/nxBdX.png');
margin-left: 5px;
}
.vote_down_off {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('https://i.stack.imgur.com/vWw7n.png');
background-position: 0 -1px;
margin-top: 3px;
}
.vote_down_on {
display: inline-block;
overflow: hidden;
width: 40px;
height: 25px;
cursor: pointer;
background: url('https://i.stack.imgur.com/vWw7n.png');
background-position: 0 -28px;
margin-top: 3px;
}
vote.js
function like_function(answer_id) {
var like_button = document.getElementById('like-'+answer_id);
var dislike_button = document.getElementById('dislike-'+answer_id);
var counter_element = document.getElementById('counter-'+answer_id);
let current_counter = parseInt(counter_element.innerText);
//check if dislike is on(true) or off(false)
let dislike_state = false
if (dislike_button.className == "vote_down_on") {
dislike_state = true
}
else {
dislike_state = false
}
//if dislike is checked
if (dislike_state) {
current_counter += 2;
dislike_button.className = 'vote_down_off'
counter_element.innerText = current_counter
like_button.className = 'vote_up_on'
}
// if dislike is not checked
else {
if (like_button.className == 'vote_up_off') {
like_button.className = "vote_up_on"
current_counter += 1;
counter_element.innerText = current_counter
}
else {
like_button.className = "vote_up_off"
current_counter += -1;
counter_element.innerText = current_counter
}
}
}
function dislike_function(answer_id) {
var like_button = document.getElementById('like-'+answer_id);
var dislike_button = document.getElementById('dislike-'+answer_id);
var counter_element = document.getElementById('counter-'+answer_id);
let current_counter = parseInt(counter_element.innerText);
//check if like is on(true) or off(false)
let like_state = false
if (like_button.className == "vote_up_on") {
like_state = true
}
else {
like_state = false
}
//if like is checked
if (like_state) {
console.log('это тру лайк (лайк нажат)')
current_counter += -2;
like_button.className = 'vote_up_off'
counter_element.innerText = current_counter
dislike_button.className = "vote_down_on"
}
//if like is not checked
else {
if (dislike_button.className == 'vote_down_off') {
dislike_button.className = "vote_down_on"
current_counter += -1;
counter_element.innerText = current_counter
}
else {
dislike_button.className = "vote_down_off"
current_counter += 1;
counter_element.innerText = current_counter
}
}
}
Related
This question already has answers here:
Increasing clickable area of a button
(4 answers)
How to increase the clickable area of a <a> tag button?
(13 answers)
Closed 3 months ago.
If the mouse is about 20px close to the button, I want that the button should be clickable. I tried increasing the width of the button by 20px and making the opacity 0.1 so the big size won't show. Then in the button:hover rule I made the opacity 1.
I did the above cause I don't really know how go about it.
Using vanilla js:
document.getElementById("my-button").onclick = function (e) {
e.stopPropagation();
window.alert("here we go");
};
button {
margin: 20px;
cursor: pointer;
}
div {
cursor: pointer;
background: gray;
width: fit-content;
}
body {
background: gray;
}
<div onclick="document.getElementById('my-button').click()">
<button id="my-button">Button</button>
</div>
$(function() {
var $win = $(window); // or $box parent container
var $box = $(".box");
var $log = $(".log");
$win.on("click.Bst", function(event) {
if (
$box.has(event.target).length == 0 //checks if descendants of $box was clicked
&&
!$box.is(event.target) //checks if the $box itself was clicked
) {
$log.text("you clicked outside the box");
} else {
$log.text("you clicked inside the box");
}
});
});
body,
div,
p {
margin: 0;
padding: 0;
}
body {
background-color: #d6d6d6;
}
.log {
position: relative;
top: 10px;
left: 10px;
color: #000;
}
.box {
position: relative;
top: 50px;
left: 100px;
width: 100px;
height: 100px;
font-size: 18px;
text-align: center;
color: white;
background-color: #79abff;
}
.box p {
color: black;
}
<p class="log">You clicked on: </p>
<div class="box">
Click me
<p>nested p</p>
</div>
I am new to css. How can I add a status button which changes color depending on chat availability on top of another button?
You can use the position property.
See an example code here.
Some resources:
https://www.w3schools.com/css/css_positioning.asp
https://developer.mozilla.org/en-US/docs/Web/CSS/position
From the picture i can tell you don't have to use 2 html elements on top of each other, but you can use css properties like border and background-color to achieve exactly as the button in your picture.
I posted how in the code below with even a little bit of javascript to toogle the button status (not needed for styling, so if you don't know any javascript yet, you can skip that part).
let isOpen = false;
const btn = document.querySelector("#btn");
const dot = document.querySelector(".dot");
const txt = document.querySelector("#text");
btn.addEventListener("click", () => {
if (isOpen) {
dot.style.backgroundColor = "red";
txt.innerHTML = "The chat is now closed";
} else {
dot.style.backgroundColor = "green";
txt.innerHTML = "The chat is now open";
}
isOpen = !isOpen;
});
.dot {
height: 25px;
width: 25px;
background-color: red;
border-radius: 50%;
display: inline-block;
border: 5px solid gray;
}
#wrapper {
border: 1px solid black;
text-align: center;
padding: 10px;
}
#btn {
margin-top: 10px;
}
<div id="wrapper">
<span class="dot"></span>
<p id="text">The chat is now closed</p>
</div>
<button id="btn">Toogle</button>
Apologies if I incorrectly use some terminology here, or don't know the terms to properly describe this but...
Easy Part- I would like to create a Wheel style slider, displaying three pictures, with the main "selected" one being forefront and the other two sitting scaled down, behind them but quickly and easily clickable and viewable.
Hard Part- I would like which ever picture is set in the forefront main portion of the slider wheel to have information displayed, page width, regarding that specific toggled picture and that picture only. Then when you toggle to a different slide/picture ONLY information regarding that would then be placed below the slider/toggle wheel.
I would think my starting point would be to grab some code for the toggle/slider picture wheel. Then somehow create some sort of event trigger type coding for whichever picture is highlighted, coupling that with some sort of html hide/show coding.
I attached some bad sketches to help me visual depict what I am saying.
Any insight is welcome, even if it is some keywords to help me narrow down my google searching and find some resources. Slide & Page Layout Sketch
Thanks & Cheers
Sounds like you're going to need some CSS and JS to make this work.
First, you're going to need your HTML layout. I have a wrapper for the entire carousel (.container). I have the left and right arrows as well as a second wrapper for the images.
For the text below the carousel, I have a second element (.content) which holds three elements, each correlating to the images. The text is only shown when .shown is applied to the element.
<div class="container">
<div class="left"><</div>
<div>
<div class="img img-left"></div>
<div class="img img-center"></div>
<div class="img img-right"></div>
</div>
<div class="right">></div>
</div>
<div class="content">
<div class="text">
Amazing Sunset
</div>
<div class="text shown">
Fall Leaves
</div>
<div class="text">
Misty Sunlight
</div>
</div>
For CSS I choose to make the .container position: relative so that I could use position: absolute on the children. I have 3 classes for the images. img-left, img-right and img-center. These can be animated. The arrows are simply centered vertically
.container {
position: relative;
height: 85vh;
}
.img {
position: absolute;
z-index: 2;
height: 75vh;
width: 121vh;
max-height: 300px;
max-width: 511px;
top: 0; bottom: 0;
left: 0; right: 0;
margin: auto;
transition: transform 0.3s, z-index 0s linear 0.15s;
}
.img:nth-of-type(1) {
background: url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg') center/contain no-repeat;
}
.img:nth-of-type(2) {
background: url('https://cdn.pixabay.com/photo/2015/12/01/20/28/road-1072823__340.jpg') center/contain no-repeat;
}
.img:nth-of-type(3) {
background: url('https://cdn.pixabay.com/photo/2015/09/09/16/05/forest-931706__340.jpg') center/contain no-repeat;
}
.img-center {
z-index: 5;
}
.img-right {
transform: translateX(200px) scale(0.7);
}
.img-left {
transform: translateX(-200px) scale(0.7);
}
.left, .right {
position: absolute;
z-index: 7;
top: 50%;
font-size: 48px;
font-family: monospace;
transform: translateY(-50%);
user-select: none;
}
.left {
left: 32px;
}
.right {
right: 32px;
}
.content {
height: 15vh;
}
.text {
display: none;
text-align: center;
font-size: 32px;
}
.text.shown {
display: block;
}
JavaScript is where things start to get more interesting. I created a function called nextImage() which takes a boolean representing the direction to switch. First, it gets the currently centered image and then based on that image gets the next and previous element siblings. In the event that the centered image happens to be the first or last element, either next or pre will be undefined. That is handled next. Once that is done the CSS classes are reassigned based on the direction.
function nextImage(forward) {
let currentCentered = document.querySelector('.img-center'),
next = currentCentered.nextElementSibling,
pre = currentCentered.previousElementSibling;
//pre and next may not be elements if currentCentered is the frist or last element.
if (!next) { //Centered Element is the frist
next = pre.previousElementSibling;
} else if (!pre) { //Centered Element is the last
pre = next.nextElementSibling;
}
if (forward) {
//Move the previously centered image to the right
currentCentered.classList.remove('img-center');
currentCentered.classList.add('img-right');
//Move the previously left image to the center
pre.classList.remove('img-left');
pre.classList.add('img-center');
//Move the previously right image to the left
next.classList.remove('img-right');
next.classList.add('img-left');
} else {
//Move the previously centered image to the left
currentCentered.classList.remove('img-center');
currentCentered.classList.add('img-left');
//Move the previously left image to the right
pre.classList.remove('img-left');
pre.classList.add('img-right');
//Move the previously right image to the center
next.classList.remove('img-right');
next.classList.add('img-center');
}
//Update the text
let currentText = document.querySelector('.text.shown'),
newText;
if (forward) {
//Get the previous element;
newText = currentText.previousElementSibling;
//If it doesn't exist get the last element
if (!newText) {
newText = currentText.nextElementSibling.nextElementSibling;
}
} else {
//Get the next element;
newText = currentText.nextElementSibling;
//If it doesn't exist get the frist element
if (!newText) {
newText = currentText.previousElementSibling.previousElementSibling;
}
}
//Apply class change
currentText.classList.remove('shown');
newText.classList.add('shown');
}
Adding onclick="nextImage(false)" to the left arrow and onclick="nextImage(true)" to the right arrow now lets you navigate with them.
Since you said you'd like the pictures so be clickable I've added a second function which lets you scroll to the given image. It gets the next and previous elements and makes sure they are actual elements. Then it called the nextImage() function based on if next or pre is the centered image.
function switchImage(imgEle) {
let next = imgEle.nextElementSibling,
pre = imgEle.previousElementSibling;
//Make sure they are actually elements
if (!next) {
next = pre.previousElementSibling;
}
if (!pre) {
pre = next.nextElementSibling;
}
if (next.classList.contains('img-center')) {
nextImage(true);
} else if (pre.classList.contains('img-center')) {
nextImage(false);
}
}
All you have to do now is add onclick="switchImage(this)" to each of your image elements.
Adding this all together you should get something like this snippet below
function nextImage(forward) {
let currentCentered = document.querySelector('.img-center'),
next = currentCentered.nextElementSibling,
pre = currentCentered.previousElementSibling;
//pre and next may not be elements if currentCentered is the frist or last element.
if (!next) { //Centered Element is the frist
next = pre.previousElementSibling;
} else if (!pre) { //Centered Element is the last
pre = next.nextElementSibling;
}
if (forward) {
//Move the previously centered image to the right
currentCentered.classList.remove('img-center');
currentCentered.classList.add('img-right');
//Move the previously left image to the center
pre.classList.remove('img-left');
pre.classList.add('img-center');
//Move the previously right image to the left
next.classList.remove('img-right');
next.classList.add('img-left');
} else {
//Move the previously centered image to the left
currentCentered.classList.remove('img-center');
currentCentered.classList.add('img-left');
//Move the previously left image to the right
pre.classList.remove('img-left');
pre.classList.add('img-right');
//Move the previously right image to the center
next.classList.remove('img-right');
next.classList.add('img-center');
}
//Update the text
let currentText = document.querySelector('.text.shown'),
newText;
if (forward) {
//Get the previous element;
newText = currentText.previousElementSibling;
//If it doesn't exist get the last element
if (!newText) {
newText = currentText.nextElementSibling.nextElementSibling;
}
} else {
//Get the next element;
newText = currentText.nextElementSibling;
//If it doesn't exist get the frist element
if (!newText) {
newText = currentText.previousElementSibling.previousElementSibling;
}
}
//Apply class change
currentText.classList.remove('shown');
newText.classList.add('shown');
}
function switchImage(imgEle) {
let next = imgEle.nextElementSibling,
pre = imgEle.previousElementSibling;
//Make sure they are actually elements
if (!next) {
next = pre.previousElementSibling;
}
if (!pre) {
pre = next.nextElementSibling;
}
if (next.classList.contains('img-center')) {
nextImage(true);
} else if (pre.classList.contains('img-center')) {
nextImage(false);
}
}
.container {
position: relative;
height: 85vh;
}
.img {
position: absolute;
z-index: 2;
height: 75vh;
width: 121vh;
max-height: 300px;
max-width: 511px;
top: 0; bottom: 0;
left: 0; right: 0;
margin: auto;
transition: transform 0.3s, z-index 0s linear 0.15s;
}
.img:nth-of-type(1) {
background: url('https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__340.jpg') center/contain no-repeat;
}
.img:nth-of-type(2) {
background: url('https://cdn.pixabay.com/photo/2015/12/01/20/28/road-1072823__340.jpg') center/contain no-repeat;
}
.img:nth-of-type(3) {
background: url('https://cdn.pixabay.com/photo/2015/09/09/16/05/forest-931706__340.jpg') center/contain no-repeat;
}
.img-center {
z-index: 5;
}
.img-right {
transform: translateX(200px) scale(0.7);
}
.img-left {
transform: translateX(-200px) scale(0.7);
}
.left, .right {
position: absolute;
z-index: 7;
top: 50%;
font-size: 48px;
font-family: monospace;
transform: translateY(-50%);
user-select: none;
}
.left {
left: 32px;
}
.right {
right: 32px;
}
.content {
height: 15vh;
}
.text {
display: none;
text-align: center;
font-size: 32px;
}
.text.shown {
display: block;
}
<div class="container">
<div class="left" onclick="nextImage(false)"><</div>
<div>
<div class="img img-left" onclick="switchImage(this)"></div>
<div class="img img-center" onclick="switchImage(this)"></div>
<div class="img img-right" onclick="switchImage(this)"></div>
</div>
<div class="right" onclick="nextImage(true)">></div>
</div>
<div class="content">
<div class="text">
Amazing Sunset
</div>
<div class="text shown">
Fall Leaves
</div>
<div class="text">
Misty Sunlight
</div>
</div>
Update: Can't see to get things working in Firefox : (
How can I display custom video controls when the in fullscreen mode in modern browsers?
They disappear as soon as I go fullscreen. I'd like them to be available, and then I'll write some JavaScript to hide them on inactivity and show them once someone wiggles their mouse around.
HTML:
<video#video src="vid.mp4" preload poster="/images/poster.jpg">
<iframe src="https://youtube.com/embed/id" frameborder="0" allowfullscreen>
</video>
JS:
var bigPlayButton = document.getElementById('big-play-button')
var video = document.getElementById('video')
var playPauseButton = document.getElementById('play-pause')
var fullscreen = document.getElementById('fullscreen')
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.documentElement.requestFullscreen()
} else {
if (document.exitFullscreen) {
document.exitFullscreen()
}
}
}
fullscreen.addEventListener('click', function (event) {
if (!video.classList.contains('fullscreen')) {
video.requestFullscreen()
} else {
document.exitFullscreen()
}
}, false)
// Detect FullScreen changes and adjust button
document.addEventListener('fullscreenchange', function (event) {
if (document.fullscreenElement) {
fullscreen.children[0].src = '/images/nofullscreen.svg'
video.classList.add('fullscreen')
} else {
fullscreen.children[0].src = '/images/fullscreen.svg'
video.classList.remove('fullscreen')
}
}, false)
CSS
video::-webkit-media-controls {
display: none !important;
}
#custom-video-controls {
z-index: 2147483648;
}
I'm using this polyfill: https://github.com/neovov/Fullscreen-API-Polyfill
Edit
The significant change was targeting the parent tag: .vidFrame for fullscreen instead of the <video> tag as per Kaido's comment.
HTML5 video's controls need special handling if you want to override them. I'm assuming you want to do that since the controls already have the full screen feature built in the controls. This demo implements:
classList for toggling the button#fullScreen states of .on and .off and button#playPause states of .play and .pause.
:fullscreen pseudo-class to insure .vidBar is on the bottom when in full screen mode.
Shadow DOM CSS Styles that are needed to override the native player's controls.
Fullscreen API vendor specific methods to enter and exit full screen mode of course.
There's no volume slider, mute button, or scrubber, just the full screen button (button#fullScreen) and play button (button#playPause). If you want them, ask another question.
Details are commented in source.
It looks as if the Snippet isn't fully functional, so here's a functional Plunker. If that version cannot be reached, then review the embedded Plunker and click the full view button:
Demo
Note: SO sandbox has changed so this demo is not fully functional go to the links mentioned previously or copy and paste the demo on a text editor.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Full Screen Video Toggle</title>
<style>
.vidFrame { position: relative; top: 10%; width: 320px; height: auto; min-height: 180px; outline: 1px dashed red; }
.vidBar { position: absolute; bottom: 0; right: 0; left: 0; height: 40px; width: 99%; }
#fullScreen { position: absolute; bottom: 0; right: 0; width: 36px; height: 36px; outline: none; border: 1px solid transparent; border-radius: 6px; display: block; cursor: pointer; }
#fullScreen:hover { border: 1px groove #0ef; }
.on, .off { background: url('https://i.imgur.com/0FTwh6M.png') no-repeat; width: 36px; height: 36px; }
.off { background-position: 0 0 }
.on { background-position: -1px -50px }
#playPause { position: absolute; bottom: 0; left: 0; width: 36px; height: 36px; background: none; font-size: 36px; color: #0ff; line-height: 1; border: 1px solid transparent; display: block; cursor: pointer; outline: none; }
#playPause.play:before { content: '\25b6'; }
#playPause.pause:before { content: '\275a\275a'; }
.vid { position: absolute; top: 0; left: 0; right: 0; bottom: 0; width: 100%; height: auto; display: block; z-index: 1; outline: 1px dotted blue; }
/*
Fullscreen Pseudo-class:
https://developer.mozilla.org/en-US/docs/Web/CSS/:fullscreen
*/
.vidBar:-moz-full-screen { position: fixed; }
.vidBar:-webkit-full-screen { position: fixed; }
.vidBar:-ms-fullscreen { position: fixed; }
.vidBar:fullscreen { position: fixed; }
/*
Special Shadow DOM Settings to Override Default Controls:
https://css-tricks.com/custom-controls-in-html5-video-full-screen/
*/
video::-webkit-media-controls-enclosure { display:none !important; }
.vidBar { z-index: 2147483648; }
</style>
</head>
<body>
<figure class="vidFrame">
<video id="vid1" class="vid" src="http://techslides.com/demos/sample-videos/small.mp4"></video>
<figcaption class="vidBar">
<button id='playPause' class="play" title="Play/Pause Video"></button>
<button id='fullScreen' class="on" title="Enter/Exit Full Screen"></button>
</figcaption>
</figure>
<script>
/*
Toggle Button with classList:
https://developer.mozilla.org/en-US/docs/Web/API/Element/classList
*/
var fullBtn = document.getElementById('fullScreen');
var playBtn = document.getElementById('playPause');
playBtn.addEventListener('click', function(event) {
var player = document.getElementById('vid1');
if(player.paused) {
playBtn.classList.remove('play');
playBtn.classList.add('pause');
player.play();
} else {
playBtn.classList.add('play');
playBtn.classList.remove('pause');
player.pause();
}
}, false);
fullBtn.addEventListener('click', function(event) {
var tgtEle = document.querySelector('.vidFrame');
var onOrOff = fullBtn.classList.contains('on');
if (onOrOff) {
enterFS(tgtEle);
fullBtn.classList.remove('on');
fullBtn.classList.add('off');
} else {
exitFS();
fullBtn.classList.add('on');
fullBtn.classList.remove('off');
}
}, false);
/*
Fullscreen API:
https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API
*/
function enterFS(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
}
}
function exitFS() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
</script>
</body>
</html>
Use the Fullscreen API on the container element, not on the video
As #Kaiido says in the comments:
You have to call the enterFS method on the container element, not on
the video one.
So the answer is to use the Fullscreen API on the container element rather than the <video> element. This enables providing custom controls in that container which is now all in fullscreen.
For reference, that is the existing enterFS() function from the question:
function enterFS(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen();
}
}
I posted this answer because I had to read the page three times to figure out what was going on here.
There is great information in #zer00ne's answer that is relevant to others with similar issues, but it doesn't directly answer #Costa's original problem, which was previously only answered in a comment.
Can I customize
<input type='number'>
field to show all the time it's arrows? By default it's hidden till the field is has no focus. Below is what I'm talking about.
Firefox and IE don't have such behavior. So, I assume you are working with Google Chrome.
input::-webkit-inner-spin-button {
opacity: 1;
}
FYI. UA stylesheet has the following:
input::-webkit-inner-spin-button {
...
opacity: 0;
pointer-events: none;
}
input:enabled:read-write:-webkit-any(:focus,:hover)::-webkit-inner-spin-button {
opacity: 1;
pointer-events: auto;
}
html.css
The UI and behavior of <input type='number'>, as well as all the other HTML5 input types (e.g., type='date', etc), is browser and/or system dependent. To make the arrows always visible, you'd need to use a custom JS solution.
Only way that I can think of is... Having two buttons for incrementing and decrementing your input and using JS. You won't be using type="number" here since the JS will be incrementing and decrementing the number for you.
Here is an example, as mentioned here:
CSS:
.spin {
display: inline-block;
}
.spin span {
display: inline-block;
width: 20px;
height: 22px;
text-align: center;
padding-top: 2px;
background: #fff;
border: 1px solid #aaa;
border-radius: 0 4px 4px 0;
cursor: pointer;
}
.spin span:first-child {
border-radius: 4px 0 0 4px;
}
.spin input {
width: 40px;
height: 20px;
text-align: center;
font-weight: bold;
}
JS:
var spins = document.getElementsByClassName("spin");
for (var i = 0, len = spins.length; i < len; i++) {
var spin = spins[i],
span = spin.getElementsByTagName("span"),
input = spin.getElementsByTagName("input")[0];
input.onchange = function() { input.value = +input.value || 0; };
span[0].onclick = function() { input.value = Math.max(0, input.value - 1); };
span[1].onclick = function() { input.value -= -1; };
}
Note: Change background: #fff; to change the arrow colors. There are other neat examples available on the web as well!
Demo