An element on a canvas jumps after the canvas itself is dragged - css

As mentioned, an element on a canvas jumps after the canvas itself is dragged. I'm using -webkit-transform: translate(x,y) to drag the canvas around. Any ideas on what to look into for this problem?

Look for changes that cause a reflow in CSS:
visibility:hidden/visible
display:none
:hover
and JavaScript:
offsetWidth or offsetHeight
scroll event
The sad truth about CSS3 selectors is that they really shouldn’t be used at all if you care about page performance. Decorating your markup with classes and ids and matching purely on those while avoiding all uses of sibling, descendant and child selectors will actually make a page perform significantly better in all browsers.
With parent selectors it becomes extremely easy to accidentally cause a document-wide grovel. People can and will misuse this selector. Supporting it is giving people a whole lot of rope to hang themselves with.
The complete profile is appropriate for contexts which aren't extremely performance sensitive. For example, implementations of the Selectors API specification [SELECTORS-API] should use the ‘complete’ profile. It includes all of the selectors defined in this document.
CSS implementations conformant to Selectors Level 4 must use the ‘fast’ profile for CSS selection.
The fast profile is appropriate for use in any context, including dynamic browser CSS selector matching. It includes every selector defined in this document, except for:
Combinators within :matches(), :not(), :nth-match(), and :nth-last-match().
The reference combinator
The subject indicator
In particular, in the situation the browser is looking at most of the selectors it's considering don't match the element in question. So the problem becomes one of deciding that a selector doesn't match as fast as possible; if that requires a bit of extra work in the cases that do match you still win due to all the work you save in the cases that don't match.
Use browser specific selectors to target the document itself:
#-moz-document url-prefix()
{
#media all
{
.foo { color: red } /* Firefox */
}
}
*::-ms-backdrop, .foo { color: red } /* IE11 */
*:-webkit-any-link, .foo { color: red } /* Webkit */
If you want to reference a child element based on its context, use the XML serialization of HTML5 and CSS3 namespaces:
#namespace m "http://www.w3.org/1998/Math/MathML/";
m|math { border: 1px solid blue; }
If you want to display a child element based on a parent pseudo class, you can define the default state of the child element, then redefine it for each state change of the parent:
li:hover > a * { display: none; }
li:hover > a:hover * { display: block; }
References
XHTML5 + CSS Namespaces
CSS Selectors: Should You Optimize Them To Perform Better?
Performance Impact of CSS Selectors
Why do browsers match CSS selectors from right to left?
List of suggested extensions to CSS
Force Element to Self-Clear its Children
The IE8 “hover” Bug: The Most Awesome IE Bug Ever?
MDN: #document
Issues for CSS Selectors Level 4
Reflows and Repaints: CSS Performance making your JavaScript Slow
How Browsers Work

Related

Why not :visited instead of a:visited for links?

