Have you ever filled out an address form that had a checkbox for “my shipping address differs from my mailing address”? When you click that box a conditional form part gets revealed that allows you to enter another address. We had to build something very similar the other day and stumbled on a neat way to make the conditional part show and hide with CSS only.
Continue reading
You can’t (yet) programmatically copy an image to the clipboard from a Javascript web app
Earlier this week we had an investigation chore about whether it was possible to programmatically copy an image to the clipboard in a Javascript web app.
Our conclusion was no, it’s not currently possible (at least not standardized across browsers).
While there is a draft for the HTML5 clipboard API that does look like it will support copying images to the clipboard, it isn’t yet standardized.
After the jump, I’ll explain the steps we took to reach our conclusion.
When we started investigating, we were searching for something like “javascript copy image to clipboard” and we were not finding any relevant search results.
We decided to look up how to copy text, then. A cursory web search for copying text to the clipboard in Javascript will show you a lot of people recommending Flash-based solutions like Zeroclipboard. Zeroclipboard works by using a flash movie that copies text to the clipboard when clicked.
A search through Zeroclipboard’s documentation didn’t turn up anything about images. Thankfully, Zeroclipboard is open source! Let’s find how they are doing the copy.
We went to the Actionscript (Flash’s ECMAScript-based programming language) source code for Zeroclipboard, and found this code:
// user click copies text to clipboard
// as of flash player 10, this MUST happen from an in-movie flash click event
System.setClipboard( clipText );
System.setClipboard it is. Maybe there’s a richer API than just copying text? Off to the docs!
The Actionscript docs had this to say about System.setClipboard:
This method is provided for SWF content running in Flash Player 9. It allows only adding String content to the Clipboard.
Flash Player 10 content and content in the application security sandbox in an AIR application can call the Clipboard.setData() method.
So Flash Player 10 can do something besides strings? Let’s look at the docs for Clipboard.setData.
The standard formats are:
- BITMAP_FORMAT: a BitmapData object (AIR only)
- FILE_LIST_FORMAT: an array of File objects (AIR only)
- HTML_FORMAT: HTML-formatted string data
- TEXT_FORMAT: string data
- RICH_TEXT_FORMAT: a ByteArray containing Rich Text Format data
- URL_FORMAT: a URL string (AIR only)
There you have it. If we were writing an AIR app, we could use Flash to copy an image to the clipboard; but a Flash movie embedded in a web page does not have those permissions available.
So until that draft is standardized and adopted, there seems to be no cross-browser way to programmatically copy an image to the clipboard in a web app.
Unwanted whitespace between elements
We recently came across a situation in our markup where we wanted whitespace in the markup for readability, but we didn’t want that whitespace represented between the elements.
We found a fix that suggested using font-size: 0 in CSS to eliminate the whitespace. That worked fine in Chrome, but we found that in Firefox, the containing element no longer scrolled with the mouse wheel or arrow keys! Apparently Firefox’s scroll speed is proportional to font-size.
Here’s a jsFiddle demonstrating the issue (open in Firefox to see the problem, of course).
Ultimately the best solution for us was to eliminate the whitespace in the markup. This StackOverflow question lists a couple creative ways to solve the same problem (using comments in place of whitespace, leaving the whitespace inside the tag).
The CSS3 draft (currently) specifies a text-space-collapse property, but we are targeting IE8 among other browsers, and the draft doesn’t seem to be finalized anyhow.
opacity (or, a paucity of transparency)
The rules for how to make parts of your HTML page translucent are kind of hard to understand — in other words, the opacity rules are pretty opaque. (Anyone who can make that into a good pun, let me know and I’ll change the title of this article accordingly.) The following represents the results of a couple of days of empirical research and as such may be incomplete or inadequate, but here goes.
In the brave new HTML5 world, with all the CSS gizmos supported by Safari and Chrome and Firefox, there are now three ways to make things translucent. And none of them works quite the way I naïvely expected.
One. Use the “opacity” CSS attribute. This attribute works pretty well… at first. It applies to an element and all its children, but according to the spec it’s meant to act as an upper bound on the opacity of all its children, and while it can technically be overridden, the overridden value is applied as a multiplier to the previous value, not as a whole separate value. So if you want some fully opaque children inside a translucent container, you can’t get there from here. The children are always going to be at least as transparent as the parent — in other words, they can’t transcend their parent’s transparency.
This is spelled out in detail in https://developer.mozilla.org/En/Useful_CSS_tips/Color_and_Background and as a solution they propose either pulling the child out of the normal hierarchy (ugh — that means you lose all the other CSS inherited styles and positioning), or …
Two. Make an alpha channel PNG and use it as the parent’s background, probably with background-repeat:repeat. This is adequate, except that there’s now another, cleaner way…
Three. For the parent, use background-color: rgba(255, 255, 255, 0.5) (where ’0.5′ is the opacity and ’255,255,255′ is the decimal RGB value) — that will work the same as an alpha PNG but without needing to go round-trip to Photoshop every time you want to change the color or level. Much better.
I have no idea what the level of support for rgba background colors is, but it seems to work in the latest Safari and Firefox so I’m happy.