/
atom.xml
2848 lines (2149 loc) · 233 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[TJ VanToll]]></title>
<link href="http://tjvantoll.com/atom.xml" rel="self"/>
<link href="http://tjvantoll.com/"/>
<updated>2013-01-08T21:18:43-05:00</updated>
<id>http://tjvantoll.com/</id>
<author>
<name><![CDATA[TJ VanToll]]></name>
<email><![CDATA[tj.vantoll@gmail.com]]></email>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Using the body Element as a Top Level Container - Is it Safe Yet?]]></title>
<link href="http://tjvantoll.com/2013/01/05/is-it-safe-to-use-the-body-as-a-top-level-container-yet/"/>
<updated>2013-01-05T14:21:00-05:00</updated>
<id>http://tjvantoll.com/2013/01/05/is-it-safe-to-use-the-body-as-a-top-level-container-yet</id>
<content type="html"><![CDATA[<p>View source on almost any web page and you’ll likely see the following:</p>
<figure class='code'><figcaption class='not_empty'><span>Common HTML Template</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><html></span>
</span><span class='line'> <span class="nt"><head></head></span>
</span><span class='line'> <span class="nt"><body></span>
</span><span class='line'> <span class="nt"><div</span> <span class="na">id=</span><span class="s">"wrapper"</span><span class="nt">></span>
</span><span class='line'> <span class="c"><!-- All the things --></span>
</span><span class='line'> <span class="nt"></div></span>
</span><span class='line'> <span class="nt"></body></span>
</span><span class='line'><span class="nt"></html></span>
</span></code></pre></td></tr></table></div></figure>
<p>The use of a wrapper or container <code>div</code> around the page is fairly universal. It is commonly used to perform tasks such as centering a page’s content or providing a shadow or border to frame it. But, since the <code>body</code> element is a necessity in the markup, why can’t it be styled directly instead? Why is a wrapper <code>div</code> used?</p>
<p>Historically there have been a number of issues with using the <code>body</code> element as a top level container in old versions of Internet Explorers. If you’re supporting IE >= 8 you’re good, but there are some things <a href="#now">you should be aware of</a>.</p>
<!--more-->
<h3>IE 5.5</h3>
<p>To get to the origins of the wrapper <code>div</code> let’s go way back. A pretty common practice is to center the top level container using <code>margin: 0 auto</code>, and this works fine in all browsers… back to IE 5.5. IE 5.5 did not support <code>auto</code> margins so this approach did not work.</p>
<p>To center the top level container in IE 5.5 you had to make use of <code>text-align: center</code> as such:</p>
<figure class='code'><figcaption class='not_empty'><span>Centering the top level container in IE 5.5</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">body</span> <span class="p">{</span>
</span><span class='line'> <span class="k">text-align</span><span class="o">:</span> <span class="k">center</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nf">#wrapper</span> <span class="p">{</span>
</span><span class='line'> <span class="k">width</span><span class="o">:</span> <span class="m">1000px</span><span class="p">;</span>
</span><span class='line'> <span class="k">text-align</span><span class="o">:</span> <span class="k">left</span><span class="p">;</span> <span class="c">/* counteract the declaration on body */</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p><code>text-align: center</code> <em>should</em> only affect inline elements, but IE 5.5 incorrectly applied it to block elements as well. (Note: The <code>text-align: center</code> bug was fixed in IE6 standards mode, but the behavior remained in Internet Explorer’s quirks mode to this day.)</p>
<h3>IE6</h3>
<p>IE6 implemented <code>auto</code> margins, so <code>margin: 0 auto</code> was now safe to use on the <code>body</code>. Additionally, IE6 fully supports adding a <code>width</code>, <code>padding</code>, <code>margin</code>, and <code>border</code> to the body element. Take the following CSS:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">body</span><span class="p">{</span>
</span><span class='line'> <span class="k">width</span><span class="o">:</span> <span class="m">90</span><span class="o">%</span><span class="p">;</span>
</span><span class='line'> <span class="k">border</span><span class="o">:</span> <span class="m">2px</span> <span class="k">solid</span> <span class="nb">red</span><span class="p">;</span>
</span><span class='line'> <span class="k">background-color</span><span class="o">:</span> <span class="nb">black</span><span class="p">;</span>
</span><span class='line'> <span class="k">color</span><span class="o">:</span> <span class="nb">white</span><span class="p">;</span>
</span><span class='line'> <span class="k">padding</span><span class="o">:</span> <span class="m">10px</span><span class="p">;</span>
</span><span class='line'> <span class="k">margin</span><span class="o">:</span> <span class="m">0</span> <span class="k">auto</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>The layout renders the same in IE6 as it does in the latest version of Chrome (23 as of this writing).</p>
<div style="overflow: hidden;">
<div style="float: left; width: 49%;">
<h4>IE6</h4>
<img title="Styling the body element in IE6" src="http://tjvantoll.com/images/posts/2013-01-05/IE6.png">
</div>
<div style="float: right; width: 49%;">
<h4>Chrome</h4>
<img title="Styling the body element in Chrome" src="http://tjvantoll.com/images/posts/2013-01-05/Chrome.png">
</div>
</div>
<p>Believe it or not using the <code>body</code> element as a top level container is actually safe in IE6.</p>
<p><a name="zoom"></a></p>
<h3>IE7</h3>
<p>If there are no issues with IE6 why am I still writing? IE7 introduced a feature new to Internet Explorer, zoom, and with it came a new bug.</p>
<p>When a <code>margin</code> or <code>width</code> is applied to the <code>body</code> and the user zooms, IE7 incorrectly treats the left edge of the <code>body</code> as the edge of the viewport. This shift bumps content on the right hand side of the page outside of the screen. The image below shows the result of a zoomed in window and styled <code>body</code> in IE7.</p>
<p><img src="http://tjvantoll.com/images/posts/2013-01-05/IE7Zoom.png" title="Zooming in IE7" style="max-height: 400px;"></p>
<p>This issue is not present using a wrapper <code>div</code>.</p>
<h3>Beyond IE7</h3>
<p>In my testing beyond IE7 there are no major issues using the <code>body</code> element as a top level container. There are however a few things to be aware of.</p>
<p><a name="now"></a></p>
<h3>Positioning</h3>
<p>Any absolutely positioned elements will be positioned relative to the viewport rather than the newly placed <code>body</code>. To fix this set <code>position: relative</code> on the <code>body</code> as such:</p>
<figure class='code'><figcaption class='not_empty'><span>Positioning elements relative to the body rather than the viewport</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">body</span> <span class="p">{</span>
</span><span class='line'> <span class="k">margin</span><span class="o">:</span> <span class="m">0</span> <span class="k">auto</span><span class="p">;</span>
</span><span class='line'> <span class="k">width</span><span class="o">:</span> <span class="m">90</span><span class="o">%</span><span class="p">;</span>
</span><span class='line'> <span class="k">position</span><span class="o">:</span> <span class="k">relative</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h3>Backgrounds</h3>
<p>Backgrounds applied to the <code>body</code> will take up whole page regardless of margins. Consider the following:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">body</span> <span class="p">{</span>
</span><span class='line'> <span class="k">background</span><span class="o">:</span> <span class="nb">black</span><span class="p">;</span>
</span><span class='line'> <span class="k">margin</span><span class="o">:</span> <span class="m">0</span> <span class="k">auto</span><span class="p">;</span>
</span><span class='line'> <span class="k">width</span><span class="o">:</span> <span class="m">200px</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Here, the background of the entire viewport will be black rather than a centered 200px block.</p>
<p><img src="http://tjvantoll.com/images/posts/2013-01-05/background-before.png" title="background on a body element" style="max-height: 300px;"></p>
<p>Luckily, this can be worked around by applying a <code>background</code> on the <code>html</code> element.</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">html</span> <span class="p">{</span>
</span><span class='line'> <span class="k">background</span><span class="o">:</span> <span class="nb">white</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="nt">body</span> <span class="p">{</span>
</span><span class='line'> <span class="k">background</span><span class="o">:</span> <span class="nb">black</span><span class="p">;</span>
</span><span class='line'> <span class="k">margin</span><span class="o">:</span> <span class="m">0</span> <span class="k">auto</span><span class="p">;</span>
</span><span class='line'> <span class="k">width</span><span class="o">:</span> <span class="m">200px</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Which renders as expected:</p>
<p><img src="http://tjvantoll.com/images/posts/2013-01-05/background-after.png" title="background on a body element with background on html element" style="max-height: 300px;"></p>
<h3>scrollHeight and scrollWidth</h3>
<p>In WebKit based browsers the <code>body</code>’s <a href="https://developer.mozilla.org/en-US/docs/DOM/element.scrollHeight">scrollHeight</a> and <a href="https://developer.mozilla.org/en-US/docs/DOM/element.scrollWidth">scrollWidth</a> properties are unaffected by declared <code>height</code> and <code>width</code> styles. For example:</p>
<figure class='code'><figcaption class='not_empty'><span>scrollHeight and scrollWidth on the body element</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><html></span>
</span><span class='line'> <span class="nt"><head></head></span>
</span><span class='line'> <span class="nt"><body</span> <span class="na">style=</span><span class="s">"height: 200px; width: 200px;"</span><span class="nt">></span>
</span><span class='line'> <span class="nt"><script></span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">scrollHeight</span><span class="p">);</span>
</span><span class='line'> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nx">scrollWidth</span><span class="p">);</span>
</span><span class='line'> <span class="nt"></script></span>
</span><span class='line'> <span class="nt"></body></span>
</span><span class='line'><span class="nt"></html></span>
</span></code></pre></td></tr></table></div></figure>
<p>This will log <code>200</code> for both in all modern browsers with the exception of WebKit based ones. WebKit will return the height and width of the viewport.</p>
<p>While you are unlikely to run into this directly, you may use a library that does. For example, this <a href="http://bugs.jqueryui.com/ticket/8940">causes an issue</a> trying to constrain <a href="http://jqueryui.com/draggable/">jQuery UI draggables</a> within the <code>body</code>.</p>
<h3>Is it Safe to Use Yet?</h3>
<p>The <a href="#zoom">zoom issue in IE7</a> is bad, but if you’re no longer supporting IE7 it’s safe to drop the wrapper <code>div</code> and style the <code>body</code> directly.</p>
<p>That being said, there’s no harm in leaving a wrapper <code>div</code> in place. So if you have any doubt stick with <code><div id="wrapper"></div></code>.</p>
<p>Know of any other bugs with styling the <code>body</code> element? Let me know in the comments.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[The Enter Key should Submit Forms, Stop Suppressing it]]></title>
<link href="http://tjvantoll.com/2013/01/01/enter-should-submit-forms-stop-messing-with-that/"/>
<updated>2013-01-01T15:54:00-05:00</updated>
<id>http://tjvantoll.com/2013/01/01/enter-should-submit-forms-stop-messing-with-that</id>
<content type="html"><![CDATA[<p>I try to do most of my work and play on the internet with the keyboard. In the course of my internet-ing there’s one unfortunate trend that I’ve noticed; an increasing number of sites are not allowing the enter key to submit a form. Before I tell you why you care, let’s look at how this should work.</p>
<!--more-->
<h3>Enter = Submit</h3>
<p>Take the following basic form:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><form></span>
</span><span class='line'> <span class="nt"><label</span> <span class="na">for=</span><span class="s">"name"</span><span class="nt">></span>Name:<span class="nt"></label></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"Submit"</span><span class="nt">></span>
</span><span class='line'><span class="nt"></form></span>
</span></code></pre></td></tr></table></div></figure>
<p>If you have focus in the textbox and hit enter, the form will be submitted automatically. This behavior is consistent across all browsers and is known as implicit submission. So why is this important?</p>
<h3>Accessibility</h3>
<p>Implicit submission is vital to assistive technologies and impaired users that cannot use a mouse at all. From the HTML5 specification:</p>
<blockquote><p>There are pages on the Web that are only usable if there is a way to implicitly submit forms, so user agents [browsers] are strongly encouraged to support this.</p><footer><strong>HTML 5 specification</strong> <cite><a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#implicit-submission'>www.whatwg.org/specs/web-apps/…</a></cite></footer></blockquote>
<p>The spec strongly encourages browsers to allow implicit submission; they all do.</p>
<h3>User Expectations</h3>
<p>Many users have an expectation that implicit submission will just work. Interfering with this leads to a negative user experience for these users.</p>
<h3>How to Prevent Implicit Submission</h3>
<p>What are sites doing to keep this from happening? Here’s a few things I’ve seen.</p>
<h4>No Submit Buttons</h4>
<p>Many sites do not have a submit button within the form. From the spec here’s how browsers determine what to do when enter is clicked.</p>
<blockquote><p>If the user agent supports letting the user submit a form implicitly (for example, on some platforms hitting the “enter” key while a text field is focused implicitly submits the form), then doing so for a form whose default button has a defined activation behavior must cause the user agent to run synthetic click activation steps on that default button.</p><footer><strong>HTML 5 specification</strong> <cite><a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#implicit-submission'>www.whatwg.org/specs/web-apps/…</a></cite></footer></blockquote>
<p>Basically, if the user hits enter when a text field is focused, the browser should find the first submit button in the form and click it.</p>
<blockquote><p>If the form has no submit button, then the implicit submission mechanism must do nothing if the form has more than one field that blocks implicit submission, and must submit the form element from the form element itself otherwise.</p><p>For the purpose of the previous paragraph, an element is a field that blocks implicit submission of a form element if it is an input element whose form owner is that form element and whose type attribute is in one of the following states: Text, Search, URL, Telephone, E-mail, Password, Date and Time, Date, Month, Week, Time, Local Date and Time, Number</p><footer><strong>HTML 5 specification</strong> <cite><a href='http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#implicit-submission'>www.whatwg.org/specs/web-apps/…</a></cite></footer></blockquote>
<p>So, in a form with no submit buttons, implicit submission will be done if only one input is present. Therefore, pressing enter in this textbox will submit the form:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><form></span>
</span><span class='line'> <span class="nt"><label</span> <span class="na">for=</span><span class="s">"name"</span><span class="nt">></span>Name:<span class="nt"></label></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">></span>
</span><span class='line'><span class="nt"></form></span>
</span></code></pre></td></tr></table></div></figure>
<p>But in this form it will not because there are multiple fields:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><form></span>
</span><span class='line'> <span class="nt"><label</span> <span class="na">for=</span><span class="s">"name"</span><span class="nt">></span>Name:<span class="nt"></label></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">></span>
</span><span class='line'> <span class="nt"><label</span> <span class="na">for=</span><span class="s">"address"</span><span class="nt">></span>Address:<span class="nt"></label></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"address"</span> <span class="na">id=</span><span class="s">"address"</span><span class="nt">></span>
</span><span class='line'><span class="nt"></form></span>
</span></code></pre></td></tr></table></div></figure>
<p>Therefore, if you have a form with more than one input field, always include a submit button. Specifically an <code><input></code> with the <code>type="submit"</code> attribute, or a <code><button></code> element should be present. (Note: IE7 has a bug where the <code>type</code> attribute of a <code><button></code> defaults to <code>button</code> instead of <code>submit</code>. Therefore for IE7 compatibility you’ll need <code><button type="submit"></code>.)</p>
<p>If you need to run some JavaScript before the form is submitted (validation, data manipulation, etc), do it in a <code>submit</code> event handler on the form, not a <code>click</code> handler on a button.</p>
<h4>No <form></h4>
<p>I’ve seen a few forms that do not use the <code><form></code> HTML tag. Why would they do that?</p>
<p>With modern day browsers and JavaScript libraries it’s easy to send data to the server via AJAX. Because an AJAX request does not require a true <code><form></code> tag, it is often omitted. However, much like implicit submission, surrounding form data with a true <code><form></code> tag is vital for accessibility. Most screen readers have a <a href="http://www.htctu.fhda.edu/trainings/manuals/tutorials/readweb/forms.htm">mode specifically for filling out forms</a>, and by omitting a true <code><form></code> tag you risk this mode not being activated.</p>
<h4>Explicit Prevention</h4>
<p>Finally, it’s also quite easy to prevent implicit submission in JavaScript. Take the following example:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><form></span>
</span><span class='line'> <span class="nt"><label</span> <span class="na">for=</span><span class="s">"name"</span><span class="nt">></span>Name:<span class="nt"></label></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">name=</span><span class="s">"name"</span> <span class="na">id=</span><span class="s">"name"</span><span class="nt">></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"submit"</span> <span class="na">value=</span><span class="s">"Submit"</span><span class="nt">></span>
</span><span class='line'><span class="nt"></form></span>
</span><span class='line'><span class="nt"><script></span>
</span><span class='line'> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'name'</span><span class="p">).</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">'keypress'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'><span class="nt"></script></span>
</span></code></pre></td></tr></table></div></figure>
<p>This sets up a <code>keypress</code> event handler that prevents the default action (implicit submission) from occurring when the enter key is pressed.</p>
<p>This technique can be handy. For example, say you have a form with multiple submit buttons. As we saw earlier, the implicit submission algorithm will click the first submit button that it finds. Therefore, if you need control over which submit button is clicked, you can use the above technique to listen an for enter keypress, prevent the default action, then explicitly click the appropriate button.</p>
<p>Take the following example:</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><form></span>
</span><span class='line'> <span class="nt"><label</span> <span class="na">for=</span><span class="s">"age"</span><span class="nt">></span>Age:<span class="nt"></label></span>
</span><span class='line'> <span class="nt"><input</span> <span class="na">type=</span><span class="s">"number"</span> <span class="na">min=</span><span class="s">"0"</span> <span class="na">max=</span><span class="s">"120"</span> <span class="na">name=</span><span class="s">"age"</span> <span class="na">id=</span><span class="s">"age"</span><span class="nt">></span>
</span><span class='line'> <span class="nt"><button</span> <span class="na">id=</span><span class="s">"child"</span><span class="nt">></span>Child<span class="nt"></button></span>
</span><span class='line'> <span class="nt"><button</span> <span class="na">id=</span><span class="s">"adult"</span><span class="nt">></span>Adult<span class="nt"></button></span>
</span><span class='line'><span class="nt"></form></span>
</span><span class='line'><span class="nt"><script></span>
</span><span class='line'> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">age</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'age'</span><span class="p">);</span>
</span><span class='line'> <span class="nx">age</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="s1">'keypress'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="nx">event</span><span class="p">.</span><span class="nx">keyCode</span> <span class="o">==</span> <span class="mi">13</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">event</span><span class="p">.</span><span class="nx">preventDefault</span><span class="p">();</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="nx">age</span><span class="p">.</span><span class="nx">value</span> <span class="o">></span> <span class="mi">20</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'adult'</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span>
</span><span class='line'> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="s1">'child'</span><span class="p">).</span><span class="nx">click</span><span class="p">();</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'> <span class="p">}());</span>
</span><span class='line'><span class="nt"></script></span>
</span></code></pre></td></tr></table></div></figure>
<p>When enter is clicked in the number input, the <code>keypress</code> event handler determines which submit button is appropriate and clicks it.</p>
<p>While this technique can be handy, I’ve seen it used plenty of times to completely prevent implicit submission from working. Don’t do that.</p>
<h3>Conclusion</h3>
<p>When filling out a form, pressing enter in a textbox should submit the form. This is known as an implicit form submission. Despite being vital for assistive technologies and an important user convenience, many web forms prevent it for one reason or another. If you write web forms, please take a minute to ensure that the enter key can indeed be used to submit them; it’ll help make the web a better place for everyone.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Debugging Print Stylesheets: Now Significantly Easier in Chrome]]></title>
<link href="http://tjvantoll.com/2012/12/12/debugging-print-stylesheets-now-significantly-easier-in-chrome/"/>
<updated>2012-12-12T21:55:00-05:00</updated>
<id>http://tjvantoll.com/2012/12/12/debugging-print-stylesheets-now-significantly-easier-in-chrome</id>
<content type="html"><![CDATA[<p>Debugging print stylesheets has always been a bit of a pain. The traditional way of doing so was to manually change the <code>media</code> attribute of all <code>link</code> tags from <code>print</code> to <code>screen</code> or <code>all</code> while testing.</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="c"><!-- Before --></span>
</span><span class='line'><span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"print.css"</span> <span class="na">media=</span><span class="s">"print"</span> <span class="nt">/></span>
</span><span class='line'>
</span><span class='line'><span class="c"><!-- After --></span>
</span><span class='line'><span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"print.css"</span> <span class="na">media=</span><span class="s">"screen"</span> <span class="nt">/></span>
</span></code></pre></td></tr></table></div></figure>
<p>The popular <a href="https://addons.mozilla.org/en-US/firefox/addon/web-developer/">Web Developer Add-on</a> for Firefox even has an option to do this for you automatically.</p>
<!--more-->
<p><img src="http://tjvantoll.com/images/posts/2012-12-12/Web_Developer.png" title="Web Developer Add-on" alt="Web Developer Add-on" /></p>
<p>Then something changed.</p>
<p>We found out that <a href="https://developers.google.com/speed/docs/best-practices/rtt">unnecessary HTTP requests are bad</a>. We also found out that there are some <a href="http://www.phpied.com/5-years-later-print-css-still-sucks/">serious performance issues with print stylesheets</a>.</p>
<p>Therefore, following the lead of projects like the <a href="http://html5boilerplate.com/">HTML5 Boilerplate</a> we all switched to writing our print styles inline with the rest of our CSS.</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="k">@media</span> <span class="nt">print</span> <span class="p">{</span>
</span><span class='line'> <span class="nt">body</span> <span class="p">{</span> <span class="k">font-size</span><span class="o">:</span> <span class="k">larger</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'> <span class="nf">#ads</span><span class="o">,</span> <span class="nf">#junk</span> <span class="p">{</span> <span class="k">display</span><span class="o">:</span> <span class="k">none</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Inline print styles save HTTP requests and are easier to maintain, but they unfortunately make testing a bit harder. They don’t work with Firefox’s Web Developer Add-on and a simple find and replace is now quite a bit harder.</p>
<h3>Good News!</h3>
<p>A means to emulate the <code>print</code> media type has <a href="https://plus.google.com/115133653231679625609/posts/MgpioU84JPe">just landed in Chrome Canary</a>.</p>
<p>To use it, first open up the settings by clicking on the gear in the bottom right corner of the DevTools:</p>
<p><img src="http://tjvantoll.com/images/posts/2012-12-12/DevTools_1.png" title="How to open the DevTools settings" alt="How to open the DevTools settings" /></p>
<p>Next, select the Overrides menu, check the “Emulate CSS media” checkbox, and select “print”.</p>
<p><img src="http://tjvantoll.com/images/posts/2012-12-12/DevTools_2.png" title="How to emulate CSS media in Chrome's DevTools" alt="How to emulate CSS media in Chrome's DevTools" /></p>
<p>That’s it! This will apply both rules defined in external <code>media="print"</code> stylesheets as well as rules within inline <code>@media print {}</code> blocks. For bonus points, combine this with an application like <a href="http://livereload.com/">LiveReload</a> that can apply CSS changes without refreshing the page and you have a robust means of developing and debugging print stylesheets.</p>
<p>This feature was added in version 25 of Chrome Canary so it hopefully will make it into Chrome stable around Chrome 27. If you don’t have Canary yet you should consider <a href="http://paulirish.com/2012/chrome-canary-for-developers/">installing it side by side</a> with the stable release.</p>
<h3>WON’T SOMEONE THINK ABOUT THE TREES</h3>
<p>Of course, the definitive way of testing print stylesheets is to physically print a web page on actual pieces of paper. I’ve done this plenty of times. And if you’ve read this far you likely have to. Hopefully the next time you have to debug printing you can save a bit of paper.</p>
<p><img src="http://tjvantoll.com/images/posts/2012-12-12/trees.jpg" title="The less pages you print the more of my type get to live" alt="The less pages you print the more of my type get to live" />
<a href="http://www.flickr.com/photos/cransell/5119828609/" style="display: block; font-size: 0.8em;">Photo Credit</a></p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Creating Cross Browser Scrollable <tbody>s - A CSS Only Approach]]></title>
<link href="http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody/"/>
<updated>2012-11-10T15:44:00-05:00</updated>
<id>http://tjvantoll.com/2012/11/10/creating-cross-browser-scrollable-tbody</id>
<content type="html"><![CDATA[<p>By default the <code>overflow</code> CSS property does not apply to table group elements (<code><thead></code>, <code><tbody></code>, or <code><tfoot></code>). <a href="https://developer.mozilla.org/en-US/docs/Firefox_4_for_developers#Miscellaneous_CSS_changes">As of Firefox 4</a> this behavior is consistent across all browser implementations.</p>
<p>Therefore, if you attempt to apply a CSS <code>height</code> and <code>overflow: scroll</code> to a <code><tbody></code> it will have no effect in modern browsers. You can see this for yourself <a href="http://jsfiddle.net/tj_vantoll/vU494/">here</a>.</p>
<p>But having a scrolling table body with fixed headers is a useful UI element, so how do you work around this?</p>
<!--more-->
<h3>The Solution</h3>
<p>Here is my solution:</p>
<pre class="codepen" data-height="400" data-type="result" data-href="JEKIu" data-user="tjvantoll"><code></code></pre>
<script async src="http://codepen.io:/assets/embed/ei.js"></script>
<h3>How does it work?</h3>
<p>The first step is to set the <code><tbody></code> to <code>display: block</code> so an <code>overflow</code> and <code>height</code> can be applied. From there the rows in the <code><thead></code> need to be set to <code>position: relative</code> and <code>display: block</code> so that they’ll sit on top of the now scrollable <code><tbody></code>.</p>
<p>That’s really about it.</p>
<h3>Unfortunate Part #1: Old Internet Explorer</h3>
<p>When you set a <code>height</code> on a <code><tbody></code> Internet Explorer < 10 applies that <code>height</code> to every table cell, which is of course wonderful.</p>
<p>My workaround for this is to conditionally create a wrapper <code><div></code>. When it’s present I give it the <code>height</code> and <code>overflow</code> and remove the <code>height</code> from the <code><tbody></code>.</p>
<figure class='code'><figcaption class='not_empty'><span>Wrap table for IE</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><style></span>
</span><span class='line'> <span class="nc">.old_ie_wrapper</span> <span class="p">{</span> <span class="k">height</span><span class="o">:</span> <span class="m">300px</span><span class="p">;</span> <span class="k">overflow</span><span class="o">:</span> <span class="k">auto</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'> <span class="nc">.old_ie_wrapper</span> <span class="nt">tbody</span> <span class="p">{</span> <span class="k">height</span><span class="o">:</span> <span class="k">auto</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nt"></style></span>
</span><span class='line'><span class="c"><!--[if lte IE 9]></span>
</span><span class='line'><span class="c"><div class="old_ie_wrapper"></span>
</span><span class='line'><span class="c"><!--<![endif]--></span>
</span><span class='line'> <span class="nt"><table></span>
</span><span class='line'> <span class="c"><!-- Contents of the table --></span>
</span><span class='line'> <span class="nt"></table></span>
</span><span class='line'><span class="c"><!--[if lte IE 9]></span>
</span><span class='line'><span class="c"></div></span>
</span><span class='line'><span class="c"><!--<![endif]--></span>
</span></code></pre></td></tr></table></div></figure>
<p>The headers will scroll with the table body, but the table will at least be usable. You could also create <a href="http://paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/">conditional classes on the <html> tag</a> to handle this as well.</p>
<h3>Unfortunate Part #2: Widths</h3>
<p>Because the <code><thead></code> is relatively positioned each table cell needs an explicit <code>width</code>.</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">td</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">1</span><span class="o">),</span> <span class="nt">th</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">1</span><span class="o">)</span> <span class="p">{</span> <span class="k">width</span><span class="o">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nt">td</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">2</span><span class="o">),</span> <span class="nt">th</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">2</span><span class="o">)</span> <span class="p">{</span> <span class="k">width</span><span class="o">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nt">td</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">3</span><span class="o">),</span> <span class="nt">th</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">3</span><span class="o">)</span> <span class="p">{</span> <span class="k">width</span><span class="o">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>But unfortunately that is not enough. When a scrollbar is present browsers allocate space for it, therefore, the <code><tbody></code> ends up having less space available than the <code><thead></code>. Notice the slight misalignment this creates:</p>
<p><img src="http://tjvantoll.com/images/posts/2012-11-10/Alignment-Issue.png" title="Alignment issue with scroll bar" alt="Alignment issue with scroll bar" /></p>
<p>The only workaround I could come up with was to set a <code>min-width</code> on all columns except the last one.</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nt">td</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">1</span><span class="o">),</span> <span class="nt">th</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">1</span><span class="o">)</span> <span class="p">{</span> <span class="k">min-width</span><span class="o">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nt">td</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">2</span><span class="o">),</span> <span class="nt">th</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">2</span><span class="o">)</span> <span class="p">{</span> <span class="k">min-width</span><span class="o">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nt">td</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">3</span><span class="o">),</span> <span class="nt">th</span><span class="nd">:nth-child</span><span class="o">(</span><span class="nt">3</span><span class="o">)</span> <span class="p">{</span> <span class="k">width</span><span class="o">:</span> <span class="m">100px</span><span class="p">;</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h3>The Good</h3>
<p>Despite these issues the solution does work in all browsers back to IE6 with no JavaScript dependency.</p>
<p>The markup to create the table is simple and semantic. I’ve seen workarounds for this issue that use <code><div></code>s instead of <code><table></code>s or multiple aligned <code><table></code>s and those always felt dirty to me.</p>
<p>The code is free to use and do whatever you want with it. If you have any suggestions for improvements or find any issues please let me know in the comments.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Creating a Polished Vertical Tabs Interaction with jQuery UI]]></title>
<link href="http://tjvantoll.com/2012/11/08/creating-a-polished-vertical-tabs-interaction-with-jquery-ui/"/>
<updated>2012-11-08T00:00:00-05:00</updated>
<id>http://tjvantoll.com/2012/11/08/creating-a-polished-vertical-tabs-interaction-with-jquery-ui</id>
<content type="html"><![CDATA[<p>The <a href="http://jqueryui.com/tabs/">jQuery UI tabs widget</a> provides a clean way to implement a tabular UI. Furthermore, the markup used gives you ample hooks to make the tabs visually into what you want them to be. The docs provide a <a href="http://jqueryui.com/tabs/#vertical">simple demo</a> of how you can give the tabs a vertical orientation, but I thought I’d show how you can use what the framework provides to create something a bit more polished.</p>
<!--more-->
<p>Here’s an example:</p>
<iframe style="width: 100%; height: 350px;" src="http://jsfiddle.net/tj_vantoll/nn2Qw/embedded/result,js,html,css/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p>Please poke around in the source to see how it was made. Feel free to use this or modify it to your liking.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Adding Pointers to jQuery UI Tooltips]]></title>
<link href="http://tjvantoll.com/2012/10/24/adding-pointers-to-jquery-ui-tooltips/"/>
<updated>2012-10-24T20:58:00-04:00</updated>
<id>http://tjvantoll.com/2012/10/24/adding-pointers-to-jquery-ui-tooltips</id>
<content type="html"><![CDATA[<p>The recent <a href="http://jqueryui.com/changelog/1.9.0/">jQuery UI 1.9 release</a> included a new <a href="http://jqueryui.com/tooltip/">tooltip plugin</a> that can be used to create tooltips much like the native tooltips the browser provides. The difference is that jQuery UI’s version are completely customizable. As such I thought I’d show a quick example of how you can create a pointer from the tooltip to its associated field:</p>
<!--more-->
<iframe style="width: 100%; height: 350px;" src="http://jsfiddle.net/tj_vantoll/kyBwU/embedded/result,js,html,css/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p>So how is this done?</p>
<ul>
<li>The <a href="http://api.jqueryui.com/tooltip/#option-position">position</a> option is used to place the tooltip appropriately around the textbox. Importantly the <code>collision</code> property is set to <code>none</code>, since, if the tooltip were to be repositioned the arrow would be placed incorrectly.</li>
<li>The pointers themselves are created using using the <code>::after</code> and <code>::before</code> pseudo-elements. For some more information on the technique and to see some other variations there’s an excellent tutorial <a href="http://nicolasgallagher.com/pure-css-speech-bubbles/">here</a>.</li>
<li>Since the <code>::after</code> and <code>::before</code> pseudo-elements are used to create the pointers, IE <= 8 users will not see them. However, they’ll simply see the default pointerless tooltip, no harm done.</li>
</ul>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Front End Efficiency - The Top Ten]]></title>
<link href="http://tjvantoll.com/2012/10/23/front-end-efficiency-the-top-ten/"/>
<updated>2012-10-23T00:00:00-04:00</updated>
<id>http://tjvantoll.com/2012/10/23/front-end-efficiency-the-top-ten</id>
<content type="html"><![CDATA[<p>I gave a “Front End Efficiency - The Top Ten” talk to the <a href="http://groups.google.com/group/greaterlansingjug?pli=1">Greater Lansing Java Users Group</a> on October 23rd, 2012. For those that missed the talk the slides are <a href="http://tjvantoll.com/speaking/slides/2012/Efficiency-Top-Ten/">here</a>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[maxlength Constraint Validation Oddities in Major Browsers]]></title>
<link href="http://tjvantoll.com/2012/10/17/maxlength-constraint-validation-oddities/"/>
<updated>2012-10-17T12:48:00-04:00</updated>
<id>http://tjvantoll.com/2012/10/17/maxlength-constraint-validation-oddities</id>
<content type="html"><![CDATA[<p>The <code>maxlength</code> attribute has been around in browsers for a long time. When provided all browsers prevent the user entering a value that exceeds the <code>maxlength</code>.</p>
<p>For example you cannot type more than 2 characters in the textbox below:</p>
<p><input type="text" maxlength="2" /></p>
<h3>Constraint Validation</h3>
<p><a href="https://developer.mozilla.org/en-US/docs/HTML/HTML5/Constraint_validation_">Constraint validation</a> is an HTML5 spec that provides native client side form validation in the browser. As part of its <a href="https://developer.mozilla.org/en-US/docs/HTML/Forms_in_HTML#Constraint_Validation_API">API</a>, all <code><input></code> and <code><textarea></code> elements have a <code>validity.tooLong</code> property that is <code>true</code> when the length of the <code>value</code> exceeds the <code>maxlength</code>.</p>
<p>But if the browser prevents this then why does the property exist?</p>
<!--more-->
<h3>Prefilled value Attribute</h3>
<p>Assume that you’re filling the <code>value</code> of form elements with information from a database and you end up with something like this:</p>
<p><code><input type="text" maxlength="1" value="ABC" /></code></p>
<p>How will the browser handle this?</p>
<p>All browsers will prevent entry of additional characters, but they do not trim excess characters already present. Additionally all browsers will allow a form containing the above input to submit. <em>Note: Opera is the only browser to set the <code>validity.tooLong</code> property to <code>true</code> in this situation. Despite this, it does not prevent form submission.</em></p>
<p>Why is submission not prevented? The key is in the <a href="http://www.whatwg.org/specs/web-apps/current-work/#concept-input-value-dirty-flag">specification</a>:</p>
<blockquote><p>Constraint validation: If an element has a maximum allowed value length, its dirty value flag is true, its value was last changed by a user edit (as opposed to a change made by a script), and the code-unit length of the element’s value is greater than the element’s maximum allowed value length, then the element is suffering from being too long.</p></blockquote>
<p>The <a href="http://www.whatwg.org/specs/web-apps/current-work/#concept-input-value-dirty-flag">dirty flag</a> essentially means the the user has changed the value of an element. Therefore, in order to be <code>tooLong</code> the element must have been last interacted with by a user edit.</p>
<h3>Actually Triggering tooLong</h3>
<p>So let’s take another approach. What happens if you have the same input:</p>
<p><code><input type="text" maxlength="1" value="ABC" /></code></p>
<p>…remove one character, then submit? You can try it for yourself below:</p>
<iframe style="width: 100%; height: 180px;" src="http://jsfiddle.net/tj_vantoll/epCQe/embedded/result,html/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<p>Upon edit IE10 and Chrome will set the <code>validity.tooLong</code> property to <code>true</code> and prevent form submission. If the user attempts to submit a form after removing the “C” they will see the following in those browsers:</p>
<p><img src="http://tjvantoll.com/images/posts/2012-10-17/Chrome.png" title="Chrome" alt="Chrome" />
<img src="http://tjvantoll.com/images/posts/2012-10-17/IE10.png" title="IE10" alt="IE10" /></p>
<p>Firefox, Safari, and Opera incorrectly handle this situation and allow the form to be submitted anyways.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Using the Attribute Selector with Numeric Values]]></title>
<link href="http://tjvantoll.com/2012/09/19/using-the-attribute-selector-with-numeric-values/"/>
<updated>2012-09-19T20:42:00-04:00</updated>
<id>http://tjvantoll.com/2012/09/19/using-the-attribute-selector-with-numeric-values</id>
<content type="html"><![CDATA[<p>What color will the number 3 be in the example below?</p>
<figure class='code'><figcaption class='empty'><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt"><style></span>
</span><span class='line'> <span class="nt">td</span> <span class="p">{</span> <span class="k">color</span><span class="o">:</span> <span class="nb">red</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'> <span class="nt">td</span><span class="o">[</span><span class="nt">colspan</span><span class="o">=</span><span class="nt">2</span><span class="o">]</span> <span class="p">{</span> <span class="k">color</span><span class="o">:</span> <span class="nb">blue</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'><span class="nt"></style></span>
</span><span class='line'>
</span><span class='line'><span class="nt"><table></span>
</span><span class='line'> <span class="nt"><tr></span>
</span><span class='line'> <span class="nt"><td</span> <span class="na">colspan=</span><span class="s">"2"</span><span class="nt">></span>1<span class="nt"></td></span>
</span><span class='line'> <span class="nt"></tr></span>
</span><span class='line'> <span class="nt"><td></span>
</span><span class='line'> <span class="nt"><td></span>2<span class="nt"></td></span>
</span><span class='line'> <span class="nt"><td></span>3<span class="nt"></td></span>
</span><span class='line'> <span class="nt"></tr></span>
</span><span class='line'><span class="nt"></table></span>
</span></code></pre></td></tr></table></div></figure>
<p>Turns out it will be red because the <code>td[colspan=2]</code> selector does not match it. Why?</p>
<!--more-->
<h3>Attribute Selector</h3>
<p>Per the <a href="http://www.w3.org/TR/css3-selectors/#attribute-selectors">CSS 3 specification</a> values used in attribute selectors must be either identifiers or strings.</p>
<p>String values are those enclosed by single or double quotes (e.g. the <code>2</code> in the selector <code>value="2"</code>). If a value is not a string the browser attempts to resolve it as an identifier, which the spec defines as such:</p>
<blockquote><p>“In CSS, identifiers (including element names, classes, and IDs in selectors) can contain only the characters [a-zA-Z0-9] and ISO 10646 characters U+00A0 and higher, plus the hyphen (-) and the underscore (_); they cannot start with a digit, two hyphens, or a hyphen followed by a digit.”</p><footer><strong>CSS 2.1 Specification</strong> <cite><a href='http://www.w3.org/TR/CSS2/syndata.html#value-def-identifier'>www.w3.org/TR/CSS2/…</a></cite></footer></blockquote>
<p>So why doesn’t <code>colspan=2</code> work above? The key part from the spec is that ”<em>identifiers … cannot start with a digit</em>”. Therefore, since <code>2</code> is not a string and does not qualify as an identifier, the browser ignores it. This behavior is implemented consistently in all browsers.</p>
<p>The fix? Simply wrap the value in quotes; both <code>td[colspan='2']</code> and <code>td[colspan="2"]</code> will match the cell in the example above.</p>
<h3>Numeric Attributes</h3>
<p>Attributes that generally only have numeric values include <code>colspan</code>, <code>rowspan</code>, <code>cellpadding</code>, <code>cellspacing</code>, <code>min</code>, <code>max</code>, and <code>step</code>. When using any of these attributes in an attribute selector ensure that you wrap the value in quotes.</p>
<h3>JavaScript</h3>
<p>Most selector engines such as jQuery’s sizzle will make the selector work regardless of whether the quotes are present. <code>$('td[colspan=2]')</code> will return the cell in question in the example above.</p>
<p>However, if you are using native JavaScript though you will not be so lucky; <code>document.querySelectorAll('td[colspan=2]')</code> actually throws an error.</p>
<h3>Conclusion</h3>
<p>Attributes with numeric values need to have quotes around them when using them in CSS or JavaScript. When in doubt use quotes around attribute values; it never hurts, and there are some strange edge cases where omitting the quotes leads to unexpected behavior. If you’re looking for a more detailed writeup on when quotes are ok to omit checkout <a href="http://mathiasbynens.be/notes/unquoted-attribute-values">Mathias Bynens’ writeup on the topic</a>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Using jQuery UI's Slider to Polyfill HTML5's input[type=range]]]></title>
<link href="http://tjvantoll.com/2012/09/14/using-jquery-ui-slider-to-polyfill-html5-input-type-range/"/>
<updated>2012-09-14T21:25:00-04:00</updated>
<id>http://tjvantoll.com/2012/09/14/using-jquery-ui-slider-to-polyfill-html5-input-type-range</id>
<content type="html"><![CDATA[<p><a href="http://jqueryui.com/demos/slider">jQuery UI’s slider plugin</a> looks and behaves much like the browser’s native <code>input[type=range]</code> control; therefore it makes an excellent choice for <a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/">polyfilling</a> the native behavior.</p>
<h3>How to do it</h3>
<p>The main issue is that the slider must be built on a block level node, not an <code><input></code>. Therefore you must create another container node (in this case a <code><div></code>) to create the slider from then hide the original <code><input></code>.</p>
<p>Here’s the script that I used.</p>
<!--more-->
<figure class='code'><figcaption class='not_empty'><span>Polyfill input[type=range] with jQuery UI’s Slider</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">//Determine whether the browser natively supports input[type=range].</span>
</span><span class='line'> <span class="c1">//If you're using Modernizr this is equivalent to Modernizr.inputtypes.range</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">input</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'input'</span><span class="p">);</span>
</span><span class='line'> <span class="nx">input</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s1">'type'</span><span class="p">,</span> <span class="s1">'range'</span><span class="p">);</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">rangeSupport</span> <span class="o">=</span> <span class="nx">input</span><span class="p">.</span><span class="nx">type</span> <span class="o">!=</span> <span class="s1">'text'</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">rangeSupport</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">$input</span><span class="p">,</span> <span class="nx">$slider</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="nx">$</span><span class="p">(</span><span class="s1">'input[type=range]'</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">index</span><span class="p">,</span> <span class="nx">input</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="nx">$input</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">input</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//Create a new div, turn it into a slider, and set its attributes based on</span>
</span><span class='line'> <span class="c1">//the attributes of the input. If the input doesn't possess those attributes</span>
</span><span class='line'> <span class="c1">//use jQuery UI's defaults.</span>
</span><span class='line'> <span class="nx">$slider</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">'<div />'</span><span class="p">).</span><span class="nx">slider</span><span class="p">({</span>
</span><span class='line'> <span class="nx">min</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">$input</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'min'</span><span class="p">),</span> <span class="mi">10</span><span class="p">)</span> <span class="o">||</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'> <span class="nx">max</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">$input</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'max'</span><span class="p">),</span> <span class="mi">10</span><span class="p">)</span> <span class="o">||</span> <span class="mi">100</span><span class="p">,</span>
</span><span class='line'> <span class="nx">value</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">$input</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'value'</span><span class="p">),</span> <span class="mi">10</span><span class="p">)</span> <span class="o">||</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'> <span class="nx">step</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">(</span><span class="nx">$input</span><span class="p">.</span><span class="nx">attr</span><span class="p">(</span><span class="s1">'step'</span><span class="p">),</span> <span class="mi">10</span><span class="p">)</span> <span class="o">||</span> <span class="mi">1</span><span class="p">,</span>
</span><span class='line'> <span class="nx">slide</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">event</span><span class="p">,</span> <span class="nx">ui</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">//Keep the value of the input[type=range] in sync with the slider.</span>
</span><span class='line'> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">prev</span><span class="p">(</span><span class="s1">'input'</span><span class="p">).</span><span class="nx">val</span><span class="p">(</span><span class="nx">ui</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">//Append the slider after the input and hide the input. The user will only</span>
</span><span class='line'> <span class="c1">//interact with the slider. </span>
</span><span class='line'> <span class="nx">$input</span><span class="p">.</span><span class="nx">after</span><span class="p">(</span><span class="nx">$slider</span><span class="p">).</span><span class="nx">hide</span><span class="p">();</span>
</span><span class='line'> <span class="p">});</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>
<h3>Future</h3>
<p>This approach handles the most common use cases but it isn’t perfect. For example, if you want to disable the <code><input type="range"></code> you’ll have to disable the slider as well.</p>
<p>There is a <a href="http://bugs.jqueryui.com/ticket/5800">feature request to add support for this natively in the slider plugin</a> itself, but it’s been sitting inactive for quite some time now. Hopefully over time <code>input[type=range]</code> support will become ubiquitous enough that we can drop these workarounds.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[HTML5 Form Validation - Start Using it in Production Applications]]></title>
<link href="http://tjvantoll.com/2012/08/30/html5-form-validation-start-using-it-in-production-applications/"/>
<updated>2012-08-30T00:00:00-04:00</updated>
<id>http://tjvantoll.com/2012/08/30/html5-form-validation-start-using-it-in-production-applications</id>
<content type="html"><![CDATA[<p>Forms suck, yet, they make or break the most crucial online transactions. Building web forms sucks as well; the APIs and lack of customizability has confused and frustrated people for years. As a byproduct an abundance of horribly unusable forms have been created for everyone to suffer through.</p>
<p>Therefore <em>anything</em> that makes this process easier should be greeted with joy and enthusiasm.</p>
<p>HTML5 does just this by including a built in <a href="https://developer.mozilla.org/en-US/docs/HTML/Forms_in_HTML#Constraint_Validation_API">client side form validation mechanism</a> designed to make implementing client side validation powerful, seamless, and most importantly - easy to implement.</p>
<p>Great! Despite this, HTML5 form validation is a topic relegated to presentations and demos; I personally have yet to fill out a web form in the wild that actually makes use of it.</p>
<p>Why?</p>
<!--more-->
<h3>Browser Support</h3>
<p>One reason people avoid HTML5 form validation is lack (or perceived lack) of browser support for the new APIs. However the <a href="http://caniuse.com/#feat=form-validation">list of supported browsers</a> now includes the latest version of every major browser, including:</p>
<ul>
<li>IE 10</li>
<li>Firefox 4+</li>
<li>Chrome 10+</li>
<li>Safari 5+</li>
<li>Opera 10+</li>
<li>Opera Mobile</li>
<li>Chrome for Android</li>
<li>Firefox for Android</li>
</ul>
<h3>What to do in unsupported browsers?</h3>
<p>This is <em>the</em> problem. Despite browser support being relatively good, for most sites there are still going to be a substantial amount of users with browsers that simply do not support the new APIs. Therefore, if you are intending to support these users you have to start forking your code to support both browsers with native support and browsers without it.</p>
<p>While this can absolutely be done, it’s time consuming and a bit of a nuisance. It’s faster and easier to simply ditch the native validation and use your own. In this case you don’t have to worry about multiple code paths; every user in every browser will hit the same codepath and get the same experience.</p>
<h3>What if we did nothing?</h3>
<p>But what if we took a new approach to this problem - simply don’t do client side validation in unsupported browsers, at all. This is advantageous for a number of reasons.</p>
<p>1) <strong>No dual maintenance</strong>. One thing that has always bothered me about doing validation on both the client and server side is that you’re validating the #1 principle of software development - <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"><strong>D</strong>on’t <strong>R</strong>epeat <strong>Y</strong>ourself</a>.</p>
<p>2) <strong>No dependencies</strong>. If you only use native browser APIs to provide client side validation you don’t have to worry about maintaining plugin or library dependencies that might not be maintained.</p>
<p>3) <strong>Faster and easier</strong>. The browser APIs are simple and easy to use. Want to make a field required? <a href="http://wufoo.com/html5/attributes/09-required.html">Add the <code>required</code> attribute</a>. Want to make a field only accept email address? <a href="http://wufoo.com/html5/types/1-email.html">Add <code>type=email</code> to your <code><input></code> field</a>.</p>
<p>4) <strong>Future Friendly</strong>. Although currently a number of older browsers (namely IE <= 9) do not support the new APIs, eventually they all will. Therefore, eventually all users will hit the client side validation as intended.</p>
<h3>But, you can’t just not validate data… right?</h3>
<p>Of course you have to validate client submitted data, but you already need to be doing that on the server side anyways. What this approach requires you to do is simply return formatted error messages from your server side processing and <a href="http://uxdesign.smashingmagazine.com/2011/11/08/extensive-guide-web-form-usability/">display them in a usability friendly way</a>. You’re likely doing that already.</p>
<h3>What About Polyfills?</h3>
<p><a href="http://remysharp.com/2010/10/08/what-is-a-polyfill/">Polyfills</a> are great and a number of <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills">HTML5 form validation polyfills</a> exist. My problem with polyfills in this case is that they add a dependency that I believe is unnecessary.</p>
<h3>Conclusion</h3>
<p>HTML5 provides native solutions to validating client side data and most all modern browsers support it. Yet, most people are still relying on the JavaScript hacks we’ve been using for well over a decade now.</p>
<p>It’s time. Come to the dark side.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Google Analytics - Excluding Your Own Visits in Development and Production]]></title>
<link href="http://tjvantoll.com/2012/08/28/google-analytics-excluding-visits-in-development-and-production/"/>
<updated>2012-08-28T00:00:00-04:00</updated>
<id>http://tjvantoll.com/2012/08/28/google-analytics-excluding-visits-in-development-and-production</id>
<content type="html"><![CDATA[<p>Googling how to exclude your own <a href="http://www.google.com/analytics/">Google Analytics</a> traffic returns a plethora of results, however, nearly all of them advocate 1 of 2 approaches:</p>
<ul>
<li>Creating an IP filter in Google Analytics itself <a href="http://support.google.com/analytics/bin/answer.py?hl=en&answer=1034840&rd=1">(example)</a>.</li>
<li>Creating a page that sets a cookie which tells Google Analytics to exclude the traffic <a href="http://webmasters.stackexchange.com/questions/15552/how-do-you-exclude-yourself-from-google-analytics-on-your-website-using-cookies">(example)</a>.</li>
</ul>
<h3>Problems</h3>
<p>These approaches are silly in my opinion. IP addresses change. In fact, most ISPs change subscriber’s IP addresses quite regularly. Furthermore, most people visit their site on a wide variety of devices in a wide variety of places. Maintaining a list of IP addresses in Google Analytics would be a nightmare.</p>
<p>The cookie approach works, but it is a pain to have to create and maintain the page that sets the cookie. It’s also problematic because verifying whether the cookie is actually active is difficult. Do you know where your browser stores your cookies and how to access them? How about your smart phone? Because of this you end up constantly having to create the cookie before accessing the site, which is a nuisance.</p>
<h3>JavaScript</h3>
<p>Both these approaches seem especially silly considering how easy it is to simply accomplish this with JavaScript. You can simply check for the exclusion criteria before including the Google Analytics code snippet.</p>
<!--more-->
<h3>Excluding localhost Traffic</h3>
<p>If you test your site on a local server you likely don’t want that traffic being logged. Assuming that your local server is using <code>localhost</code> as the hostname the following will exclude the traffic.</p>
<figure class='code'><figcaption class='not_empty'><span>Excluding localhost Traffic</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o"><</span><span class="nx">script</span><span class="o">></span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">host</span> <span class="o">!=</span> <span class="s1">'localhost'</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">_gaq</span> <span class="o">=</span> <span class="nx">_gaq</span> <span class="o">||</span> <span class="p">[];</span>
</span><span class='line'> <span class="nx">_gaq</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">'_setAccount'</span><span class="p">,</span> <span class="s1">'UA-12345678-1'</span><span class="p">]);</span>
</span><span class='line'> <span class="nx">_gaq</span><span class="p">.</span><span class="nx">push</span><span class="p">([</span><span class="s1">'_trackPageview'</span><span class="p">]);</span>
</span><span class='line'>
</span><span class='line'> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">ga</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">createElement</span><span class="p">(</span><span class="s1">'script'</span><span class="p">);</span> <span class="nx">ga</span><span class="p">.</span><span class="nx">type</span> <span class="o">=</span> <span class="s1">'text/javascript'</span><span class="p">;</span> <span class="nx">ga</span><span class="p">.</span><span class="nx">async</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'> <span class="nx">ga</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="p">(</span><span class="s1">'https:'</span> <span class="o">==</span> <span class="nb">document</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">protocol</span> <span class="o">?</span> <span class="s1">'https://ssl'</span> <span class="o">:</span> <span class="s1">'http://www'</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'.google-analytics.com/ga.js'</span><span class="p">;</span>
</span><span class='line'> <span class="kd">var</span> <span class="nx">s</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementsByTagName</span><span class="p">(</span><span class="s1">'script'</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span> <span class="nx">s</span><span class="p">.</span><span class="nx">parentNode</span><span class="p">.</span><span class="nx">insertBefore</span><span class="p">(</span><span class="nx">ga</span><span class="p">,</span> <span class="nx">s</span><span class="p">);</span>
</span><span class='line'> <span class="p">})();</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="o"><</span><span class="err">/script></span>
</span></code></pre></td></tr></table></div></figure>