From Elvanör's Technical Wiki
Jump to: navigation, search

Various important things I noticed when writing HTML & CSS code.



  • <span> elements are like DIVs, but inline.
  • <textarea> elements are not block elements, they behave like inline elements. Actually they are inline-block elements, which means that their content is treated like a block, but the element itself is treated like an inline element.
  • Most of the form elements (<label>,<input>,<button>) are inline elements.
  • <div> elements are not permitted inside a <p> element; it is DIV elements that should englobe other elements, not the contrary.
  • As much as possible, use elements like <strong>, <em>, <cite>, <h1>... Do not try to define styles that will render as these elements. Not only doing this adds better structure to the document, thus helping others to understand it, but it also helps for search engines (hopefully).

Head Elements

  • The base element allows you to specify a base URL for all links and images. It should be an absolute URI (if it's not, Firefox ignores it, although IE does not).

Embedding style sheets, JavaScript in HTML documents

  • Not too sure about that, but it seems you can use a <link> tag only in the <head> section of the document.
  • Do not use <link> for JavaScript code. You must use <script src="code.js" > </script> syntax. Avoid closing the <script> tag in the same element (eg, <script />); it won't work, and will completely confuse the browser! It is maybe possible to use <link> for JS code but then the <script> tag must appear in the file (untested).


  • If you use the GET method on a form, on the action URL, don't give an URL already containing variables encoded in GET style. The browser will just rebuild the URL when you submit the form, and thus the variables will be ignored. Eg, something like:
<form action="myurl.html?myVariable=yes&myCounter=3" method="GET"><button type="submit></button></form>

won't work. If you want to pass variables and use a GET method, just create hidden input fields.

  • To provide a custom background submit button, but with normal text inside, the best is to use <input type="submit" />. You just have to provide the following example CSS:
background-color: transparent;
background-image: url(;
border: medium none;
height: 30px;
padding: 0;
width: 115px;
  • To do the same without any text inside, just specify an empty value attribute. This means you never need to bother with the other ways of creating buttons:
    • <button />
    • <input type="image" />
  • To write valid HTML code, the textarea element needs the rows and cols attributes. Just write
rows="1" cols="1"

and give the actual dimensions via CSS, as you will have cross platform problems without this technique.

File upload widget

  • You can entirely style the file upload browser control. You just need to create a div with a background image (or whatever you want as an actual visual appearance, it could be just an <img>). Then use an absolutely positioned <input type="file" /> control with an opacity of 0, inside the base div (with relative position, of course). To make it work in a cross browser way you must make the input element huge, and use overflow: hidden on the base div so that the control does not take more place than the base div.
  • An example page giving the correct values for positioning the input element for this technique.


  • <div> elements are not permitted, only <tr> and <td>.
  • The <tbody> tag is not mandatory, but the element is. This means a tbody element will be created in the DOM even if you don't specify the tags in your HTML source. Be aware of this as it can lead to subtle errors if you manipulate the DOM later.
  • You usually want the HTML attributes cellspacing and cellpadding set to 0 on your tables.

Inner Frames (iframes)

  • DISCLAIMER: iframes are bad; do not use them if you can avoid that.
  • POSTing to an iframe from the outside is possible, see the code below:
  <iframe src='form_handler.php' frameborder="0"  name="reference_tag" />

  <form method='post' action='form_handler.php' target='reference_tag'>
      <input type='text' value='Random text'>
      <input type='submit'>

Note that the src attribute on the iframe is not mandatory with this technique.

noscript Tag

  • This tag is not interpreted when browsers support JavaScript. This can be used to provide an block that should be hidden when JS is supported. The best would be to be able to read the content of the noscript tag, in order to update another block. This works in Firefox and Opera but not on IE 7 nor Safari / Konqueror.
  • The best technique I have currently found (in order not to duplicate the content) is to use a first block containing the content, with display: none; style, and then a noscript tag with a style tag:
	<style type="text/css">#welcomePage .Dialog {display: block !important;}</style>
  • This works in all browsers, however is not valid W3C code.


  • Any element with an id can be linked to with the "#" character in a URI. Eg: /demos#magento, you would need to have an element with a "magento" id.

XHTML 1.0 & 1.1

  • Don't use the name attribute on forms, a, img or map elements. Only use id.
  • XHTML documents should be served with the MIME type "application/xhtml+xml" and NOT "text/html". If served properly as XML documents, this will cause Firefox to parse them using the XML parser, not the TagSoup parser. When served as text/html, the TagSoup parser will be used even if the document type is declared as XHTML.
  • However, currently there are lots of problems associated with XML documents. In particular, the JavaScript code document.write() does not work. This leads (for example) to fail. So actually it is almost impossible to use XML parsing.
  • Also note that IE 7 does not support "application/xhtml+xml" at all.
  • An empty self-closing div (<div class="Important" />) is perfectly legal in XHTML. However, it will cause problems if parsed by Firefox HTML parser, so you must not use it. Always close your divs with a </div>.

XHTML Strict

  • The iframe tag is not legal, as well as the target attribute in a link or form. This makes the use of Ajax upload almost impossible to achieve in an XHTML Strict compliant way.


  • When using Firefox, be very careful of the difference between "generated source" or "simple source". The generated source is produced by Firefox, and so contains the changes brought by DHTML, Ajax etc. However, this also means that this is the source once it is reinterpreted by Firefox which may add elements or remove some...
  • Even if you save the page, it will save the source reinterpreted by Firefox. Almost the only way to obtain the source as first sent by the server is to view the source and then save it in Firefox. This of course precludes any DHTML changes.
  • So the real solution is to install a special Firefox extension for validation. TotalValidator seems a good one.


  • There is a very important parameter for Flash objects: wmode. It can be set to "window" (default) or "transparent". The transparent mode is better as it allows HTML tags to be overlaid over the Flash content (normal z-index is respected).
  • Previously there was a bug in the Linux Flash player that prevented "transparent" to work as expected. But this bug is actually fixed. Previous workaround: You can use an inner frame to "erase" Flash content. This is especially useful on Linux; it allows you to erase parts of a Flash to redraw dynamic HTML over it. An useful link.