Every example and stylesheet I've looked at uses a:visited to style links. Besides a:visited having higher specificity, shouldn't :visited be equivalent and simpler?
TL;DR: At the time of writing, you are completely correct; there is no difference between a:visited and :visited. However, using a:visited is best practice for future-proofing your code.
TL;DR EDIT: As of August 2016, the CSS4 Working Draft allows other tags to use :visited. There is now a functional difference between a:visited and :visited! Beware.
For web development languages today, specifically HTML5 and CSS3, you are right: there is functionally no difference between a:visited and :visited. Now, please take this with caution: web standards, elements, and user interface protocols are ever-evolving, meaning that in the future, it is possible that a new tag compatible with :visited may be introduced.
When :visited was introduced in CSS, the W3C CSS1 spec said:
In CSS1, anchor pseudo-classes have no effect on elements other than 'a'. Therefore, the element type can be omitted from the selector:
a:link { color: red } == :link { color: red }
HOWEVER, in the CSS2 spec, the behavior of the :visited pseudo-class was not restricted to just a tags:
The document language determines which elements are hyperlink source anchors. For example, in HTML4, the link pseudo-classes apply to a elements with an "href" attribute.
This means that it is up to the document language and browser to determine which elements are compatible with :visited. While the current industry standard states that for HTML, only a elements with an href attribute qualify, this may well change later down the line.
EDIT, August 2016: Looks like the CSS4 Working Draft has confirmed my suspicion; in the new spec, :visited can be used for other "link-like" elements, namely <area> and <link>. The spec says:
The :any-link pseudo-class represents an element that acts as the source anchor of a hyperlink. For example, in [HTML5], any <a>, <area>, or <link> elements with an href attribute are hyperlinks.
So <a>, <area>, and <link> are all treated as hyperlinks, and the spec says that :visited applies to all hyperlinks. So as of CSS4, you'll be better off including the a in a:visited.
According to Selectors Level 4 :visited applies to any hyperlink, which in HTML is the <a>, <area> and <link> elements when they have an href attribute.
A quick test for the link element shows that Firefox at least partially respects this:
Try http://jsfiddle.net/rfdzpjLo/4/ in FF or see below
link:before { content:attr(href); }
link { display:block; }
:visited { color: red; }
:link { color:green; }
<link href="http://stackoverflow.com/questions/27263128/why-not-visited-instead-of-avisited-for-links" />
<link href="example.net/lsjhuehbsi00ejjdus" />
Yes, but it won't be future compatible if a new tag is introduced that may be styled with :visited.
Closest proof I can find:
http://www.w3.org/TR/CSS21/selector.html#link-pseudo-classes
The document language determines which elements are hyperlink source anchors. For example, in HTML4, the link pseudo-classes apply to A elements with an "href" attribute. Thus, the following two CSS 2.1 declarations have similar effect:
a:link { color: red }
:link { color: red }
In theory it's the same for reasons already mentioned. On paper, a:visited vs :visited makes it explicit that the style only applies to anchors, and may potentially be faster: think of it as the browser needing to iterate through all a tags in the one hand side, and checking if :visited applies, vs doing the same for all tags in the DOM.
Imho though, the more important reason is that styles related to a tag, a pseudo-selector, a class and an identifier aren't necessarily applied in a consistent and predictable order from a browser to the next.
Suppose, for instance, this visited link:
<a id="foo" class="bar" href="...">visited link</a>
Then consider the following CSS:
#foo {
color: red;
}
.bar {
color: green;
}
:visited {
color: purple
}
There used to be a time where the link would appear red, green or purple depending on the browser. (Perhaps it's still the case; I haven't tested.) Because, some would treat #foo as more important than .bar (it's an ID vs a class) and both of these as more important than :visited for similar reasons. Some would treat #foo, .bar and :visited as if they had the same importance, as a property of the tag itself. Some might have treated #foo and .bar as equals but more important than :visited on grounds the latter is a mere pseudo class. And so forth.
Now, consider this CSS, which is the kind of stuff you might encounter in a stylesheet today:
a.bar {
color: green;
}
:visited {
color: purple
}
Even assuming that tags, ID, classes and pseudo classes are all treated equal, we still have a potential problem, in that a.bar can also be considered more specific than plain :visited by some browsers.
Ergo, you end up needing to specify a:visited in the declaration to ensure the behavior is consistent in all browsers -- and chances are there are still a few bad apples around that'll make you want to write a:visited, a.bar:visited just to be sure.
Once you've run into the problem a few times, force of habit kicks in and you'll end up always writing a:hover or a:visited.
:visited is a pseudo class selector used only for anchor link elements that matches when the href attribute of that anchor link has been visited in the past by this browser. It is meant to be useful feedback for a user, so they can tell the difference between links they have been to and links they have not.
REFERENCE
The syntax of a pseudo class is as follows
selector:pseudo-class {
property:value;
}
So you have to use a selector when using a pseudo class and since it supports only links, in this case, the selector would be a.

Should I add a element name in front of '#id' or '.class' selector?

