Blog

Posts tagged with “HTML”

Mobile Browsers lost their :FOCUS

 

Alright,
I had been hoping to display a CSS user interaction technique that would make context sensitive drop-down menus, but it unfortunately doesn't work on current mobile phones (webkit based ones, at any rate). The problem is the mobile browsers don't recognize :FOCUS on any element other than text entry areas.

See, according to W3C's HTML5 recommendation (and implemented in all modern desktop browsers), any element can receive user focus if they have a "tabindex" attribute assigned to them. If that value is a positive number, they then also enter the tab sequence for keyboard navigation. It also means that, in desktop browsers, clicking on the element allows the client to render special :FOCUS selector, that is normally reserved mostly for form elements and links. With a little bit of work, one can create a nice little context menu as follows:

HTML:

<div tabindex="1" class="opt-sel">Options
  <ul tabindex="0"><!-- this needs a tabindex too, to allow styling it's :ACTIVE state to allow for a complete "click" of it's children -->
    <li><a href="#1">Option 1</a></li>
    <li><a href="#2">Option 2</a></li>
    <li><a href="#3">Option 3</a></li>
    <li><a href="#4">Option 4</a></li>
  </ul>
</div>

CSS (the effective bits):

.opt-sel UL {
   position:absolute;
   list-style:none;
   padding:0;
   margin:0;
}
.opt-sel:NOT(:FOCUS) UL { /* only hide the sub-menu in modern browsers */
  display:none;
}
.opt-sel:FOCUS UL,
.opt-sel UL:ACTIVE { 
/*
A child element's mousedown event causes said element to pull focus away 
from the parent div and disappear immediately, and disables any "click" 
from occurring. Styling the UL's :ACTIVE state keeps the child elements 
around until mouseup, and lets the click happen.
*/     
  display:block;
}

And, on desktop browsers, this works great. Click on the word "options", and a list of options appears and stays open until you click somewhere else. If you click one of the available options, the desired action occurs and the list nicely disappears. Now, it's not perfect — you can't tab through the options, for example (though, you should be able to) but it's no worse than current :HOVER menus.

Now, one would expect this to work beautifully on a touchscreen/mobile environment. Unfortunately it doesn't. Instead, what happens is clicking (or touching) on a tabindex'ed element results in the rendering of a :HOVER selector — :FOCUS is completely ignored. Not only that, but :FOCUS doesn't even effect the usual suspects. Only elements that accept keyboard interaction are allowed to use :FOCUS state — and only when they do need a keyboard; setting readonly="readonly" removes the :FOCUS state. I assume that the reason for this is that many pre-mobile site's navigation systems broke when :HOVER disappeared. And it makes sense. Touch screens can't tell you if you're hovering, only if you're touching. So, instead of following standards, mobile browsers rewarded laziness, and changed the rules. Problem is, the only way to make something recognize :HOVER is by setting a tabindex value, which means it still won't be used by the lazy coders this change was trying to appease — and it hijacks the first click on an element to set :HOVER, requiring users to click (or touch) twice.

