HTML & XHTML: Difference between revisions

From Elvanör's Technical Wiki
Jump to navigation Jump to search
No edit summary
 
(54 intermediate revisions by the same user not shown)
Line 6: Line 6:


* <nowiki><span></nowiki> elements are like DIVs, but inline.
* <nowiki><span></nowiki> elements are like DIVs, but inline.
* <nowiki><textarea></nowiki> 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 (<nowiki><label>,<input>,<button></nowiki>) are inline elements.
* <nowiki><div></nowiki> elements are not permitted inside a <nowiki><p></nowiki> element; it is DIV elements that should englobe other elements, not the contrary.
* As much as possible, use elements like <nowiki><strong>, <em>, <cite>, <h1>...</nowiki> 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).


* <nowiki><div></nowiki> elements are not permitted inside a <nowiki><p></nowiki> element; it is DIV elements that should englobe other elements, not the contrary.
=== 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 ==
== Embedding style sheets, JavaScript in HTML documents ==
Line 22: Line 28:


won't work. If you want to pass variables and use a GET method, just create hidden input fields.
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:
<pre>
background-color: transparent;
background-image: url(http://images.example.net/common/site/form-button.png);
border: medium none;
height: 30px;
padding: 0;
width: 115px;
</pre>
* 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.
* [http://test.elvanor.net/css/general/input_file_button.html An example page] giving the correct values for positioning the input element for this technique.


== Tables ==
== Tables ==


* <nowiki><div></nowiki> elements are not permitted, only <tr> and <td>.
* <nowiki><div></nowiki> elements are not permitted, only <tr> and <td>.
* The <nowiki><tbody></nowiki> 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) ==
== Inner Frames (iframes) ==
Line 44: Line 75:
Note that the src attribute on the iframe is not mandatory with this technique.
Note that the src attribute on the iframe is not mandatory with this technique.


* 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 (the Flash player has a bug on Linux that normally prevents HTML content to be drawn over a Flash object). [http://piast.pertus.com.pl/~marcoos/flashlinux/ An useful link.]
== noscript Tag ==


= XHTML 1.1 =
* 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:
<pre>
<noscript>
<style type="text/css">#welcomePage .Dialog {display: block !important;}</style>
</noscript>
</pre>


* Don't use the ''name'' attribute on forms, a, img or map elements. Only use ''id''.
* This works in all browsers, however is not valid W3C code.


= CSS =
== Anchors ==


== Margins, paddings and borders on a table ==
* 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.


Margins don't seem to work at all with table elements (it would work with the table itself, though). Paddings seem to work only with <td> elements, not <tr>.
= XHTML 1.0 & 1.1 =


So the recommended way to specify spacings between elements in a table is through the specific <tt>'border-spacing'</tt> property. Note that this property should be applied to the table element, not the <td>.
* 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.
Note that the border property, specifying the border of the cell, should be on the contrary applied to each <td> cell, like this:
* However, currently there are lots of problems associated with XML documents. In particular, the JavaScript code document.write() does not work. This leads Script.aculo.us (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.
table.WithBorders td {border: 1px solid black; padding: 3px;}
* 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>.


If you write this, borders will have in fact most of the time 2 pixels, because the borders will not be merged between two cells. If you want them to merge (and thus always have only 1 pixel), use <tt>border-collapse: collapse;</tt> in your table element.
== XHTML Strict ==


You can specify certain properties to be applied to an entire column in a table (for exemple the 'border' property). However not all properties can be such applied, apparently. For example, I don't know how to apply the text-align property to an entire column (or if it is even possible).
* 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.


== Selectors ==
= Validation =


To apply an "AND" on a selector in CSS (for example, to apply a style to elements belonging to two classes), just repeat the normal selector, like this:
* 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...


*.first_class.second_class
* 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.
 
This would probably also work on class and ID, etc (untested yet):
 
*.first_class#my_id
 
To select every column in a table except the first one, use the following selector:
 
tr td + td
 
To eliminate the first row from the selector, just add tr +:
 
tr + tr td + td
 
== Display ==
 
* Note that ''display: inline;'' does not restrict the width whatsoever. This means that if you have a <nowiki><div></nowiki> element with display: inline, and a child that creates a block element like <nowiki><p></nowiki>, the child element will take all the place available. This will actually nullify the effect of the parent display: inline property.
 
* Don't use an element that has display: inline property if it contains block children.
 
* ''display: inline-block;'' is currently NOT supported on Firefox (although support is already implemented in CVS as of May 2007), and only partially supported in IE. This means: do not use it.
 
== Absolute Positioning ==
 
* This is done with respect to the parent element/block (the container). Thus, if you have a containing block, and inside a div with absolute positioning and bottom: 0px; it will get drawn at the bottom of the containing block. The parent block needs to have its positioning set as relative, fixed or absolute.
 
== Floats ==
 
* Floats don't work with absolutely or relatively positioned elements, only with those elements in the normal flow.
 
* A div that is positioned to the right of a left floating block still takes the whole width that it is allowed to take. It is only its content that is positioned next to the floating block. This makes it impossible to use properties such as padding-left, they won't apply as expected. You can use a span instead of a div, or position the block as relative and use left: 25p;x instead of padding: 25px.
 
== Containing Blocks ==
 
* A containing block does not necessarily have the height of its children elements. Thus sometimes it is better to set the height on the containing block, and set the height of the child to 100% (with absolute positioning).
 
== Widths and Heights ==
 
* If you have an empty div, setting a width won't make it appear on the page. You will also need to set the height.
 
== Creating a box with custom borders ==
 
* The best is to create a div with some margins. Then put inside 8 divs (if you want a complete custom box!) and set the background-position accordingly for each of the divs. The last thing is to add a last div, the content div, and set the padding in that div equal to the margin set in the outer div.
 
== Vertical Centering ==
 
* See [http://www.zoffix.com/zoffix/css/vertcenter.shtml here for a good article.]
* Basically the following code will work. It does require you to know the height of the block you want to center (another technique allows you to center without assigning a height to the element, but is more complex):
<pre>
<div style="position: relative; height: 200px;">
    <div style="position: absolute; top: 50%; margin-top: -50px; height: 100px;">
Hello World!
    </div>
</div>
</pre>
 
== Horizontal Centering ==
 
* ''text-align: center'' will only work with inline elements. For block level elements you must specify a width on them and use the margin properties (''margin: auto'').
 
== Forms ==


* To get all form elements correctly aligned, the best is to set the width of the labels to an equal value (and to set them as floats, so this width actually applies).
* So the real solution is to install a special Firefox extension for validation. TotalValidator seems a good one.


* Unfortunately, a div element floating next to input fields can mask access to these fields (making impossible to click on the field to select it). One work around is to use a span or restrict the width of the div.
= Flash =


== Inline elements ==
* 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).


* You cannot force an inline element to have a given width. One workaround is to float this element.
* 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. [http://piast.pertus.com.pl/~marcoos/flashlinux/ An useful link.]

Latest revision as of 15:31, 25 November 2010

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

HTML

Elements

  • <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).

Forms

  • 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(http://images.example.net/common/site/form-button.png);
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.

Tables

  • <div> elements are not permitted, only and .
  • 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'>
  </form>

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:
<noscript>
	<style type="text/css">#welcomePage .Dialog {display: block !important;}</style>
</noscript>
  • This works in all browsers, however is not valid W3C code.

Anchors

  • 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 Script.aculo.us (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 (
    ) 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
    .

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.

Validation

  • 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.

Flash

  • 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.