I'm reading the book: CSS Mastery: Advanced Web Standards Solutions, and finding the css code inside is almost writed in this format:
elementName#idName
elementName.className
but, I'm used to write code ignoring element name with this format:
#idName
.className
so, I want to figure out what difference is between the two format.
Actually, I understand when should use type.class. And, I just want to find out the impact when I use type.class insead of only using .class when there is only one kind of tag here.
There must be some impact on performance.
Here's a real life scenario as when to use elementName and when to just use class or id name:
HTML:
<a class="blue">I'm blue and underline</a>
<span class"blue">I'm blue and bold</a>
CSS:
.blue {
color:blue //will make both <a> and <span> blue
}
a.blue {
text-decoration:underline // will make only the <a> tags underline
}
span.blue {
font-weight:bold //will make only the <span> tags bold
}
but remember when it comes to IDs you should not have duplicate IDs on your page anyway, this is more practical for classes
The difference between the two is that the first:
element.class
Is calling the element with that specific class.
And the second:
.class
Is calling all elements that contain this class
I think that the element inclusion in the selector is a holdover from days where some browsers required it (I think IE5 does, but I could be wrong). This is no longer necessary, and it does not make sense to include element selector for at least three reasons:
It slows the selector down since the element selector is slower than the other two -- especially id. Assuming selection is optimized so that fast selection is done first (e.g. the element with the matching id is found before the element selector is checked), there is still the additional step of checking the element selector.
It's not as extensible since you can't change the element without also having to change the selector. The implication is also that div.class would function differently than label.class, but I think that the class should be descriptive enough.
It changes the specificity of the selector. This could be very frustrating for some developers who may want to change <div class="foo"> from green to red:
div.foo { color: green; }
/* below is not applied since the above has higher specificity */
.foo { color: red; }
I've never heard an argument that supports type.class unless old browsers need to be supported.

CSS selectors that is not applied if hierarchy contains an element?

There are tens of CSS rules I would like to be applied on a section of a page - this part is easy:
.generalStyles a,p,button,div.foo {
/* many styling rules here*/
}
However, when I mark a section of a page with class="generalStyles", I would like certain subsections not to inherit those styles, such as descendants of class="noGeneralStyles" (1). This should work with arbitrary nesting.
What I am looking for is a selector that could be translated into:
Inherit CSS rules if you are a descendant of .generalStyles, but not
when .noGeneralStyles is a closer parent
An interactive jsFiddle example can be found here
EDIT: The solution (if there is any) should not make any assumptions of inner HTML
(1) - the reason is there are way too many CSS rules to reset
You won't be able to limit or otherwise control inheritance chains using selectors alone, not even through combining :not() and descendant selectors for the reasons given here and here. You will have to provide an overriding rule for elements within .generalStyles .noGeneralStyles.
How about using direct descendant selectors? > means it will select button tag, which is direct child to an element having class noGeneralStyles or generalStyles
Demo
.noGeneralStyles > button {
color: black;
}
.generalStyles > button {
color: red;
}

Why does IE10 require the presence of a p:hover {} rule for transitions to work on a pseudo element?

