What is the difference between :focus and :active? - css

What is the difference between the :focus and :active pseudo-classes?

:focus and :active are two different states.
:focus represents the state when the element is currently selected to receive input and
:active represents the state when the element is currently being activated by the user.
For example let's say we have a <button>. The <button> will not have any state to begin with. It just exists. If we use Tab to give "focus" to the <button>, it now enters its :focus state. If you then click (or press space), you then make the button enter its (:active) state.
On that note, when you click on an element, you give it focus, which also cultivates the illusion that :focus and :active are the same. They are not the same. When clicked the button is in :focus:active state.
An example:
<style type="text/css">
button { font-weight: normal; color: black; }
button:focus { color: red; }
button:active { font-weight: bold; }
</style>
<button>
When clicked, my text turns red AND bold!<br />
But not when focused only,<br />
where my text just turns red
</button>
edit: jsfiddle

:active Adds a style to an element that is activated
:focus Adds a style to an element that has keyboard input focus
:hover Adds a style to an element when you mouse over it
:lang Adds a style to an element with a specific lang attribute
:link Adds a style to an unvisited link
:visited Adds a style to a visited link
Source: CSS Pseudo-classes

There are four cases.
By default, active and focus are both off.
When you tab to cycle through focusable elements, they will enter :focus (without active).
When you click on a non-focusable element, it enters :active (without focus).
When you click on a focusable element it enters :active:focus (active and focus simultaneously).
Example:
<div>
I cannot be focused.
</div>
<div tabindex="0">
I am focusable.
</div>
div:focus {
background: green;
}
div:active {
color: orange;
}
div:focus:active {
font-weight: bold;
}
When the page loads both are in case 1. When you press tab you will focus the second div and see it exhibit case 2. When you click on the first div you see case 3. When you click the second div, you see case 4.
Whether an element is focusable or not is another question. Most are not by default. But, it's safe to assume <a>, <input>, <textarea> are focusable by default.

:focus is when an element is able to accept input - the cursor in a input box or a link that has been tabbed to.
:active is when an element is being activated by a user - the time between when a user presses a mouse button and then releases it.

Active is when the user activating that point (Like mouse clicking, if we use tab from field-to-field there is no sign from active style. Maybe clicking need more time, just try hold click on that point), focus is happened after the point is activated. Try this :
<style type="text/css">
input { font-weight: normal; color: black; }
input:focus { color: green; outline: 1px solid green; }
input:active { color: red; outline: 1px solid red; }
</style>
<input type="text"/>
<input type="text"/>

Focus can only be given by keyboard input, but an Element can be activated by both, a mouse or a keyboard.
If one would use :focus on a link, the style rule would only apply with pressing a botton on the keyboard.

Using "focus" will give keyboard users the same effect that mouse users get when they hover with a mouse. "Active" is needed to get the same effect in Internet Explorer.
The reality is, these states do not work as they should for all users. Not using all three selectors creates accessibility issues for many keyboard-only users who are physically unable to use a mouse. I invite you to take the #nomouse challenge (nomouse dot org).

Related

How to change the focus state in CSS to just affect the keyboard and not mouse clicks

