Styling visited links via bookmarklet? - javascript

For a while a bookmarklet I made extensive use of has been broken for me in Firefox. It may apply to other browsers, but I only use it in Firefox.
The bookmarklet in question is "hide visited" from squarefree.
Since this wasn't working (properly) I decided to have at it myself and ended up with this:
javascript:(
function(){
var css=document.createElement('style');
css.type='text/css';
var styles='a%3Avisited{display%3Anone !important}';
css.appendChild(document.createTextNode(styles));
document.getElementsByTagName("head")[0].appendChild(css);
})();
Broken up into several lines for readability, otherwise unmodified from what I'm using.
The thing is, it does append the inline stylesheet to the head, it just never alters the look of the links. Once I remove the :visited (or %3Avisited as it appears here), however, the stylesheet IS applied to links and they are hidden, though obviously the hiding is done regardless of their visited-state at this point.
Bottom line here is that I believe there is a problem with :visited, and flipping the bool for layout.css.visited_links_enabled in about:config, predictably, does nothing as this simply removes styling from visited links wholesale. This is undesirable. :)
It is probably worth noting that the squarefree bookmarklet still appends its stuff to the head, it simply has no effect either.
I am at a loss. What have I missed, and is it at all possible to hide visited links via a bookmarklet anymore?

The behavior of :visited was changed a couple of years ago due to security reasons ... while your code (and the squarefree bookmarklet) might work on older browsers, you won't be able to get the same impact in latest versions of the browsers
A note from https://blog.mozilla.org/security/2010/03/31/plugging-the-css-history-leak/
Visited links can only be different in color: foreground, background, outline, border, SVG stroke and fill colors. All other style changes either leak the visitedness of the link by loading a resource or changing position or size of the styled content in the document, which can be detected and used to identify visited links.
Other useful references:
http://www.azarask.in/blog/post/socialhistoryjs/ - what was the security problem (and its creative use)
http://dbaron.org/mozilla/visited-privacy - approach for the fix
For CSS, you can try for something like:
a:visited {
color: white !important; /* It would hide the text if the background is white too */
/* or some better css approach for your requirement */
}

I know that you cannot find out which links have been visited with javascript anymore. This was done to protect user privacy. For security purposes, I believe that even attempting to style, or create styles for, visited links will not work in any current major browser.

For security reasons browsers have taken steps to prevent the "visited" status of links from being read by JavaScript. This means that any style you apply to ":visited" via CSS will not be registered in the DOM.
You can change things like color and text-decoration (probably), and the user will see the change on screen, but the result will not be readable to JS.
Why won't it apply "display:none"? Because if the browser were to remove the link from the page, this could alter the layout of the page, such as the height of a div, and provide a potential side channel for determining which links have been visited or not. For that reason "display:none" will not be applied.
The best solution I can suggest for your goal is to change the link color to match the background color, or perhaps modify the opacity.

Related

Image flicker and prevention. Proper coding standards

I've been working with some basic animations lately and trying to follow good web practices at the same time. The problem I'm encountering is image flicker when not using a preset css method to hide the element before the page loads.
It's very easy to prevent the flicker by just hiding the element with my normal css and then revealing it with javascript, but that seems to me a horrible practice if someone has javascript disabled.
Should I use the HTML5 feature of putting <noscript> tags in the header and then use a separate style sheet to set the opacity and position to the final settings for users without javascript? Is that the most elegant solution?
I've started using the greensock (gsap) library to TweenLite.from, since I can just set everything to the final state in the css, but I get a slight image/text flicker the first time the page is loaded. I like this solution because I can set all of the css as it will be for someone with no javascript, and it allows me to easily animate from a point, to an existing point, instead of working backwards like I have to do with Javascript or jQuery. But, there's still that image flicker which isn't really acceptable. Would a page preloader solve this?
What is the generally agreed upon practice for this these days? I'm also worried about SEO and the consequences of setting stuff to visibility: hidden or display:none and then animating it in. Does the Google spider read javascript?
Here's an example of the screen flicker and animations I'm talking about.
Have a look at HTML5 Boilerplate and Modernizr.
http://html5boilerplate.com/
http://modernizr.com/
It ships with a smart solution to see if a client has JavaScript enabled in CSS.
By default a class no-js is applied to HTML tag and it is then replaced by js by Modernizr. That way you can qualify your CSS selectors accordingly.
Example CSS:
.no-js .foo { }
.js .foo { }
This should execute fast enough that clients with enabled JavaScript don't see the no-js styles.
References:
What is the purpose of the HTML "no-js" class?
https://github.com/Modernizr/Modernizr/blob/master/src/setClasses.js#L9

Good or bad idea: Replacing all images on a mobile website with CSS property "content:url()" for retina displays