HTML:
<p>Hover</p>
CSS:
p::after {
content: " here";
transition: all 1s;
}
p:hover::after {
font-size: 200%;
color: red;
}
Live demo: http://jsfiddle.net/SPHzj/13/ (works in Firefox and Chrome)
As you can see, I've set up CSS transitions on the ::after pseudo-element of the paragraph. Then, when the paragraph is hovered, two new styles apply for the pseudo-element which are transitioned.
This works in Firefox and Chrome, but not in IE10. My reasoning was that IE doesn't understand the p:hover::after selector, as it works in IE if you set the hover on an ancestor element, e.g. div:hover p::after - live demo: http://jsfiddle.net/SPHzj/14/.
However, this is not the case, as IE is indeed able to understand that selector. The trick is to define a p:hover {} rule as well. (Discovered by #maxw3st.)
p:hover {}
This rule can be empty. The mere presence of this rule will make the transitioning work in IE10.
Live demo: http://jsfiddle.net/SPHzj/15/ (also works in IE10)
What's going on here? Why does IE require that rule to be present in order for transitions to work on the pseudo-element? Should this be considered a bug?
Appears to be a Regression
This does appear to be a legitimate regression in Internet Explorer 10. As indicated on MSDN, since Internet Explorer 7 users have been able to target the hover state of any element , and not only a.
Curiously I tried the :active pseudo-class, and this appears to work as expected. Further establishing that this is a regression, you can see that by changing this to an a element, the transition takes place as expected (since historically, a and :hover go hand-in-hand).
Optional Work-Arounds
There are only a few solutions that I can think of at this point (while waiting for this to be fixed):
Use the empty p:hover {} fix.
Modify your markup to target ::after on a child of the p.
Modify the selector to use combinators.
The first item is that which you specified in your question, and is very attractive given its simplicity. In fact, you could use :hover{} and get the same results (probably the best solution).
The second item is also do-able, but a little less desirable since it requires modifying the markup, which is not always possible, and to be frank, a bit silly.
The last option is somewhat interesting. If you modify the selector to be based on sibling relationships, it magically begins to work again. For instance, suppose we have multiple elements in the body:
<h1>Hello, World</h1>
<p>This is my first paragraph. it does not animate.</p>
<p>This animates, with a pseudo-element.</p>
We can now use combinators to target the second paragraph:
p+p:hover::after {}
This selector will match any paragraph following a paragraph though, which isn't desirable. At this point we could consider :nth-child, or :nth-of-type to further specify which paragraph we want, even using the general sibling combinator:
h1~p:nth-of-type(2):hover::after {} /* Targets second <p> nearest <h1> */
But more ideally we would target with a class:
h1~.hoverme:hover::after {} /* Targets <p class="hoverme"> */
A Two-Char Solution?
One step further, maybe you don't want to be locked down explicitly providing a general sibling tag. You could also use the Universal Selector:
*~.hoverme:hover::after {} /* Targets <p class="hoverme"> among siblings */
This requires that the p tag have siblings, which is typically expected. Very rarely does a document consist of nothing more than a single paragraph tag.
I understand that these aren't ideal, but they are a means to an end for now. Let's hope to see this resolved in future releases of Internet Explorer.
Strangely, the effect will work on a <a> link rather than a paragraph tag.
It certainly appears to be an IE10 bug or regression. Fortunately, you've found a nice fix.
This same phenomenon popped up when I tried adding a rule to change the cursor to a pointer. However, cursor: pointer; has to be included in the pseudo's parent, it can't be used to target just the pseudo's content string in IE10.
http://jsfiddle.net/maxw3st/SPHzj/22/ uses a div as a container, http://jsfiddle.net/maxw3st/7sBVC/ uses the p:hover workaround. Adding the div was suggested by #simevidas, and works fine for the transition, just not the pointer. The pointer only seems to appear in IE10 when it is applied to the parent of the pseudo-element.

Is :not(:hover) and :hover a safe way to hide accessible elements?

Sometimes it appears helpful to make certain page elements only visible on e.g. hovers. An example is stackoverflow's "feedback - Was this post useful to you?"-widget. As those elements might be crucial to the interface, such a show-on-hover-feature should be a progressive enhancement or, in other terms, unobtrusive and degrade gracefully.
The usual way appears to be employing javascript, e.g. hiding the elements and making them available when a parent element is hovered. The reason for that choice might be :hover is not support for all elements especially in legacy browsers, thereby forbidding you to hide elements in the first place up to css2. (for a js/jQuery example cf. jquery showing elements on hover)
I wonder if you can achieve such a feature safely* with pure css3, using :not(:hover) and :hover, not affecting older browsers. As far as I can see, the requirement is that every browser supporting :not() must support :hover for all elements. According to the following sources, that appears to be the case
http://www.quirksmode.org/css/contents.html
http://kimblim.dk/css-tests/selectors/
Example implementation: http://jsfiddle.net/LGQMJ/
What do you think? Any objections or other sources?
*by safely I mean the browser should always show all elements as a last resort.
Your solution looks alright for CSS3. There isn't anything I can think of to improve your solution for modern browsers as the opacity property will never be applied by browsers that don't support it anyway.
There is literally no other browser besides IE6 and NN4 (and older) without support for :hover on elements other than a. As implied in your question, all browsers that support :not() are known to also fully support :hover.
That said, you end up leaving IE7 and IE8 missing out on the hover effect, the latter of which is still quite prevalent. You're probably looking to support IE6 as well, but here's a solution that I believe will address these concerns, if you need it:
Omit :not(:hover) altogether so your first selector becomes less specific rather than equally specific to your second selector with :hover, and you can reach out to IE7 and IE8 which don't support :not() but do support :hover on all visual elements:
div span.question {
opacity: 0;
}
div:hover span.question {
opacity: 1;
}
Use the visibility property instead of the opacity property to reach out to IE7 and IE8 which don't support CSS3 opacity:
div span.question {
visibility: hidden;
}
div:hover span.question {
visibility: visible;
}
Keep in mind that visibility: hidden will make an element invisible to mouseovers as well, but in this case you're applying it to a child element, so the parent will remain visible to mouseovers.
Use CSS2/3 combinators that IE6 doesn't support but IE7 and IE8 do (child >, adjacent sibling +, general sibling ~) to hide both rules from IE6. This borders on "hacky", but your situation is one where the child combinator > fits very well, so it can be integrated organically rather than hacked in like the famous html > body filter:
div > span.question {
visibility: hidden;
}
div:hover > span.question {
visibility: visible;
}
Updated fiddle

Resources