In Chrome/Firefox (haven't looked in other browsers), my mouse clicks are showing the properties attached to the :focus selector. See http://jsfiddle.net/qtLoLf6p/1/
a:focus {
color: black;
text-decoration: none;
}
I'd like it to work just like the default blue outline works on anchor (a) tags, just on tab focus and not on click focus.
Note in my fiddle that i've just added the JS so the page doesn't change.
I'm alittle unclear on what you're trying achieve with the overall appearance however I would recommend looking to the :active selector.
When tabbing onto a link, the :focus selector is fulfilled, however when clicking on a link the :active selector is also fulfilled, this means you can set your styling for tabbing in :focus, and then override these styles with the mouse only properties in :active
The below example will give both the mouse click and the tab event different styling
a:focus {
color: #000;
text-decoration: none;
}
a:active {
color: #F00;
text-decoration: underline;
}
JSFiddle example here
Edit: An extract from CSS-Tricks explaining the purpose of :focus
The :focus pseudo class in CSS is used for styling an element that is currently targeted by the keyboard, or activated by the mouse
:focus selector explanation article

:focus not working as expected in IE

I have a question on accessibility on a postchat survey window which I've worked on.There's a close button on the top right(as an image of X) where I've included visual focus by putting focus pseudo class, now the problem i'm facing is that the close button has white border around it when it is focused and this is happening as expected in chrome, Mozilla but in IE a blue border is coming. Can someone help me how to remove this blue border and bring white in its place?
I'm sharing the code snippet where I've used focus
a.close-link:focus {
outline: 1px dotted white;
}
Though active and focus are to different states but you can try both at same time for your purpose i think
:active Adds a style to an element that is activated
:focus Adds a style to an element that has keyboard input focus
:hover Adds a style to an element when you mouse over it
:lang Adds a style to an element with a specific lang attribute
:link Adds a style to an unvisited link
:visited Adds a style to a visited link
following source http://www.w3schools.com/CSS/css_pseudo_classes.asp
a.close-link:focus, a.close-link:active {
outline: 1px dotted white;
}
:FOCUS pseudo-class does work in IE, Instead, I believe your problem is with outline property.
Try this:
IE 9
George Langley wrote in to say that IE 9 apparently doesn't allow you
to remove the dotted outline around links unless you include this meta
tag:
<meta http-equiv="X-UA-Compatible" content="IE=9" />
((source))
Well i've found out a workaround. For IE9 border comes by default so I've removed border now and the blue outline is no more there!
a.close-link:focus {
outline: 1px dotted white;
}
a.close-link img {
border: none;
}

:active selector occurs only on click

With the following HTML:
<input type="text">
And the CSS:
input[type="text"] {outline: none; border: thin solid red}
input[type="text"]:active {border: thin solid yellow}
I hoped that the text field would have a yellow border when it is active (when the user is typing). However, the new style only applies when you are clicking on the element. How can I reach the effect I want?
You should use :focus:
input[type="text"]:focus {border: thin solid yellow}
JSFiddle Demo.
From W3C:
The :active pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it.
The :focus pseudo-class applies while an element has the focus (accepts keyboard or mouse events, or other forms of input).

Disable CSS3 delayed transitions with click/tap events

I have a web page with links that look like:
<span>Home</span>
My link is displayed just as an icon (using pseudo elements), but when one hovers over it and waits for some time text also appears beside it. I created these states purely in CSS3 using transition delayed state changes.
a span {
text-indent: -1000em;
}
a:hover span {
text-indent: 0;
transition: text-indent 0 3s;
}
Here's a working example on JSFiddle.
But there are quirks that I'd like to resolve and would be especially happy to do that without Javascript if at all possible:
When using a mouse I would like to not show the span when user already clicks the action link (does something on page without redirecting elsewhere), because when user clicks the link they likely still stay on it with mouse cursor so delayed hover state still executes.
When taping the same link on a mobile device I would like to unhover from it so only click would be recorded.
Basically by resolving #2 I would resolve #1 as well when solution isn't device specific.
I'm not sure if it does the trick but you can use a:active and a:visited to hide the span
a:active span{
display: none;
}
a:visited span{
display: none;
}
Example

Clicking a child doesn't trigger the parent's :active state in IE

I have found an irritating bug in IE 8-10 that prevents a parent's active state being triggered. It appears that if a child of the parent element is the target of the click event the active state on the parent element is not triggered.
Here is a working example. If you click the text inside the <li> the element wont change colour. If you click inside an <li> anywhere other than on the <p> child the element will turn blue.
This is a problem as it pretty much renders the css :active pseudo state useless in IE if the element has any children.
Has anyone encountered this problem before, and even better found a way round it?
Here's an easy workaround: add a css rule to the paragraph.
Working example
CSS
ul { list-style: none; }
li { height: 50px; margin-bottom: 4px; background: red; }
li:active { background: blue; }
p:active { background: blue; height: 100%;}
I have fixed the issue by preventing pointer-events on the child element. This way the :active state is triggered directly on the parent and doesn't need to be propagated. The only downside of this solution is you cannot attach an event listener (not even a css `:hover selector) to the child anymore. So you have to move all your event listeners to the parent.
.child { pointer-events: none; }
Here is jsFiddle https://jsbin.com/govelabuca/1/edit?css,output
Just uncomment the last line in css and compare the result in IE and other modern browser
You could add another CSS selector for the <p> tag so your
li:active { background: blue; }
will become
li:active, li p:active { background: blue; }
I would suggest you would use javascript or jquery for that when you click a child element, perform the active state of of the parent.
I've stumbled upon this on IE11. I was writing a drag-n-drop styling logic using this approach suggested by Martin.
In my case I have a row with td cell elements and using :active for the parent tr does the job for other browsers. For IE, I've added a CSS rule to target the cells (tr.myRowClass > td:active) and modified the if condition in my custom JS logic executed during the mousemove event handler of the cells:
if (style.getPropertyValue('cursor') == 'auto' || document.querySelectorAll(":active").length > 0) {
The remaining task is to find the target element:
Determine which element the mouse pointer is on top of in Javascript

Resources