{"rowid": 179, "title": "Have a Field Day with HTML5 Forms", "contents": "Forms are usually seen as that obnoxious thing we have to markup and style. I respectfully disagree: forms (on a par with tables) are the most exciting thing we have to work with.\n\nHere we\u2019re going to take a look at how to style a beautiful HTML5 form using some advanced CSS and latest CSS3 techniques. I promise you will want to style your own forms after you\u2019ve read this article.\n\nHere\u2019s what we\u2019ll be creating:\n\n The form. (Icons from Chalkwork Payments)\n\nMeaningful markup\n\nWe\u2019re going to style a simple payment form. There are three main sections on this form:\n\n\n\tThe person\u2019s details\n\tThe address details\n\tThe credit card details\n\n\nWe are also going to use some of HTML5\u2019s new input types and attributes to create more meaningful fields and use less unnecessary classes and ids:\n\n\n\temail, for the email field\n\ttel, for the telephone field\n\tnumber, for the credit card number and security code\n\trequired, for required fields\n\tplaceholder, for the hints within some of the fields\n\tautofocus, to put focus on the first input field when the page loads\n\n\nThere are a million more new input types and form attributes on HTML5, and you should definitely take a look at what\u2019s new on the W3C website. Hopefully this will give you a good idea of how much more fun form markup can be.\n\nA good foundation\n\nEach section of the form will be contained within its own fieldset. In the case of the radio buttons for choosing the card type, we will enclose those options in another nested fieldset.\n\nWe will also be using an ordered list to group each label / input pair. This will provide us with a (kind of) semantic styling hook and it will also make the form easier to read when viewing with no CSS applied:\n\n The unstyled form\n\nSo here\u2019s the markup we are going to be working with:\n\n
\n\t
\n\t\tYour details\n\t\t
    \n\t\t\t
  1. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  2. \n\t\t\t
  3. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  4. \n\t\t\t
  5. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  6. \n\t\t
\n\t
\n\t
\n\t\tDelivery address\n\t\t
    \n\t\t\t
  1. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  2. \n\t\t\t
  3. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  4. \n\t\t\t
  5. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  6. \n\t\t
\n\t
\n\t
\n\t\tCard details\n\t\t
    \t\t\n\t\t\t
  1. \n\t\t\t\t
    \n\t\t\t\t\tCard type\n\t\t\t\t\t
      \n\t\t\t\t\t\t
    1. \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    2. \n\t\t\t\t\t\t
    3. \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    4. \n\t\t\t\t\t\t
    5. \n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t
    6. \n\t\t\t\t\t
    \n\t\t\t\t
    \n\t\t\t
  2. \n\t\t\t
  3. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  4. \n\t\t\t
  5. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  6. \n\t\t\t
  7. \n\t\t\t\t\n\t\t\t\t\n\t\t\t
  8. \n\t\t
\n\t
\n\t
\n\t\t\n\t
\n
\n\nMaking things look nice\n\nFirst things first, so let\u2019s start by adding some defaults to our form by resetting the margins and paddings of the elements and adding a default font to the page:\n\nhtml, body, h1, form, fieldset, legend, ol, li {\n\tmargin: 0;\n\tpadding: 0;\n}\nbody {\n\tbackground: #ffffff;\n\tcolor: #111111;\n\tfont-family: Georgia, \"Times New Roman\", Times, serif;\n\tpadding: 20px;\n}\n\nNext we are going to style the form element that is wrapping our fields:\n\nform#payment {\n\tbackground: #9cbc2c;\n\t-moz-border-radius: 5px;\n\t-webkit-border-radius: 5px;\n\tborder-radius: 5px;\n\tpadding: 20px;\n\twidth: 400px;\n}\n\nWe will also remove the border from the fieldset and apply some bottom margin to it. Using the :last-of-type pseudo-class, we remove the bottom margin of the last fieldset \u2014 there is no need for it:\n\nform#payment fieldset {\n\tborder: none;\n\tmargin-bottom: 10px;\n}\nform#payment fieldset:last-of-type {\n\tmargin-bottom: 0;\n}\n\nNext we\u2019ll make the legends big and bold, and we will also apply a light-green text-shadow, to add that little extra special detail:\n\nform#payment legend {\n\tcolor: #384313;\n\tfont-size: 16px;\n\tfont-weight: bold;\n\tpadding-bottom: 10px;\n\ttext-shadow: 0 1px 1px #c0d576;\n}\n\nOur legends are looking great, but how about adding a clear indication of how many steps our form has? Instead of adding that manually to every legend, we can use automatically generated counters.\n\nTo add a counter to an element, we have to use either the :before or :after pseudo-elements to add content via CSS. We will follow these steps:\n\n\n\tcreate a counter using the counter-reset property on the form element\n\tcall the counter with the content property (using the same name we\u2019ve created before)\n\twith the counter-incremet property, indicate that for each element that matches our selector, that counter will be increased by 1\n\n\nform#payment > fieldset > legend:before {\n\tcontent: \"Step \" counter(fieldsets) \": \";\n\tcounter-increment: fieldsets;\n}\n\nFinally, we need to change the style of the legend that is part of the radio buttons group, to make it look like a label:\n\nform#payment fieldset fieldset legend {\n\tcolor: #111111;\n\tfont-size: 13px;\n\tfont-weight: normal;\n\tpadding-bottom: 0;\n}\n\nStyling the lists\n\nFor our list elements, we\u2019ll just add some nice rounded corners and semi-transparent border and background. Because we are using RGBa colors, we should provide a fallback for browsers that don\u2019t support them (that comes before the RBGa color). For the nested lists, we will remove these properties because they would be overlapping:\n\nform#payment ol li {\n\tbackground: #b9cf6a;\n\tbackground: rgba(255,255,255,.3);\n\tborder-color: #e3ebc3;\n\tborder-color: rgba(255,255,255,.6);\n\tborder-style: solid;\n\tborder-width: 2px;\n\t-moz-border-radius: 5px;\n\t-webkit-border-radius: 5px;\n\tborder-radius: 5px;\n\tline-height: 30px;\n\tlist-style: none;\n\tpadding: 5px 10px;\n\tmargin-bottom: 2px;\n}\nform#payment ol ol li {\n\tbackground: none;\n\tborder: none;\n\tfloat: left;\n}\n\nForm controls\n\nNow we only need to style our labels, inputs and the button element.\n\nAll our labels will look the same, with the exception of the one for the radio elements. We will float them to the left and give them a width.\n\nFor the credit card type labels, we will add an icon as the background, and override some of the properties that aren\u2019t necessary. We will be using the attribute selector to specify the background image for each label \u2014 in this case, we use the for attribute of each label.\n\nTo add an extra user-friendly detail, we\u2019ll add a cursor: pointer to the radio button labels on the :hover state, so the user knows that he can simply click them to select that option.\n\nform#payment label {\n\tfloat: left;\n\tfont-size: 13px;\n\twidth: 110px;\n}\nform#payment fieldset fieldset label {\n\tbackground:none no-repeat left 50%;\n\tline-height: 20px;\n\tpadding: 0 0 0 30px;\n\twidth: auto;\n}\nform#payment label[for=visa] {\n\tbackground-image: url(visa.gif);\n}\nform#payment label[for=amex] {\n\tbackground-image: url(amex.gif);\n}\nform#payment label[for=mastercard] {\n\tbackground-image: url(mastercard.gif);\n}\nform#payment fieldset fieldset label:hover {\n\tcursor: pointer;\n}\n\nAlmost there! Now onto the input elements. Here we want to match all inputs, except for the radio ones, and the textarea. For that we will use the negation pseudo-class (:not()). With it we can target all input elements except for the ones with type of radio.\n\nWe will also make sure to add some :focus styles and add the appropriate styling for the radio inputs:\n\nform#payment input:not([type=radio]),\nform#payment textarea {\n\tbackground: #ffffff;\n\tborder: none;\n\t-moz-border-radius: 3px;\n\t-webkit-border-radius: 3px;\n\t-khtml-border-radius: 3px;\n\tborder-radius: 3px;\n\tfont: italic 13px Georgia, \"Times New Roman\", Times, serif;\n\toutline: none;\n\tpadding: 5px;\n\twidth: 200px;\n}\nform#payment input:not([type=submit]):focus,\nform#payment textarea:focus {\n\tbackground: #eaeaea;\n}\nform#payment input[type=radio] {\n\tfloat: left;\n\tmargin-right: 5px;\n}\n\nAnd finally we come to our submit button. To it, we will just add some nice typography and text-shadow, align it to the center of the form and give it some background colors for its different states:\n\nform#payment button {\n\tbackground: #384313;\n\tborder: none;\n\t-moz-border-radius: 20px;\n\t-webkit-border-radius: 20px;\n\t-khtml-border-radius: 20px;\n\tborder-radius: 20px;\n\tcolor: #ffffff;\n\tdisplay: block;\n\tfont: 18px Georgia, \"Times New Roman\", Times, serif;\n\tletter-spacing: 1px;\n\tmargin: auto;\n\tpadding: 7px 25px;\n\ttext-shadow: 0 1px 1px #000000;\n\ttext-transform: uppercase;\n}\nform#payment button:hover {\n\tbackground: #1e2506;\n\tcursor: pointer;\n}\n\nAnd that\u2019s it! See the completed form.\n\nThis form will not look the same on every browser. Internet Explorer and Opera don\u2019t support border-radius (at least not for now); the new input types are rendered as just normal inputs on some browsers; and some of the most advanced CSS, like the counter, :last-of-type or text-shadow are not supported on some browsers. But that doesn\u2019t mean you can\u2019t use them right now, and simplify your development process. My gift to you!", "year": "2009", "author": "Inayaili de Le\u00f3n Persson", "author_slug": "inayailideleon", "published": "2009-12-03T00:00:00+00:00", "url": "https://24ways.org/2009/have-a-field-day-with-html5-forms/", "topic": "code"}