We're currently building a website for mobile devices. Supported operating systems and browsers should be:
Android 4.x (Stock Browser, Google Chrome)
iOS6+ (Safari, Google Chrome)
In order to also support high resolution displays we evaluated various techniques and libraries to automatically replace images with their high-res pendants:
Attempt 1: retina.js
http://retinajs.com/
The first attempt was to use a normal <img> Tag like this: <img src="foo.png"> and use retina.js to let it automatically replace the src Attribute with the name of the retina image (foo#2x.png). This works but has 2 downsides: First, it will create unwanted overhead because both, the original as well as the retina image, would be loaded and second, if there is no retina image available it will cause lots of 404 errors on server log which we do not want.
Attempt 2: picturefill.js
https://github.com/scottjehl/picturefill
This framework uses some weird html markup based on <span> elements. For me it looks like as if the author tried to mimic the proposed <picture> element which is not a standard (yet), see http://picture.responsiveimages.org - I don't like this approach because of the weird markup. For me it doesn't make sense to semantically describe images with spans.
Attempt 3: Replace images via CSS property background-image
I see sometimes people using CSS media queries to detect retina displays and then set a background-image on a div (or similar element) with a higher or lower solution picture. I personally don't like this approach either because it completely discourages creating semantically good markup à la <img src="foo.png">. I can't imagine building a website just with div's and then set all images as background images - This just feels very weird.
Attempt 4: Set images via CSS property content:url(...)
As proposed here Is it possible to set the equivalent of a src attribute of an img tag in CSS? it seems to be possible to overwrite the src Attribute in img Tags via CSS using the property content:url(). Now, here is the plan: We set img tags for each image with a transparent blank 1x1 png referenced in its src attribute, like this: <img id="img56456" src="transp_1x1.png" alt="img description">. Now this is semantically ok and also valid against the W3C validator. Then we load a CSS Stylesheet that sets all the images on the website via Media Queries.
Example:
#img56456{content:url(foo.png)}
#media (-webkit-min-device-pixel-ratio: 2){
#img56456{content:url(foo#2x.png)}
}
Now, this approach works pretty good:
No overhead
Solid markup
Works on the required devices/browsers
SEO for Images is not requirement here
Now, could this approach cause any side effects we didn't think of? I am just asking because I know it works but kinda "feels" weird to set all images via CSS and I also found this comment on this approach on SO Is it possible to set the equivalent of a src attribute of an img tag in CSS?:
"Worth to add that even in browsers that support assigning content to
img, it changes its behavior. The image starts to ignore size
attributes, and in Chrome/Safari it loses the context menu options
like 'Save image'. This is because assigning a content effectively
converts img from empty replaced element to something like
<span><img></span>"
Could this be a problem? (I didn't notice any sizing problems and the context menu is not a requirement)
There are lots of advantages and disadvantages, but one disadvantage is that the image won't be cached. This is more of a problem on mobile devices where internet is generally slower and more expensive for the user (if on a data connection not wifi).
I don't know about those libraries but you could use media-queries, depending on how many images you have, otherwise it would be lots of code variations to write. And have a threshold screen size at which point you use a different file. Only one file is actually loaded, even though you specify both in the media-queries.
The new version of picturefill http://scottjehl.github.io/picturefill/ doesn't rely on <span> any more. Instead it simply uses the official HTML5 srcset attribute and mimics its behavior if the browser doesn't support it, so for me this is the ideal solution after quite a while now.
Using the CSS property content:url(...) was a neat little idea but it made things a little complicated and hackish too.
So, to answer my own question: No, it's a bad idea. Using the new version of picturefill is a way better solution. You can even remove it after a while when newer versions of all major browsers support the srcset attribute and you'll still be standard compliant. http://caniuse.com/#search=srcset
Example:
<img srcset="examples/images/small.jpg, examples/images/medium.jpg 2x" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<script src="picturefill.js"></script>

Rendering bug in Google Chrome at certain window widths

My users and I are running into a rendering glitch in Chrome only (on both Windows and Mac) where an overlaid div that I'm using for on-hover tooltip-style "popouts"(see first image below) does not get rendered properly in certain cases (see second image below). In all other browsers I've tested, it works as expected.
Here's how the hover popouts are supposed to look (and what happens in Firefox, Safari, IE):
Here's what happens in Chrome:
You can see it in action on this site if you look at May 24 using a browser window width of ~ 1200px (significnatly wider or narrower windows do not seem to work). The glitch only affects the popouts in the bottom right of the menu that are popping left, e.g. those on May 24. Hovers using the same exact mechanism higher up in the page work just fine. Glitched popouts are invisible (except for part of the carat), but if you click on the link to lock the popout in place and then hold left click while moving your mouse around as if to "select text" in the area where the popout should be, it will then render partially. Also if I open dev tools and try to select the popout, it will render just fine at that point.
I've been looking at this all day and trying different work arounds with opacity, z-index, etc. and getting nowhere. Does this glitch ring any bells for anyone? Is there a way to force Chrome to render the div, once its been positioned and unhidden? I'm fine with any work-around or hack.
I use a custom (and fairly complicated) jquery plugin for popouts. If it would be helpful to see the non-minified javascript for the plugin, I can post or provide a link to that, but general guidance that leads me to a work around will be sufficient to be accepted as an answer.
Edit: My Browser Build: 26.0.1410.65
(Per my comments)
This does indeed seem to be a bug in Chrome, though without a smaller test case to reproduce it, it could be very hard to track down. You may want to report it to the Chrome team with as much information as possible.
In support of my "it's a bug" assertion:
The hidden/clipped elements become visible when they are selected.
The elements underneath the hidden/clipped elements are not clickable.
This indicates that z-index and height is correct.
It only happens under very specific circumstances; the rest of the items with the same style work fine. The same item may work fine at a slightly bigger/smaller screen width.
Applying a 3D transform fixes it.
The problem goes away when I apply a CSS transform such as scale3d or translate3d. I imagine this is because certain CSS properties cause the browser to switch to GPU acceleration.
In this case, switching to the fast path for rendering seems to alter the drawing sequence enough to fix the problem.
Super hacky but this fixes it for me:
$('.drop-link.food').on('hover',function() {
$('.tool-tip').css('overflow', 'hidden').height();
$('.tool-tip').css('overflow', 'auto');
});
Obviously this isn't a "good" solution, and even remaining hacky you could probably optimize it to only force the redraw on the tooltip it needs to, but hopefully it helps...
Another clue:
$('.drop-link').on('hover',function() {
$(this).siblings('.tool-tip').css('display','block');
});
This won't fix it right away, but it seems like if this is there, once you've hovered on something, it will work the next time you hover on it.
Not sure if this helps with your situation, but over the last couple of days I've started to notice that certain site elements on Facebook and Weight Watchers no longer show up. Specifically it seems to be affecting items that (I believe) to be controlled by or dependent on Javascript. When I call up these sites in Firefox and Safari they work as expected.

Animating opacity, opacity in general in IE

When IE renders a filter: alpha(opacity=..) whether it's on an image or text. It looks bad.
Is there a way to make IE render normal-browser-like smooth opacity?
If no, how can I easily after a fadeIn (opacity x->1) javascript animation re-render the elements so it doesn't look bad anymore..?
Applying a background colour or an opaque background image to the element should fix this problem. This is due to the way filters work, they're ActiveX components and they're old so they have certain limitations when working with partial transparency.
You can also disable the filter when the animation has completed, using something like:
myElement.filters[0].enabled = false;
A lot of animation libraries use this technique to enable the filter only during the fading so the user will not notice the ugly aliasing as much.
There's another fix (best viewed in IE to understand the point of the post), although it's more of a hack and it's not a good solution in all cases, particularly where you need to alter the size of the image.

What is the preferred way to do a CSS rollover?

When setting up a rollover effect in HTML, are there any benefits (or pitfalls) to doing it in CSS vs. JavaScript? Are there any performance or code maintainability issues I should be aware of with either approach?
CSS is fine for rollovers. They're implemented basically using the :hover pseudo-selector. Here's a really simple implementation:
a{
background-image: url(non-hovered-state.png);
}
a:hover{
background-image: url(hovered-state.png);
}
There are a few things you need to be aware of though:
IE6 only supports :hover on <a> tags
Images specified in CSS but not used on the page won't be loaded immediately (meaning the rollover state can take a second to appear first time)
The <a>-tags-only restriction is usually no problem, as you tend to want rollovers clickable. The latter however is a bit more of an issue. There is a technique called CSS Sprites that can prevent this problem, you can find an example of the technique in use to make no-preload rollovers.
It's pretty simple, the core principle is that you create an image larger than the element, set the image as a background image, and position it using background-position so only the bit you want is visible. This means that to show the hovered state, you just need to reposition the background - no extra files need to be loaded at all. Here's a quick-and-dirty example (this example assumes you have an element 20px high, and a background image containing both the hovered and non-hovered states - one on top of the other (so the image is 40px high)):
a{
background-image: url(rollover-sprites.png);
background-position: 0 0; /* Added for clarity */
height: 20px;
}
a:hover{
background-position: 0 -20px; /* move the image up 20px to show the hovered state below */
}
Note that using this 'sprites' technique means that you will be unable to use alpha-transparent PNGs with IE6 (as the only way IE6 has to render alpha-transparent PNGs properly uses a special image filter which don't support background-position)
It will still work in CSS if the browser happens to have Javascript disabled.
Because it's an aspect of presentation, I'd say it's more standards based to do it with CSS. It used to be done in Javascript, simply because we couldn't do it with CSS (old browsers suck, and I don't think :hover was even added until CSS 2).
Implementing a rollover with CSS uses the :hover pseudo-class to define the style of the target element when it is hovered over. This works great in many browsers but not in IE6 where it only works well with the anchor tag (i.e. a:hover). I used CSS hover to implement a tabbed navigation bar but had to use IE behaviors to get it working in IE6.
Yep, the best way to do this is css sprites. An annoying problem occurs in IE6, when browser make a request every time an element is hovered. To fix this, take a look here.
I'd stay on the CSS side of the house, but I've done very little Javascript.
CSS seems to be easier to standardize across browsers than Javascript, though that may be changing with the advent of Chrome's V8 and Firefox's upcoming new rendering tool.
Isn't there a mnemonic for remembering the sequence of declarations in CSS?

Categories