What should happen, in my opinion (and the W3C's as well, if I read the latest recommendation correctly) is that :HOVER should be ignored (or at least mimic :ACTIVE) on touch screens, since they don't use "pointing devices" and :FOCUS should work on any element that accepts tab navigation. Don't break things to appease lazy coding. That's what made IE6 and quirks mode happen to us.

Tags: , ,
2013.02.04 09:51 AM | Permalink 0 Comments

CSS3 Pie Charts Revisited

Quite a while back I figured out how to create pie charts using nothing but CSS and a handful of HTML tags.

In the original method, I used at least two nested elements to create each segment of the pie chart. Well, turns out I figured out how to make it use even less HTML. I now use BEFORE: and (occasionally) :AFTER pseudo elements.

<div class="pie" data-start="0" data-value="30"></div>
<div class="pie highlight" data-start="30" data-value="30"></div>
<div class="pie" data-start="60" data-value="40"></div>
<div class="pie big" data-start="100" data-value="260"></div>

The other thing I did differently with the HTML was to remove ID's for each element in favour of adding data- attributes. You could just as easily use class names like s30 and v30, but I will explain why I like the data attributes later. I was also able to remove the clip workaround to WebKit's now fixed changing an element's transform-position negates border-radius bug.

The technique remains essentially the same. for each piece; convert the inner element (or pseudo element in this case) into a half circle, and hide it from view by setting the outer element to overflow:hidden. Rotate both outer and inner elements to place and size the pie piece. For pieces larger than 50% of the entire pie's volume, use a second (pseudo) element as filler.

as for why I prefer data- attributes over classes, it's so I can complain about the lack of support for the proposed W3C CSS3 attr() function, which would make this technique truly awesome. Instead of creating custom style rules for each possible value of data-start and data-value, I could replace them with two rules:

.pie {
   transform:rotate(attr(data-start,deg,0);
}
.pie:BEFORE {
   transform:rotate(attr(data-value,deg,0);
}

Check out the code in action, or even play with it yourself on Code Pen

Tags: , , ,
2013.01.26 04:09 PM | Permalink 0 Comments

Analogue flip-clock wiith CSS3 and jQuery

After creating pie charts and international flags with CSS3's border-radius and transform:rotate, I figured I'd try the other transformations available; specifically, skew and scale. By combining these two features with a bit of jQuery to animate, I created a rather nifty retro-styled analogue flip-clock.

Now, this is just a proof of concept, but it could fairly easily be turned into a count down clock, or dynamically incrementing "total donations" type display. To show this functionality, I've added a reset to start the clock at 12:00;00 am, making it flip forward to the current time.

As with the other CSS3 experiments, it currently only works in Firefox, Google Chrome, and Safari (which loses the rounded corners due to an interaction bug with transform-origin and border radius) UPDATE and Opera 10.5. One the nice thing about this experiment, as opposed to the other two, is that the clock still works in IE, even though the flip animation is missing.

Tags: , , ,
2010.02.22 12:20 PM | Permalink 2 Comments

Creating Pie Charts with CSS3

After playing around and creating flags with CSS3, it dawned on me that the same methods used there could be used to create Pie charts. Keep in mind that this technique is currently cutting-edge. It only works in the latest versions of Firefox, Chrome,and Safari UPDATE and Opera; and requires browser-specific extensions to CSS to pull off, but it does use elements in the current CSS3 specification, so it stands that eventually the rest of the web will catch up.

UPDATE 2 I've completely overhauled this technique. Here's an explination of how and the new code/example on CodePen

First off, you need to draw a circle, which is easy enough, simply create a square <div> and set border-radius to be half it's height/width

.circle {
position:absolute;
background-color:red;
width:200px;
height:200px;
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
}

Next, we have to cut that in half. Normally, one would smply draw a half circle like so:

.half-circle {
position:absolute;
background-color:red;
width:100px;
height:200px;
-moz-border-radius:100px 0 0 100px;
-webkit-border-radius:100px 0 0 100px;
border-radius:100px 0 0 100px;
}

However, this method becomes problematic, since we'll have to rotate it. The half-circle above would rotate at it's centre (left-50,top-100). Combine that with the difference  in width and length,  it would require a lot of horizontal shifting to ensure the centres line up properly. That's a bunch of math or annoying trial and error. Thankfully, there's an easier way. Draw a full circle and use the old-school clip property to only show half:

.pie {
position:absolute;
width:200px;
height:200px;
clip:rect(0px,100px,200px,0px);
-moz-border-radius:100px;
-webkit-border-radius:100px;
border-radius:100px;
}

NOTE: you could use the original half-circle method and set the CSS3 transform-origin property to right, center to move the rotation point. But experimentation with this method revealed that using transform-origin in Safari caused that browser to ignore the border-radius setting (in Safari ver. 4.04 on Windows at least). So for now, stick with full circle and clip.

Now we have a half circle that will rotate around the centre of it's flat edge.

Next, we need to hide it in a way that allows us to show only the part we need to see. So we drop it into another square <div> and clip it too, to display the opposite half.

.hold {
position:absolute;
width:200px;
height:200px;
clip:rect(0px,200px,200px,100px);
}

We're clipping the hold <div>, because we need it to rotate around the same point as the circle.

now we stack all the pie elements on top of each other, and rotate the pie pieces by their appropriate percentage amount — (360*(x*100)) where x is the percentage value — and also rotate each hold div the cumulative amount of each previous pie piece's rotation. So given the following html:

<div id="piece1" class="hold">
<div class="pie"></div>
</div>
<div id="piece3" class="hold">
<div class="pie"></div>
</div>
<div id="piece3" class="hold">
<div class="pie"></div>
</div>

we can add the following CSS to create a pie chart with three equal pieces:

#piece1 {

}
#piece1 .pie {
color:red;
-moz-transform:rotate(120deg);
-webkit-transform:rotate(120deg);
-o-transform:rotate(120deg);
transform:rotate(120deg);
}
#piece2 {
-moz-transform:rotate(120deg);
-webkit-transform:rotate(120deg);
-o-transform:rotate(120deg);
transform:rotate(120deg);
}
#piece2 .pie {
color:green;
-moz-transform:rotate(120deg);
-webkit-transform:rotate(120deg);
-o-transform:rotate(120deg);
transform:rotate(120deg);
}
#piece3 {
-moz-transform:rotate(240deg);
-webkit-transform:rotate(240deg);
-o-transform:rotate(240deg);
transform:rotate(120deg);
}
#piece3 .pie {
color:blue;
-moz-transform:rotate(120deg);
-webkit-transform:rotate(120deg);
-o-transform:rotate(120deg);
transform:rotate(120deg);
}

