I'm trying to create a custom outline for a button and I'm facing issues with Chrome and IE and Edge.
See this codepen: http://codepen.io/alansouzati/pen/dXEWLB
.custom:focus {
outline: black solid 2px;
}
.custom:active,
.custom:hover,
.custom:visited {
outline: 0;
}
In Safari and Firefox I get the expected behavior.
To test it, click the second button (Custom focus). In IE and Edge I'm getting the outline even though I did not press tab. In Safari and Firefox the outline only shows up if I press tab, not when I click the button.
Any suggestions on how to fix this issue for Chrome and IE ?
You can use .blur() in jQuery to avoid focusing after a button is clicked.
function myFunction() {
alert('hi');
}
$(".custom").click(function(e) {
$(this).blur();
myFunction();
});
.custom:focus {
outline: black solid 2px;
}
.custom:active,
.custom:hover,
.custom:visited {
outline: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" onclick="myFunction()">Default focus</button>
<br/>
<br/>
<button type="button" class="custom">Custom focus</button>
Your CSS can be simplified to
.custom:focus:not(:active) {
outline: black solid 2px;
}
And then Edge will render the outline just like Chrome, which makes me think the problem has to do with the handling of CSS selector specificity in Edge.
Updated Codepen: http://codepen.io/anon/pen/EgvYPR
Note however that in your example when I click on the second button with the mouse and then move the cursor outside the button before releasing it, the outline appears even if the tab key was not pressed: same behavior in all browsers.
If this is not intended, I'd suggest you switch to a JavaScript solution.
Related
I'm working on a table where users will click on cells and drag the mouse across other cells to interact with it.
I want the mouse cursor to stay as 'pointer' the whole time the user is on the table. They should not be able to select any text.
Here's some example code to demonstrate:
<html>
<head>
<style>
td {
user-select: none;
-webkit-user-select: none;
cursor: pointer;
}
</style>
</head>
<body>
<table>
<tr><td>Test</td><td>Test</td></tr>
<tr><td>Test</td><td>Test</td></tr>
</table>
</body>
</html>
This works perfectly in Chrome - the cursor never changes from pointer regardless of how you interact with the cells using the mouse.
However, Safari always changes to the 'text' cursor as soon as you start dragging the mouse over the table (even though -webkit-user-select successfully prevents you from actually selecting text).
I've tried applying the styles above to the :active selector, as well as to parent elements (e.g. ) but no luck.
Does anyone know how to make this work in Safari?
Use mousedown event and event.preventDefault() -
function preventDefault(event) {
event.preventDefault()
}
div {
cursor: pointer;
background-color: lavender;
padding: 1rem;
margin: 1rem 0;
}
<div>
❌ click and drag with default cursor
</div>
<div onmousedown="preventDefault(event)">
✅ click and drag with custom cursor
</div>
Triggering the click event depends on the value of transform: scale().
When there is a relative big number, it works, but when there is a small one, it does not work properly.
Does anybody know how to fix it?
Here is my Demo
Try to click on the border in order to see it.
document.querySelectorAll("button").forEach((itm)=>{
itm.addEventListener("click",function(){alert("press")});
})
button{cursor:pointer;user-select:none;outline:none;background-color:#c7ffff}
button{border:25px solid red;box-sizing: border-box;}
#b1:active{transform:scale(0.4)}
#b2:active{transform:scale(0.95)}
<!-- Click on the border on each one of then-->
<!-- Then click on the center, and it works in both-->
<button id="b1">Click Me</button>
<button id="b2">Click Me x2</button>
The problem is the div seems to lose the click event as the active button is now too small and therefore the click is no longer inside the button (try the larger button number but click in the bit that turns white and you will see it has the same problem).
https://developer.mozilla.org/en-US/docs/Web/Events/click - The click event is fired when a pointing device button (usually a mouse's primary button) is pressed and released on a single element.
This means when the button is released, as the mouse is no longer in the button because it was scaled down, the click event for that button won't fire
How about using mousedown to capture the event instead:
document.querySelectorAll("button").forEach((itm) => {
itm.addEventListener("mousedown", function() {
console.log("press"); // changed to console so you can see it fire in the snippet as well as the animation taking place (which wuldn't happen with an alert)
});
})
button {
cursor: pointer;
user-select: none;
outline: none;
background-color: #c7ffff
}
button {
border: 25px solid red;
box-sizing: border-box;
}
#b1:active {
transform: scale(0.4)
}
#b2:active {
transform: scale(0.95)
}
<!-- Click on the border on each one of then-->
<!-- Then click on the center, and it works in both-->
<button id="b1">Click Me</button>
<button id="b2">Click Me x2</button>
I have a Burger Menu Button which is selectable via TAB. When I click on it and the menu opens up the burger has this blue outline to make it clear that it is focused.
I don't want to remove that blue outline, because it helps vision impaired people and for tab selection it is also great, but is there a smart way to remove the blue outline only when someone clicks on it via mouse. Just asthetics...
Thanks for your answer.
cheers
As you pointed out, the blue outline is here for accessibility reasons.
If you click on the element, the keyboard focus will also move to that element.
So users have to know that the keyboard focus has been moved to that element.
Some people with disabilities may want to jump to a particular tab using the mouse, but then use their keyboard for easiness reasons.
js:
$('#element').click(function(){
$(this).addClass('mouse');
});
$('#element').blur(function(){
if($(this).hasClass('mouse'){
$(this).removeClass('mouse');
}
});
css:
.mouse{
outline: none;
}
If I understood correctly the question, try:
.myButton:active {outline: none;}
Here's a simple solution, in plain Javascript, that works back to IE 10.
This answer is similar to #kuba's answer. Add/remove a class using JS to detect a mouse click or a tab button press.
javascript:
var htmlElement = document.querySelector('html');
document.addEventListener('click', function(){
htmlElement.classList.add('clicking');
});
document.addEventListener('keyup', function(e){
if (e.keyCode === 9) {
htmlElement.classList.remove('clicking');
}
});
Then turn off outline on :focus when the clicking class exists
CSS:
html.clicking .targetElement:focus {
outline: none;
}
/*
or you can try dealing with all visibly focusable elements from the start. I'm not sure if this is all of them, but it's good starting point.
*/
html.clicking a:focus,
html.clicking button:focus,
html.clicking input:focus,
html.clicking textarea:focus {
outline: none;
}
Browser Compatibility:
querySelector IE 8+
element.classList IE 10+
jQuery alternative if you need to support browsers older than IE10.
$(document).on('click', function(){
$('html').addClass('clicking');
});
$(document).on('keyup', function(){
if (e.keyCode === 9) {
$('html').removeClass('clicking');
}
});
Well you may want to do it this way:
div:active, div:focus{
outline: none;
border: none;
}
and maybe:
*{
-webkit-tap-highlight-color: rgba(0, 0, 0, 0) !important;
}
Firefox, since version 23, natively supports the <input type="range"> element, but I couldn’t figure out how to remove the dotted outline. The following CSS has no effect:
input[type='range'],
input[type='range']:focus,
input[type='range']:active,
input[type='range']::-moz-focus-inner,
input[type='range']:-moz-focusring {
border: 0;
outline: none;
}
Does anyone have any idea how to fix this issue in Firefox?
Example: https://jsfiddle.net/pF37g/
Unfortunately, you can't! (update; you now can)
It's a bug in Firefox and there is no work-around to fix this besides from fixing the source base itself (see below).
Also see Jonathan Watt's blog (who is working on this):
Known issues:
the default CSS styled appearance still needs work, and native theming (giving the slider the appearance of the operating system's
theme) is still to come ...
In a reply to a comment in his blog about this very same issue he states:
Right now you can't - sorry. I've filed bug 932410 to make that
possible.
At the moment of writing there appear to be no progress on this and it's not known when a official fix will be available.
Update
Since this answer was posted the bug has been fixed. You can now use (as stated in other answers, but I include it here for completeness):
input[type=range]::-moz-focus-outer {
border: 0;
}
It can be done with new version of Firefox. As stated here, this bug is fixed. So it is possible to hide outer dotted border. To do so, set ::-moz-focus-outer's border to 0, like this:
input[type=range]::-moz-focus-outer {
border: 0;
}
Here is working example: http://jsfiddle.net/n2dsc/1/
In webkit browsers outer line will appear if -webkit-appearance: none; is set. To remove it, just set :focus's outline to none, like this:
input[type=range]:focus {
outline: none;
}
Here is working example: http://jsfiddle.net/8b5Mm/1/
As Ken already pointed out, there is no way to remove the outline. However, there is a work-around to "hide" the outline if you know the background-color of the parent element. Assuming a white background the following CSS would hide the dotted outline:
input[type=range] {
border: 1px solid white;
outline: 2px solid white;
outline-offset: -1px;
}
Your updated example: http://jsfiddle.net/9fVdd/15/
If you can settle for a wrapping element (it's likely you already have a wrapping LI or P), you can use FireFox-only CSS to position the input out of view and reposition the track/thumb in view.
Note 1 - don't try to use translateX - I think FireFox uses that to actually slide the thumb - so stick with translateY
Note 2 - Be sure to test with keyboard navigation. You should only move the input by the smallest amount possible to get the dotted lines out of sight. If you position it waaay far away (translateY(-1000em)) - then you will break usability for keyboard navigation.
Here ya go:
HTML
<span class="range-wrap"><input type="range" /></span>
CSS
.range-wrap {
overflow: hidden;
}
input[type='range'] {
-moz-transform: translateY(-3em);
}
input[type='range']::-moz-range-track {
-moz-transform: translateY(3em)
}
input[type='range']::-moz-range-thumb {
-moz-transform: translateY(3em);
}
http://jsfiddle.net/pF37g/98/
Dotted outline is not an issue, it's browser's way to show the input element is selected. What you can do is set tabIndex to -1 which will prevent your input element from taking focus on tab and, consequently, from having the outline:
<input class="size" type="range" tabIndex="-1" name="size" min="1" max="6" value="6"></input>
But after doing this you will lose some keyboard accessibility. It is better to have input element keyboard accessible.
Here is the fiddle: http://jsfiddle.net/pF37g/14/
If any custom styling is applied to input[type='range'] then Firefox use a different model (beta) to render the range input.
You can see the 2 different models here:
http://jsfiddle.net/pF37g/75/
Currently I do not believe it is currently possible to have a custom CSS styled input range box in Firefox to adhere to outline: 0; as of Firefox 27.0
To make it complete: The Bug has been fixed and now it's working with:
input[type=range]::-moz-focus-outer { border: 0; }
to remove all outlines from all input-tags use:
input::-moz-focus-inner, input::-moz-focus-outer { border: none; }
source: https://bugzilla.mozilla.org/show_bug.cgi?id=932410#c7
You can not. It seams to be a bug in Firefox.
It makes two outlines for the range element. One you can influence by css setting and a second, which is resistant against any manipulation.
I set the outline visible to show the issues:
input[type='range']:focus {
outline: 5px solid green;
}
Here you can see it:
http://jsfiddle.net/pF37g/97/
I have little research in config section of mozilla add this too
:-moz-any-link:focus {
outline: none;
}
a, a:active, a:visited, a:hover {
outline: 0;
}
then
:focus {
outline: none;
}
then
::-moz-focus-inner {
border: 0;
}
Here comes the solution
:focus {
outline:none;
}
::-moz-focus-inner {
border:0;
}
I am developing an HTML5 web page for mobile. On mobile device, we can't detect hover event. So, how to change the background of button when I press it by my finger?
Update: One simple example of what I want is the button "Google Search" of google main page: https://www.google.com.vn/
Thanks.
I found the solution as below. Hope this helps
button:ACTIVE {
background: aqua;
}
button {
background: green;
}