Now, the more astute readers will notice that this works great for pie pieces that are 50% of the pie or less. How can you draw larger pieces? There are two methods. The easiest is to simply draw a full circle and then overlay the other pieces on top. But if you want a discrete piece that you can potentially move out for emphasis, you'll need to do two things: remove the clip on the hold <div>, and add a second pie piece as filler.

.hold.gt50 {
clip:rect(auto, auto, auto, auto);
}
.pie.fill {
-moz-transform:rotate(180deg) !important;
-webkit-transform:rotate(180deg) !important;
transform:rotate(180deg) !important;
}

That's it.

Here's the code in action

Tags: , ,
2010.02.20 12:30 PM | Permalink 9 Comments

Pure CSS3 Canadian Flag (and a few others)

I happened upon a few impressive international flags made out of XHTML and CSS through Smashing Magazine's twitter feed and noticed that there was a certain flag near and dear to my heart was missing. So I created a pure CSS3 Canadian flag.

As you might be able to tell, I found it easier to draw the white outline around the center leaf, instead of the leaf itself. It's done primarily with border-radius  and transform:rotate CSS3 properties, so it only works with the latest versions of Firefox, Safari (which does the best job of rendering it) and Chrome right now. UPDATE 2010.03.02: It works in just released Opera 10.5 now too. I had to add the browser-specific extention for rotate, but it works.

This was so much fun, I decided to do a few others:

The Macedonian CSS3 Flag. - This is barely CSS3 as it only uses border-radius for the center. It looks best in Firefox, but works relatively well in Safari and Chrome too.

The Kenyan CSS3 Flag. Which is actually more impressive than the Canadian flag, if I say so myself. It looks awesome in Firefox and Chrome. Oddly, it failed badly in my version of Safari (4.04 Windows) though. I think it has to do with the fact that I'm combining the border-radius property and a bit of rotating with some old school clip'ing It appears that Safari doesn't yet support the dual value ( r1 / r2 ) eliptical border-radius sttings.

And for those of you using IE, here's some classic CSS flags to look at:

Pure CSS Jamacian Flag.

Pure CSS South African Flag.

Tags: , ,
2010.02.17 12:39 AM | Permalink 0 Comments
Next → Page 1 of 2