Diff for /books/www/chapters/ch04.html between versions 1.7 and 1.8

version 1.7, 2002/12/04 06:07:15 version 1.8, 2002/12/11 18:57:10
Line 1 Line 1
<HTML>    <style type="text/css">
<HEAD><TITLE>Chapter 4</TITLE></HEAD><BODY BGCOLOR=WHITE><H2>Chapter 4</H2>      div.c13 {font-weight: bold; text-align: center}
<H1><A NAME="77060"></A> CSS in Mozilla Applications</H1>      div.c12 {text-align: center}
<P>This chapter describes how Cascading Style Sheets (CSS) are used to create the look and feel of a Mozilla application's interface. Although XUL has a central role in creating a structure for an application's interface, defining widgets and their functionality, and creating the basic application code, it is CSS that creates the visible portion of an application. XUL and CSS often work so closely together that they seem inseparable, but XUL is generally responsible for the structure of an application's interface and CSS is responsible for the application's presentation. As described in the next sections, it is not until an XPFE application has been "skinned," or styled with stylesheets, that it has a usable interface.    </style>
<P>The first few sections in this chapter provide basic information about using CSS and some examples of how the Mozilla interface is created. 
They include reference material you can refer back to as you learn more. Starting with the "Creating New Skins" section, you can dive in, have     <h2>Chapter 4</h2>
some fun with CSS, and begin to create your own skins. The xFly package example created earlier in the book shows how to add custom styles to the XUL files you created in Chapters <A HREF="ch02.html#68959">2</A> and <A HREF="ch03.html#32764">3</A>.    <h1><a name="77060"></a> CSS in Mozilla Applications</h1>
<H2><A NAME="77061"></A> Interface Basics</H2>    <p>This chapter describes how Cascading Style Sheets (CSS) are
<P>Before describing the  <!--INDEX interfaces:(see also user interface)[interfaces:zz(see also user interface)] -->  <!--INDEX user interface:overview;UI (see user interface) --> practice of using  <!--INDEX CSS (Cascading Style Sheets):user interfaces --> CSS, let's get some basic theory out of the way. When we talk about the interface of an application, we mean all of the parts of the application that are displayed and allow the user to interact. Buttons, windows, pages, menus, sliders, and descriptive text are all parts of the interface. In Mozilla, XUL usually defines the basic structure of the interface and CSS defines its presentation. These two aspects of the interface-the way it's organized and the way it's presented-are kept as distinct from one another as possible in Mozilla and in many good programming environments. Indeed, this separation is what gives rise to the concept of  <!--INDEX skins -->  <!--INDEX user interface:skins --> skins-coherent, separate, and typically swappable "looks" for the same underlying structure. Mozilla uses Cascading Style Sheets, a quickly evolving series of standards already common in HTML web page presentation, to define the skin of XUL application interfaces.    used to create the look and feel of a Mozilla application's
<H3><A NAME="77062"></A> Skins Versus Themes</H3>    interface. Although XUL has a central role in creating a
<P>When we  <!--INDEX skins:compared to themes -->  <!--INDEX themes:compared to skins -->  <!--INDEX user interface:skins:compared to themes --> say <I>skin</I> in this <!--INDEX CSS (Cascading Style Sheets):skins:themes and -->  chapter, we refer to the look of the interface-to the CSS styles and its relationship to the XUL structure underneath. The term <I>theme</I> is also used often in conjunction with interfaces and skins. These words are used interchangeably, although there are some differences in their meaning.    structure for an application's interface, defining widgets and
<P>A single, overall theme is made up of many skins. The Navigator component's skin described in <I> <!--INDEX navigator.css --> navigator.css</I>, for example, is part of the overall Modern theme of Mozilla. Following this definition, the Modern theme may be made up of as many as 20 or 30 different skins corresponding to the major components and major UI features within those components. In addition to <I>navigator.css</I>, for example, there are stylesheets for <I>toolbar.css</I>, <I>linkToolbar.css</I>, and others, which collectively make up the Navigator skin. The CSS files may also be described as skins, as when this book instructs you to "open the <I>messenger.css</I> skin in a text editor." All skins of a particular kind or look organized together comprise a single theme.    their functionality, and creating the basic application code,
<P>Themes are also often used to refer to the different looks that you can download and install for Mozilla and Netscape 6.x and 7.x. (To get new themes for the Mozilla browser go to View &gt; Apply Themes &gt; Get New Themes.) Any application created with Mozilla, though, can have different themes that users can install and select to customize the look of that application.    it is CSS that creates the visible portion of an application.
<P>This distinction between a skin and a theme is not enforced-or even acknowledged-by many people in the Mozilla community, so you will see a profligate use of these terms in practice. Try to remain calm. The terminology differences aren't important. What is important is that you can create one (or many) looks for your application using CSS. This chapter will show you how.    XUL and CSS often work so closely together that they seem
<H3><A NAME="77063"></A> Limitations of a Skin</H3>    inseparable, but XUL is generally responsible for the structure
<P>Skins are used  <!--INDEX skins:limitations of -->  <!--INDEX user interface:skins:limitations of --> to style the structure of an interface that has been created with XUL. Once the interface has been defined in XUL, that structure is set and CSS can be used to change how that structure will look, but can't be used to change the structure itself. In practice, this means that you can use CSS to change the way a button looks--but to move a button from one toolbar to another within the interface, you need to edit your XUL code. Skins generally affect the usability or appearance, but not the functionality of an interface, though the use of XBL in CSS is an exciting exception to this rule, as you will see.    of an application's interface and CSS is responsible for the
<P>This separation of the style and the content of an application means that there are a number of things you can't change in an application using CSS. Here are some examples of the kinds of interface elements that cannot be manipulated with a skin.    application's presentation. As described in the next sections,
<UL><P><LI>The position and contents of menus and menu items and the functionality they trigger.<P>    it is not until an XPFE application has been "skinned," or
<P><LI>The overall layout and functionality of buttons.<P>    styled with stylesheets, that it has a usable interface.</p>
<P><LI>The general layout of the application (although you can use CSS to hide sections of an interface).<P></UL>    <p>The first few sections in this chapter provide basic
<P>While the underlying structure of menus and buttons cannot be changed in the process of editing a theme, you can, of course, change the appearance of things quite radically. In fact, you can change whether an element-say, an item in a menu-has any visibility using the <TT>visibility</TT> or <TT>display</TT> CSS properties. One of the Mozilla extensions to CSS, <TT>-moz-box-ordinal</TT>, lets you set the order in which the elements in a container are displayed. We describe these extensions and others later in this chapter in the section <A HREF="#77083">"Special Mozilla Extensions</A>."    information about using CSS and some examples of how the
<H3><A NAME="77064"></A> Theme Abstraction (or Building Good Skins)</H3>    Mozilla interface is created. They include reference material
<P>One of the most <!--INDEX themes:creating, design considerations -->  <!--INDEX skins:creating:design considerations -->  important  <!--INDEX design issues, user interfaces:themes and skins --> parts of a well-written theme is that it be as separate as possible from the actual structure of the interface-that it be abstracted as a layer so it can be switched or updated without affecting or forcing you to edit the underlying XUL. Keeping an application's style separate is not mandatory, however, and you can have all presentation code in your XUL files, although we explain why this isn't a good idea.    you can refer back to as you learn more. Starting with the
<P>As we have tried to stress, at the most basic level, abstraction means that the XUL should describe the structure and the CSS should describe the presentation, or look, of the interface. In reality, of course, the presentation layer is itself divided into different layers, where lower, more basic files like <I>xul.css</I> describe the look and feel of common UI elements such as buttons and menus, and higher-level CSS files consistently describe the layout and stylistic details of a component. When working on a theme or skin for your application, you should use as few inline style attributes as you can, as well as ensure that your themes are organized into component subdirectories and that one skin does not depend on another that is farther down in the "skin hierarchy." (This is discussed later in this chapter in the <A HREF="#77087">"CSS and Skin Hierarchies</A>" section.).    "Creating New Skins" section, you can dive in, have some fun
<BLOCKQUOTE><HR><B>Planning Your Interface</B>    with CSS, and begin to create your own skins. The xFly package
<P>Before you begin  <!--INDEX user interface:planning considerations --> using CSS and images to style your XUL application code, it's important to have a sense of where your interface is heading. Begin by asking yourself some questions. What should the buttons look like? Do you want to give users the ability to switch skins in your application, as they can in the Mozilla browser? How will your application be affected when the user switches skins in Mozilla? What, if any, are the differences on the different platforms on which you expect users to run your application?    example created earlier in the book shows how to add custom
<P>Although creating interfaces using XUL and CSS is fun and fast, it's best to do a mockup of your interface before you begin so you know where you are heading (both Adobe Photoshop and the GIMP are excellent tools for creating sophisticated images and mock-ups). The creators of the Modern and Classic themes do lots of visualization of the themes in image editing software and go through several iterations of testing and feedback.    styles to the XUL files you created in Chapters <a href=
<P>One of the great advantages of using such an approach is that you will undoubtedly develop images and icons for your interface anyway, and you can slice and dice your mockup to get, for example, the icons for your buttons, the background images, and other real parts of the interface. You may find that you can actually use most of the mockup in your actual interface! See <A HREF="#77084">"Referencing Images in CSS</A>" later in this chapter for an explanation of how this image slicing can work in an advanced way when you have XBL-based widgets that use GIF images that are stitched together.    "ch02.html#68959">2</a> and <a href=
<P>Because the overall theme of an application will most likely consist of a large number of individual graphic elements and widgets, pay special attention to considerations of color palette, web-optimized file formats such as <I>.gif</I> and <I>.png</I>, and file size to make sure your interface looks good and loads quickly.<HR></BLOCKQUOTE>    "ch03.html#32764">3</a>.</p>
    <h2><a name="77061"></a> Interface Basics</h2>
<H3><A NAME="77065"></A> Cross-Platform  <!--INDEX STARTRANGE--Cross-Platform:interface considerations --> Interface Considerations</H3>    <p>Before describing the 
<P>Often in  <!--INDEX STARTRANGE--user interface:design issues, cross-platform considerations -->  <!--INDEX STARTRANGE--design issues, user interfaces:cross-platform considerations --> traditional interface development, you try to make things look and work right on a single platform. Using something like MFC on Windows, for example, you can drop in the widget it provides and be reasonably assured that the interface will look like a Windows application interface whenever and wherever your application is run.    <!--INDEX interfaces:(see also user interface)[interfaces:zz(see also user interface)] -->
<P>When you do cross-platform  <!--INDEX Cross-Platform:user interface development --> user interface development, you need to be aware of how your application will look on the platforms on which it will be used. One common difference, for example, is the layout of scrollbars in Windows applications and in Macintosh applications. On Windows, scrollbars typically have buttons at either end that advance the scrollbar button itself. On the classic Macintosh, the scrollbars are configured so that the buttons are clustered together. The difference is subtle, but it is a source of huge contention in the Mozilla world. <A HREF="#77002">Figure 4-1</A> shows the difference between the scrollbars on the two platforms. (This figure also shows a small notch in the lower righthand corner that is part of all classic Macintosh application windows and that shifts part of the Mozilla interface over to the left.)    <!--INDEX user interface:overview;UI (see user interface) -->
<P><CENTER><IMG SRC="foo.gif"></CENTER>    practice of using 
<P><I>Figure 4-1: <A NAME="77002"></A></I>    <!--INDEX CSS (Cascading Style Sheets):user interfaces --> CSS,
<I>Scrollbars on Windows and on the Macintosh</I>    let's get some basic theory out of the way. When we talk about
    the interface of an application, we mean all of the parts of
<P>When you use the  <!--INDEX Cross-Platform:XPFE -->  <!--INDEX XPFE:user interface cross-platform considerations --> XPFE, you use a single code base to deploy on any number of different platforms. In the Mozilla code, there are some tricks for making things work differently on different platforms. Like scrollbars, the layout of buttons in dialogs is another important area of platform difference. The layout code for the Open Web Location dialog, for example, is defined in platform-specific files, and slightly different dialog layouts are deployed transparently to users (depending on their platform). <A HREF="#77004">Figure 4-2</A> illustrates the differing layouts of this dialog on different platforms (note the different positions of the Open and Cancel buttons in the two images).    the application that are displayed and allow the user to
<P><CENTER><IMG SRC="foo.gif"></CENTER>    interact. Buttons, windows, pages, menus, sliders, and
<P><I>Figure 4-2: <A NAME="77004"></A></I>    descriptive text are all parts of the interface. In Mozilla,
<I>The Open Web Location dialog in Windows and the Macintosh</I>    XUL usually defines the basic structure of the interface and
    CSS defines its presentation. These two aspects of the
<P>If you look in the global resources area of the <I>xpfe</I> in the source code (using a tool like Mozilla's LXR), you can see the platform subdirectories where the buttons in the dialogs are arranged with <TT>&lt;spacer /&gt;</TT>  <!--INDEX spacer element, XUL:user interface cross-platform considerations --> elements and different alignments:    interface-the way it's organized and the way it's presented-are
<PRE>mozilla/xpfe/global/resources/content/    kept as distinct from one another as possible in Mozilla and in
     many good programming environments. Indeed, this separation is
     what gives rise to the concept of <!--INDEX skins --> 
     <!--INDEX user interface:skins --> skins-coherent, separate,
     and typically swappable "looks" for the same underlying
     structure. Mozilla uses Cascading Style Sheets, a quickly
     evolving series of standards already common in HTML web page
     presentation, to define the skin of XUL application
     interfaces.</p>
     <h3><a name="77062"></a> Skins Versus Themes</h3>
     <p>When we <!--INDEX skins:compared to themes --> 
     <!--INDEX themes:compared to skins --> 
     <!--INDEX user interface:skins:compared to themes --> say
     <i>skin</i> in this 
     <!--INDEX CSS (Cascading Style Sheets):skins:themes and -->
     chapter, we refer to the look of the interface-to the CSS
     styles and its relationship to the XUL structure underneath.
     The term <i>theme</i> is also used often in conjunction with
     interfaces and skins. These words are used interchangeably,
     although there are some differences in their meaning.</p>
     <p>A single, overall theme is made up of many skins. The
     Navigator component's skin described in <i>
     <!--INDEX navigator.css --> navigator.css</i>, for example, is
     part of the overall Modern theme of Mozilla. Following this
     definition, the Modern theme may be made up of as many as 20 or
     30 different skins corresponding to the major components and
     major UI features within those components. In addition to
     <i>navigator.css</i>, for example, there are stylesheets for
     <i>toolbar.css</i>, <i>linkToolbar.css</i>, and others, which
     collectively make up the Navigator skin. The CSS files may also
     be described as skins, as when this book instructs you to "open
     the <i>messenger.css</i> skin in a text editor." All skins of a
     particular kind or look organized together comprise a single
     theme.</p>
     <p>Themes are also often used to refer to the different looks
     that you can download and install for Mozilla and Netscape 6.x
     and 7.x. (To get new themes for the Mozilla browser go to View
     &gt; Apply Themes &gt; Get New Themes.) Any application created
     with Mozilla, though, can have different themes that users can
     install and select to customize the look of that
     application.</p>
     <p>This distinction between a skin and a theme is not
     enforced-or even acknowledged-by many people in the Mozilla
     community, so you will see a profligate use of these terms in
     practice. Try to remain calm. The terminology differences
     aren't important. What is important is that you can create one
     (or many) looks for your application using CSS. This chapter
     will show you how.</p>
     <h3><a name="77063"></a> Limitations of a Skin</h3>
     <p>Skins are used <!--INDEX skins:limitations of --> 
     <!--INDEX user interface:skins:limitations of --> to style the
     structure of an interface that has been created with XUL. Once
     the interface has been defined in XUL, that structure is set
     and CSS can be used to change how that structure will look, but
     can't be used to change the structure itself. In practice, this
     means that you can use CSS to change the way a button
     looks--but to move a button from one toolbar to another within
     the interface, you need to edit your XUL code. Skins generally
     affect the usability or appearance, but not the functionality
     of an interface, though the use of XBL in CSS is an exciting
     exception to this rule, as you will see.</p>
     <p>This separation of the style and the content of an
     application means that there are a number of things you can't
     change in an application using CSS. Here are some examples of
     the kinds of interface elements that cannot be manipulated with
     a skin.</p>
     <ul>
       <li>The position and contents of menus and menu items and the
       functionality they trigger.</li>
       <li>The overall layout and functionality of buttons.</li>
       <li>The general layout of the application (although you can
       use CSS to hide sections of an interface).</li>
     </ul>
     <p>While the underlying structure of menus and buttons cannot
     be changed in the process of editing a theme, you can, of
     course, change the appearance of things quite radically. In
     fact, you can change whether an element-say, an item in a
     menu-has any visibility using the <tt>visibility</tt> or
     <tt>display</tt> CSS properties. One of the Mozilla extensions
     to CSS, <tt>-moz-box-ordinal</tt>, lets you set the order in
     which the elements in a container are displayed. We describe
     these extensions and others later in this chapter in the
     section <a href="#77083">"Special Mozilla Extensions</a>."</p>
     <h3><a name="77064"></a> Theme Abstraction (or Building Good
     Skins)</h3>
     <p>One of the most 
     <!--INDEX themes:creating, design considerations --> 
     <!--INDEX skins:creating:design considerations --> important 
     <!--INDEX design issues, user interfaces:themes and skins -->
     parts of a well-written theme is that it be as separate as
     possible from the actual structure of the interface-that it be
     abstracted as a layer so it can be switched or updated without
     affecting or forcing you to edit the underlying XUL. Keeping an
     application's style separate is not mandatory, however, and you
     can have all presentation code in your XUL files, although we
     explain why this isn't a good idea.</p>
     <p>As we have tried to stress, at the most basic level,
     abstraction means that the XUL should describe the structure
     and the CSS should describe the presentation, or look, of the
     interface. In reality, of course, the presentation layer is
     itself divided into different layers, where lower, more basic
     files like <i>xul.css</i> describe the look and feel of common
     UI elements such as buttons and menus, and higher-level CSS
     files consistently describe the layout and stylistic details of
     a component. When working on a theme or skin for your
     application, you should use as few inline style attributes as
     you can, as well as ensure that your themes are organized into
     component subdirectories and that one skin does not depend on
     another that is farther down in the "skin hierarchy." (This is
     discussed later in this chapter in the <a href="#77087">"CSS
     and Skin Hierarchies</a>" section.).</p>
     <blockquote>
       <hr>
       <b>Planning Your Interface</b> 
       <p>Before you begin 
       <!--INDEX user interface:planning considerations --> using
       CSS and images to style your XUL application code, it's
       important to have a sense of where your interface is heading.
       Begin by asking yourself some questions. What should the
       buttons look like? Do you want to give users the ability to
       switch skins in your application, as they can in the Mozilla
       browser? How will your application be affected when the user
       switches skins in Mozilla? What, if any, are the differences
       on the different platforms on which you expect users to run
       your application?</p>
       <p>Although creating interfaces using XUL and CSS is fun and
       fast, it's best to do a mockup of your interface before you
       begin so you know where you are heading (both Adobe Photoshop
       and the GIMP are excellent tools for creating sophisticated
       images and mock-ups). The creators of the Modern and Classic
       themes do lots of visualization of the themes in image
       editing software and go through several iterations of testing
       and feedback.</p>
       <p>One of the great advantages of using such an approach is
       that you will undoubtedly develop images and icons for your
       interface anyway, and you can slice and dice your mockup to
       get, for example, the icons for your buttons, the background
       images, and other real parts of the interface. You may find
       that you can actually use most of the mockup in your actual
       interface! See <a href="#77084">"Referencing Images in
       CSS</a>" later in this chapter for an explanation of how this
       image slicing can work in an advanced way when you have
       XBL-based widgets that use GIF images that are stitched
       together.</p>
       <p>Because the overall theme of an application will most
       likely consist of a large number of individual graphic
       elements and widgets, pay special attention to considerations
       of color palette, web-optimized file formats such as
       <i>.gif</i> and <i>.png</i>, and file size to make sure your
       interface looks good and loads quickly.</p>
       <hr>
     </blockquote>
     <h3><a name="77065"></a> Cross-Platform 
     <!--INDEX STARTRANGE==Cross-Platform:interface considerations -->
     Interface Considerations</h3>
     <p>Often in 
     <!--INDEX STARTRANGE==user interface:design issues, cross-platform considerations -->
     <!--INDEX STARTRANGE==design issues, user interfaces:cross-platform considerations -->
     traditional interface development, you try to make things look
     and work right on a single platform. Using something like MFC
     on Windows, for example, you can drop in the widget it provides
     and be reasonably assured that the interface will look like a
     Windows application interface whenever and wherever your
     application is run.</p>
     <p>When you do cross-platform 
     <!--INDEX Cross-Platform:user interface development --> user
     interface development, you need to be aware of how your
     application will look on the platforms on which it will be
     used. One common difference, for example, is the layout of
     scrollbars in Windows applications and in Macintosh
     applications. On Windows, scrollbars typically have buttons at
     either end that advance the scrollbar button itself. On the
     classic Macintosh, the scrollbars are configured so that the
     buttons are clustered together. The difference is subtle, but
     it is a source of huge contention in the Mozilla world. <a
     href="#77002">Figure 4-1</a> shows the difference between the
     scrollbars on the two platforms. (This figure also shows a
     small notch in the lower righthand corner that is part of all
     classic Macintosh application windows and that shifts part of
     the Mozilla interface over to the left.)</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-1: <a name="77002"></a></i> <i>Scrollbars on
     Windows and on the Macintosh</i></p>
     <p>When you use the <!--INDEX Cross-Platform:XPFE --> 
     <!--INDEX XPFE:user interface cross-platform considerations -->
     XPFE, you use a single code base to deploy on any number of
     different platforms. In the Mozilla code, there are some tricks
     for making things work differently on different platforms. Like
     scrollbars, the layout of buttons in dialogs is another
     important area of platform difference. The layout code for the
     Open Web Location dialog, for example, is defined in
     platform-specific files, and slightly different dialog layouts
     are deployed transparently to users (depending on their
     platform). <a href="#77004">Figure 4-2</a> illustrates the
     differing layouts of this dialog on different platforms (note
     the different positions of the Open and Cancel buttons in the
     two images).</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-2: <a name="77004"></a></i> <i>The Open Web
     Location dialog in Windows and the Macintosh</i></p>
     <p>If you look in the global resources area of the <i>xpfe</i>
     in the source code (using a tool like Mozilla's LXR), you can
     see the platform subdirectories where the buttons in the
     dialogs are arranged with <tt>&lt;spacer /&gt;</tt> 
     <!--INDEX spacer element, XUL:user interface cross-platform considerations -->
     elements and different alignments:</p>
 <pre>
 mozilla/xpfe/global/resources/content/
 mac/  mac/
 platformDialogOverlay.xul  platformDialogOverlay.xul
 os2/  os2/
Line 49  platformDialogOverlay.xul Line 260  platformDialogOverlay.xul
 unix  unix
 platformDialogOverlay.xul  platformDialogOverlay.xul
 win  win
platformDialogOverlay.xul</PRE>platformDialogOverlay.xul
<P>These platform-specific files allow the application developer to write XUL that works the same way on every platform, but preserves subtler aspects of an interface that users expect from their <!--INDEX ENDRANGE--user interface:design issues, cross-platform considerations -->  <!--INDEX ENDRANGE--design issues, user interfaces:cross-platform considerations -->   <!--INDEX ENDRANGE--Cross-Platform:interface considerations --> platform.</pre>
<H2><A NAME="77066"></A> Introduction to CSS in Mozilla</H2>    <p>These platform-specific files allow the application
<P>Now that you have absorbed some of the most important basic aspects of interface design, we can begin to discuss how Mozilla uses CSS and     developer to write XUL that works the same way on every
images to make actual interfaces out of the structure defined in the XUL files. Though XUL contains the widgets and structure upon which the interface rests, it is not until at least some basic skin information has been loaded into the XUL that the interface becomes visible and editable by the user. In addition to this, CSS binds XBL widgets to the basic structure of the XUL code, allowing extended content to appear in your document. For more information about XBL, see <A HREF="ch07.html#70326">Chapter 7</A>.    platform, but preserves subtler aspects of an interface that
<H3><A NAME="77067"></A> Basic XUL + CSS Interaction</H3>    users expect from their 
<P>XUL and CSS interact at two basic levels in Mozilla. At the file level, XUL picks up CSS information by explicitly loading CSS stylesheets at runtime. At the element level, selectors bind CSS rules to specific XUL elements or groups of elements. For an XUL element to pick up a style defined in a CSS file, the XUL file must load the CSS file, and an element or group of elements in the XUL must match a selector in the CSS rule. We discuss these basic levels of interaction in the following two sections.    <!--INDEX ENDRANGE==user interface:design issues, cross-platform considerations -->
<H4><A NAME="77068"></A> CSS and XUL file interaction</H4>    <!--INDEX ENDRANGE==design issues, user interfaces:cross-platform considerations -->
<P>Like HTML,  <!--INDEX CSS (Cascading Style Sheets):XUL:file interaction -->  <!--INDEX XUL (XML-based User-interface Language):CSS:file interaction --> XUL loads style information by including a specific processing instruction somewhere at the top of the file. There are various ways to apply style to HTML pages, including the common example below, in which a  <!--INDEX link element, loading stylesheets --> <TT>&lt;link /&gt;</TT> element with a URI loads an external stylesheet that holds the style information for the web page.    <!--INDEX ENDRANGE==Cross-Platform:interface considerations -->
<PRE>&lt;link rel="stylesheet" href="../style.css" type="text/css"&gt;</PRE>    platform.</p>
<P>In XUL, however, you must use one or more special processing instructions at the top of the XUL file to load the <!--INDEX stylesheets:loading -->  <!--INDEX CSS (Cascading Style Sheets):(see also stylesheets)[CSS (Cascading Style Sheets):zz(see also style sheets)] -->  CSS stylesheet information, or skin, into the XUL.    <h2><a name="77066"></a> Introduction to CSS in Mozilla</h2>
<PRE>&lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;</PRE>    <p>Now that you have absorbed some of the most important basic
<P>Note that the XUL <!--INDEX URLs (Universal Resource Locators):stylesheet loading -->  stylesheet loading supports the use of <TT>http://</TT> and <TT>file://</TT> type URLs, but most often, the <!--INDEX chrome:URLs, stylesheet loading -->  <TT>chrome://</TT> type URL is used, which points to files that are available in the application's chrome subdirectory and that are registered with the chrome registry. The example above uses a special feature of this chrome type URL, which resolves directory pointers to files within those directories that have the same name as the directory itself (thus serving as a shorthand for main theme stylesheets). The chrome URL <TT>chrome://global/skin</TT>, in other words, loads a stylesheet found at <TT>chrome://modern.jar:/global/skin/global.css</TT>.    aspects of interface design, we can begin to discuss how
<BLOCKQUOTE><CENTER><B>NOTE</B></CENTER>    Mozilla uses CSS and images to make actual interfaces out of
<P>XUL also supports the  <!--INDEX inline styles -->  <!--INDEX stylesheets:inline styles --> use of <I>inline styles</I>, which is style information that is applied to individual elements with a style attribute. However, this practice is generally frowned upon, since it overrides the skin information and makes it very difficult for new skins to be applied correctly.<P></BLOCKQUOTE>    the structure defined in the XUL files. Though XUL contains the
<P>Actually, the chrome URL in the example does more than this. Another important function of the chrome registry is that it keeps track of which packages you have installed, which skin you have applied to your application, and resolves URLs like <TT>chrome://global/skin</TT> into the global skin information for the currently selected skin. If you apply the modern skin, for example, then this URL loads the global skin file from the <I>modern.jar</I>; if you apply the Classic skin, then the chrome URL actually resolves to <TT>chrome://classic.jar:/global/skin/global.css</TT> instead. This flexibility in the chrome registry abstracts the structure in the XUL files from the skin information and allows you to create and apply different skins.    widgets and structure upon which the interface rests, it is not
<H4><A NAME="77069"></A> Applying style rules to XUL</H4>    until at least some basic skin information has been loaded into
<P>In CSS,  <!--INDEX CSS (Cascading Style Sheets):selectors -->  <!--INDEX selectors, CSS --> <I>selector</I>  <!--INDEX CSS (Cascading Style Sheets):XUL:applying style rules -->  <!--INDEX XUL (XML-based User-interface Language):CSS:applying style rules --> refers to the element or group of elements to which a style rule is bound-to the thing that is selected for styling. In some cases, the selector is an actual XUL element. The following style rule, for example, says that all XUL <TT>&lt;menu/&gt;</TT> elements in the XUL file(s) into which this CSS is loaded will have a red background color:    the XUL that the interface becomes visible and editable by the
<PRE>menu {    user. In addition to this, CSS binds XBL widgets to the basic
     structure of the XUL code, allowing extended content to appear
     in your document. For more information about XBL, see <a href=
     "ch07.html#70326">Chapter 7</a>.</p>
     <h3><a name="77067"></a> Basic XUL + CSS Interaction</h3>
     <p>XUL and CSS interact at two basic levels in Mozilla. At the
     file level, XUL picks up CSS information by explicitly loading
     CSS stylesheets at runtime. At the element level, selectors
     bind CSS rules to specific XUL elements or groups of elements.
     For an XUL element to pick up a style defined in a CSS file,
     the XUL file must load the CSS file, and an element or group of
     elements in the XUL must match a selector in the CSS rule. We
     discuss these basic levels of interaction in the following two
     sections.</p>
     <h4><a name="77068"></a> CSS and XUL file interaction</h4>
     <p>Like HTML, 
     <!--INDEX CSS (Cascading Style Sheets):XUL:file interaction -->
     <!--INDEX XUL (XML-based User-interface Language):CSS:file interaction -->
     XUL loads style information by including a specific processing
     instruction somewhere at the top of the file. There are various
     ways to apply style to HTML pages, including the common example
     below, in which a 
     <!--INDEX link element, loading stylesheets --> <tt>&lt;link
     /&gt;</tt> element with a URI loads an external stylesheet that
     holds the style information for the web page.</p>
 <pre>
 &lt;link rel="stylesheet" href="../style.css" type="text/css"&gt;
 </pre>
     <p>In XUL, however, you must use one or more special processing
     instructions at the top of the XUL file to load the 
     <!--INDEX stylesheets:loading --> 
     <!--INDEX CSS (Cascading Style Sheets):(see also stylesheets)[CSS (Cascading Style Sheets):zz(see also style sheets)] -->
     CSS stylesheet information, or skin, into the XUL.</p>
 <pre>
 &lt;?xml-stylesheet href="chrome://global/skin" type="text/css"?&gt;
 </pre>
     <p>Note that the XUL 
     <!--INDEX URLs (Universal Resource Locators):stylesheet loading -->
     stylesheet loading supports the use of <tt>http://</tt> and
     <tt>file://</tt> type URLs, but most often, the 
     <!--INDEX chrome:URLs, stylesheet loading -->
     <tt>chrome://</tt> type URL is used, which points to files that
     are available in the application's chrome subdirectory and that
     are registered with the chrome registry. The example above uses
     a special feature of this chrome type URL, which resolves
     directory pointers to files within those directories that have
     the same name as the directory itself (thus serving as a
     shorthand for main theme stylesheets). The chrome URL
     <tt>chrome://global/skin</tt>, in other words, loads a
     stylesheet found at
     <tt>chrome://modern.jar:/global/skin/global.css</tt>.</p>
     <blockquote>
       <div class="c13">
         NOTE
       </div>
       <p>XUL also supports the <!--INDEX inline styles --> 
       <!--INDEX stylesheets:inline styles --> use of <i>inline
       styles</i>, which is style information that is applied to
       individual elements with a style attribute. However, this
       practice is generally frowned upon, since it overrides the
       skin information and makes it very difficult for new skins to
       be applied correctly.</p>
     </blockquote>
     <p>Actually, the chrome URL in the example does more than this.
     Another important function of the chrome registry is that it
     keeps track of which packages you have installed, which skin
     you have applied to your application, and resolves URLs like
     <tt>chrome://global/skin</tt> into the global skin information
     for the currently selected skin. If you apply the modern skin,
     for example, then this URL loads the global skin file from the
     <i>modern.jar</i>; if you apply the Classic skin, then the
     chrome URL actually resolves to
     <tt>chrome://classic.jar:/global/skin/global.css</tt> instead.
     This flexibility in the chrome registry abstracts the structure
     in the XUL files from the skin information and allows you to
     create and apply different skins.</p>
     <h4><a name="77069"></a> Applying style rules to XUL</h4>
     <p>In CSS, <!--INDEX CSS (Cascading Style Sheets):selectors -->
     <!--INDEX selectors, CSS --> <i>selector</i> 
     <!--INDEX CSS (Cascading Style Sheets):XUL:applying style rules -->
     <!--INDEX XUL (XML-based User-interface Language):CSS:applying style rules -->
     refers to the element or group of elements to which a style
     rule is bound-to the thing that is selected for styling. In
     some cases, the selector is an actual XUL element. The
     following style rule, for example, says that all XUL
     <tt>&lt;menu/&gt;</tt> elements in the XUL file(s) into which
     this CSS is loaded will have a red background color:</p>
 <pre>
 menu {
 background-color: red;  background-color: red;
}</PRE>}
<P>In this case, the element selector names an element (menu) directly: all elements of that type match and are styled with the rule. In the next few sections, we describe the main types of selectors and the style rules that can be applied to them. With a couple of notable exceptions (see <A HREF="#77083">"Special Mozilla Extensions</A>" later in this chapter), the CSS you use with XUL is the same one you use for HTML elements.</pre>
<H4><A NAME="77070"></A> Inline styles</H4>    <p>In this case, the element selector names an element (menu)
<P>Another way to  <!--INDEX CSS (Cascading Style Sheets):XUL:inline styles -->  <!--INDEX XUL (XML-based User-interface Language):CSS:inline styles --> apply style to XUL elements is to use inline style rules. Use inline styles with caution. All XUL elements have a <TT>style</TT> attribute that can be used to define styles directly for that element. In the following example, the <TT>style</TT> attribute is used (in a common but somewhat deprecated manner) to hide the XUL element-to apply a style that suppresses rendering of the element (though it still takes up space in the UI):    directly: all elements of that type match and are styled with
<PRE>&lt;menuitem id="e_src"    the rule. In the next few sections, we describe the main types
     of selectors and the style rules that can be applied to them.
     With a couple of notable exceptions (see <a href=
     "#77083">"Special Mozilla Extensions</a>" later in this
     chapter), the CSS you use with XUL is the same one you use for
     HTML elements.</p>
     <h4><a name="77070"></a> Inline styles</h4>
     <p>Another way to 
     <!--INDEX CSS (Cascading Style Sheets):XUL:inline styles --> 
     <!--INDEX XUL (XML-based User-interface Language):CSS:inline styles -->
     apply style to XUL elements is to use inline style rules. Use
     inline styles with caution. All XUL elements have a
     <tt>style</tt> attribute that can be used to define styles
     directly for that element. In the following example, the
     <tt>style</tt> attribute is used (in a common but somewhat
     deprecated manner) to hide the XUL element-to apply a style
     that suppresses rendering of the element (though it still takes
     up space in the UI):</p>
 <pre>
 &lt;menuitem id="e_src"
 label="&amp;editsrc.label;"  label="&amp;editsrc.label;"
style="visibility: none;" /&gt;</PRE>style="visibility: none;" /&gt;
<P>When you use inline styles, the syntax does not include the brackets, but you can still add multiple style rules by using the semicolon. The item before the colon is the property, and the item after it is its value. The format of inline styles is as follows:</pre>
<PRE>style="style attribute1: value[; style attribute2: value; etc...]"</PRE>    <p>When you use inline styles, the syntax does not include the
<P>The reason why inline styles are frowned upon in XUL and skin development is that they can be extremely difficult to locate and work around when you design a new skin and want to change the appearance of an element that has an inline style. The style attribute takes precedence over styles applied from other sources-inline styles are the last rule in the cascade of style rules-so they cascade over styles defined in a skin and may "break" the overall look of that skin.    brackets, but you can still add multiple style rules by using
<P>Besides this problem, many tricks for which application developers use the inline style can be done using XUL attributes. It's very common to use the CSS attribute-value pairs display: <TT>none;</TT> or visibility: <TT>none;</TT> to hide elements in order to change what's available from the interface. However, smart XUL developers use the <TT>hidden<I> </I>or thecollapse</TT> attribute instead, thereby keeping structural matters as separate from style matters as possible.    the semicolon. The item before the colon is the property, and
<H3><A NAME="77071"></A> Stylesheet Syntax</H3>    the item after it is its value. The format of inline styles is
<P>Cascading Style Sheets  <!--INDEX STARTRANGE--style definitions -->  <!--INDEX STARTRANGE--CSS (Cascading Style Sheets):style definitions --> are the blueprints for Mozilla skins. In Cascading Style Sheets, style definitions take the following basic form:    as follows:</p>
<PRE>element {<pre>
 style="style attribute1: value[; style attribute2: value; etc...]"
 </pre>
     <p>The reason why inline styles are frowned upon in XUL and
     skin development is that they can be extremely difficult to
     locate and work around when you design a new skin and want to
     change the appearance of an element that has an inline style.
     The style attribute takes precedence over styles applied from
     other sources-inline styles are the last rule in the cascade of
     style rules-so they cascade over styles defined in a skin and
     may "break" the overall look of that skin.</p>
     <p>Besides this problem, many tricks for which application
     developers use the inline style can be done using XUL
     attributes. It's very common to use the CSS attribute-value
     pairs display: <tt>none;</tt> or visibility: <tt>none;</tt> to
     hide elements in order to change what's available from the
     interface. However, smart XUL developers use the <tt>hidden or
     thecollapse</tt> attribute instead, thereby keeping structural
     matters as separate from style matters as possible.</p>
     <h3><a name="77071"></a> Stylesheet Syntax</h3>
     <p>Cascading Style Sheets 
     <!--INDEX STARTRANGE==style definitions --> 
     <!--INDEX STARTRANGE==CSS (Cascading Style Sheets):style definitions -->
     are the blueprints for Mozilla skins. In Cascading Style
     Sheets, style definitions take the following basic form:</p>
 <pre>
 element {
 style attribute1: value;  style attribute1: value;
 style attribute2: value;  style attribute2: value;
 style attribute3: value;  style attribute3: value;
}</PRE>}
<P>For example, the following definition makes all XUL menus appear with a one-pixel border, a light-blue background, and ten-point fonts:</pre>
<PRE>menu {    <p>For example, the following definition makes all XUL menus
     appear with a one-pixel border, a light-blue background, and
     ten-point fonts:</p>
 <pre>
 menu {
 border: 1px;  border: 1px;
 background-color: lightblue;  background-color: lightblue;
 font-size: 10pt;  font-size: 10pt;
}</PRE>}
<P>This is an example of using the element itself-in this case, a "menu"-as a selector (the item to which the style definition is applied). In addition to the basic element selector and style rules, CSS provides the application of style information to classes of elements, element IDs, and elements with particular attributes or states. The following three sections demonstrate the basic format for these three common style selectors.</pre>
<H4><A NAME="77072"></A> The element selector</H4>    <p>This is an example of using the element itself-in this case,
<P>The <I>element</I> <I>selector</I> is  <!--INDEX element selectors, CSS -->  <!--INDEX CSS (Cascading Style Sheets):selectors:element -->  <!--INDEX selectors, CSS:element --> the most basic kind of selector. It is just the name of the element to be styled at the front of the style rule. In the previous example, the <TT>&lt;menuitem /&gt;</TT> element, defined in a XUL file that loads this style rule, will have a light blue background color:    a "menu"-as a selector (the item to which the style definition
<PRE>element { attribute: value; }    is applied). In addition to the basic element selector and
menuitem  { background-color: lightblue; }</PRE>    style rules, CSS provides the application of style information
<H4><A NAME="77073"></A> The pseudoelement selector</H4>    to classes of elements, element IDs, and elements with
<P>The <I>pseudoelement</I> <I>selector</I>  <!--INDEX pseudoelement selectors, CSS -->  <!--INDEX CSS (Cascading Style Sheets):selectors:pseudoelement -->  <!--INDEX selectors, CSS:pseudoelement --> selects a piece of an element for styling. While a selector like <TT>menuitem</TT> picks up all menu items in a given XUL document, a pseudoelement selector like <TT>menuitem:first-letter</TT> binds the rule's styles to only the first letter in a <TT>menuitem</TT> value.    particular attributes or states. The following three sections
<PRE>menuitem:first-letter { text-decoration: underline; }    demonstrate the basic format for these three common style
description:first-line { margin-left: .25in; }</PRE>    selectors.</p>
<P>The first style rule above gives all menu items to which it applies the look of being <TT>accesskey</TT> enabled. The second creates an indentation in the first line of a XUL <TT>description</TT> element's text. Menu access keys let you open and choose items from a menu by using the underlined letters and modifiers (e.g., "F" and <TT>&lt;alt&gt;</TT> to open the File menu).    <h4><a name="77072"></a> The element selector</h4>
<H4><A NAME="77074"></A> The class selector</H4>    <p>The <i>element</i> <i>selector</i> is 
<P>The <I>class selector</I>  <!--INDEX class selectors, CSS -->  <!--INDEX CSS (Cascading Style Sheets):selectors:class -->  <!--INDEX selectors, CSS:class --> applies the style rule to all XUL widgets of a given class. In the XUL files that define the structure of Netscape 7, the class is specified with the <TT>class</TT> attribute (e.g., <TT>&lt;menu class="baseline"&gt;</TT>) and in CSS with the dot notation:    <!--INDEX element selectors, CSS --> 
<PRE>element.class { attribute: value;}    <!--INDEX CSS (Cascading Style Sheets):selectors:element --> 
menu.baseline {   border: 0px;   font-size: 9pt; }</PRE>    <!--INDEX selectors, CSS:element --> the most basic kind of
<P>In this example, all menus with a XUL baseline class have no borders and a nine-point font size. Note that you can use the class without the preceding XUL element to skin all XUL elements with a given class. In <A HREF="#77030">Example 4-1</A>, both the XUL box and the XUL menu pick up the style given in the "redbox" class style definition.    selector. It is just the name of the element to be styled at
    the front of the style rule. In the previous example, the
<P><I>Example 4-1: <A NAME="77030"></A></I>    <tt>&lt;menuitem /&gt;</tt> element, defined in a XUL file that
<I>Class selector in CSS</I>    loads this style rule, will have a light blue background
<PRE> .redbox {    color:</p>
 <pre>
 element { attribute: value; }
 menuitem  { background-color: lightblue; }
 </pre>
     <h4><a name="77073"></a> The pseudoelement selector</h4>
     <p>The <i>pseudoelement</i> <i>selector</i> 
     <!--INDEX pseudoelement selectors, CSS --> 
     <!--INDEX CSS (Cascading Style Sheets):selectors:pseudoelement -->
     <!--INDEX selectors, CSS:pseudoelement --> selects a piece of
     an element for styling. While a selector like <tt>menuitem</tt>
     picks up all menu items in a given XUL document, a
     pseudoelement selector like <tt>menuitem:first-letter</tt>
     binds the rule's styles to only the first letter in a
     <tt>menuitem</tt> value.</p>
 <pre>
 menuitem:first-letter { text-decoration: underline; }
 description:first-line { margin-left: .25in; }
 </pre>
     <p>The first style rule above gives all menu items to which it
     applies the look of being <tt>accesskey</tt> enabled. The
     second creates an indentation in the first line of a XUL
     <tt>description</tt> element's text. Menu access keys let you
     open and choose items from a menu by using the underlined
     letters and modifiers (e.g., "F" and <tt>&lt;alt&gt;</tt> to
     open the File menu).</p>
     <h4><a name="77074"></a> The class selector</h4>
     <p>The <i>class selector</i> <!--INDEX class selectors, CSS -->
     <!--INDEX CSS (Cascading Style Sheets):selectors:class --> 
     <!--INDEX selectors, CSS:class --> applies the style rule to
     all XUL widgets of a given class. In the XUL files that define
     the structure of Netscape 7, the class is specified with the
     <tt>class</tt> attribute (e.g., <tt>&lt;menu
     class="baseline"&gt;</tt>) and in CSS with the dot
     notation:</p>
 <pre>
 element.class { attribute: value;}
 menu.baseline {   border: 0px;   font-size: 9pt; }
 </pre>
     <p>In this example, all menus with a XUL baseline class have no
     borders and a nine-point font size. Note that you can use the
     class without the preceding XUL element to skin all XUL
     elements with a given class. In <a href="#77030">Example
     4-1</a>, both the XUL box and the XUL menu pick up the style
     given in the "redbox" class style definition.</p>
     <p><i>Example 4-1: <a name="77030"></a></i> <i>Class selector
     in CSS</i></p>
 <pre>
  .redbox {
    border: 2px solid red;     border: 2px solid red;
    font-size: 9pt;     font-size: 9pt;
  }   }
  &lt;box class="redbox"&gt;   &lt;box class="redbox"&gt;
      &lt;menu class="redbox"&gt;       &lt;menu class="redbox"&gt;
      &lt;menu class="bluebox"&gt;       &lt;menu class="bluebox"&gt;
 &lt;/box&gt;</PRE> &lt;/box&gt;
</pre>
<H4><A NAME="77075"></A> The ID selector</H4>    <h4><a name="77075"></a> The ID selector</h4>
<P>The CSS <I>ID selector</I>  <!--INDEX CSS (Cascading Style Sheets):selectors:ID -->  <!--INDEX selectors, CSS:ID --> applies the style rule to a unique XUL element. As with <TT>class</TT>, the <TT>ID</TT> is specified in the XUL with an attribute (e.g., <TT>&lt;menu id="file_menu"&gt;</TT>) and in the CSS with the pound sign preceding the <TT>ID</TT> itself. In this example, the menu with an ID of <TT>edit</TT> has a red color:    <p>The CSS <i>ID selector</i> 
<PRE>element#id { attribute: value;}    <!--INDEX CSS (Cascading Style Sheets):selectors:ID --> 
menu#edit { color: red;}</PRE>    <!--INDEX selectors, CSS:ID --> applies the style rule to a
<P>In the example above, both the element type and the element ID are given. You can also identify elements anonymously (though still uniquely) by using just the selector:    unique XUL element. As with <tt>class</tt>, the <tt>ID</tt> is
<PRE>#whitey {    specified in the XUL with an attribute (e.g., <tt>&lt;menu
     id="file_menu"&gt;</tt>) and in the CSS with the pound sign
     preceding the <tt>ID</tt> itself. In this example, the menu
     with an ID of <tt>edit</tt> has a red color:</p>
 <pre>
 element#id { attribute: value;}
 menu#edit { color: red;}
 </pre>
     <p>In the example above, both the element type and the element
     ID are given. You can also identify elements anonymously
     (though still uniquely) by using just the selector:</p>
 <pre>
 #whitey {
 background-color: white;  background-color: white;
 margin: .25in;  margin: .25in;
}</PRE>}
<P>In the case of IDs, these are selectors are identical, since IDs need to be unique across the whole XUL file. When you use classes, however, the typeless style rule is a good way to apply your style information to a range of elements.</pre>
<H4><A NAME="77076"></A> The attribute selector</H4>    <p>In the case of IDs, these are selectors are identical, since
<P>The <I>attribute selector</I>  <!--INDEX attribute selectors, CSS -->  <!--INDEX CSS (Cascading Style Sheets):selectors:attrribute -->  <!--INDEX selectors, CSS:attribute --> allows you to style XUL elements with particular attributes or with attributes of a particular value. In <A HREF="#77032">Example 4-2</A>, all elements with a disabled attribute set to <TT>true</TT> will have a light-grey color.    IDs need to be unique across the whole XUL file. When you use
    classes, however, the typeless style rule is a good way to
<P><I>Example 4-2: <A NAME="77032"></A></I>    apply your style information to a range of elements.</p>
<I>Attribute selector in CSS</I>    <h4><a name="77076"></a> The attribute selector</h4>
<PRE> element </TD>[attribute=value] { attribute: value; }    <p>The <i>attribute selector</i> 
 element </TD>[attribute~=value] { attribute: value; }    <!--INDEX attribute selectors, CSS --> 
 *</TD>[disabled="true"]    <!--INDEX CSS (Cascading Style Sheets):selectors:attrribute -->
     <!--INDEX selectors, CSS:attribute --> allows you to style XUL
     elements with particular attributes or with attributes of a
     particular value. In <a href="#77032">Example 4-2</a>, all
     elements with a disabled attribute set to <tt>true</tt> will
     have a light-grey color.</p>
     <p><i>Example 4-2: <a name="77032"></a></i> <i>Attribute
     selector in CSS</i></p>
 <pre>
  element &lt;/td&gt;[attribute=value] { attribute: value; }
  element &lt;/td&gt;[attribute~=value] { attribute: value; }
  *&lt;/td&gt;[disabled="true"]
  {   {
    color: lightgrey;     color: lightgrey;
  }   }
 menu</TD>[value="File"] { menu&lt;/td&gt;[value="File"] {
    font-weight: bold;     font-weight: bold;
  }   }
 [id~="my"] { color: red; }</PRE><P> [id~="my"] { color: red; }
</pre>
<P>Note that <A HREF="#77032">Example 4-2</A> uses the <TT>*</TT> character for selecting all elements. This "wildcard" selector can be combined with attribute and other selectors to make a powerful filter in your CSS stylesheets-but of course, in an example like <A HREF="#77032">Example 4-2</A>, it could be omitted and [disabled=true] would still apply to all elements with that attribute set to that value.    <p>Note that <a href="#77032">Example 4-2</a> uses the
<P><A HREF="#77032">Example 4-2</A> also uses <TT>~=</TT> to match attributes that contain the given fragment. In this case, any elements that have an ID with the fragment "my" have text colored red, as when you want to see all your customized elements for debugging purposes.    <tt>*</tt> character for selecting all elements. This
<H4><A NAME="77077"></A> Pseudoclass selectors</H4>    "wildcard" selector can be combined with attribute and other
<P>Another  <!--INDEX pseudoclass selectors, CSS -->  <!--INDEX CSS (Cascading Style Sheets):selectors:pseudoclass -->  <!--INDEX selectors, CSS:pseudoclass --> feature of CSS-2 that Mozilla makes extensive use of is the <I>pseudoclass</I>. In CSS, pseudoclasses are used to represent different states for elements that are manipulated by the user, such as buttons. The states-represented by pseudoclasses such as <TT>active</TT>, <TT>focus</TT>, and <TT>hover-</TT>change when the user interacts with an element. The pseudoclasses actually correspond to events on the interface elements.    selectors to make a powerful filter in your CSS stylesheets-but
<P>The : character is used to add these <TT>pseudoclasses</TT> in the CSS notation:    of course, in an example like <a href="#77032">Example 4-2</a>,
<PRE>#forwardButton:hover    it could be omitted and [disabled=true] would still apply to
     all elements with that attribute set to that value.</p>
     <p><a href="#77032">Example 4-2</a> also uses <tt>~=</tt> to
     match attributes that contain the given fragment. In this case,
     any elements that have an ID with the fragment "my" have text
     colored red, as when you want to see all your customized
     elements for debugging purposes.</p>
     <h4><a name="77077"></a> Pseudoclass selectors</h4>
     <p>Another <!--INDEX pseudoclass selectors, CSS --> 
     <!--INDEX CSS (Cascading Style Sheets):selectors:pseudoclass -->
     <!--INDEX selectors, CSS:pseudoclass --> feature of CSS-2 that
     Mozilla makes extensive use of is the <i>pseudoclass</i>. In
     CSS, pseudoclasses are used to represent different states for
     elements that are manipulated by the user, such as buttons. The
     states-represented by pseudoclasses such as <tt>active</tt>,
     <tt>focus</tt>, and <tt>hover-</tt>change when the user
     interacts with an element. The pseudoclasses actually
     correspond to events on the interface elements.</p>
     <p>The : character is used to add these <tt>pseudoclasses</tt>
     in the CSS notation:</p>
 <pre>
 #forwardButton:hover
 {  {
 list-style-image      : url("chrome://navigator/skin/forward-hover.gif");  list-style-image      : url("chrome://navigator/skin/forward-hover.gif");
}</PRE>}
<P>The pseudoclass is often appended to another style. Since specific CSS style rules inherit from more general rules (see the section <A HREF="#77087">"CSS and Skin Hierarchies</A>" later in this chapter for more information about this inheritance), the example above picks up any styles defined for the button with the <TT>id</TT> of <TT>forwardButton</TT> (and any class-based information, as well as the basic CSS for a button), but substitutes whatever image is used with this special GIF that represents a button being moused or hovered over.</pre>
<P>In Mozilla's Modern skin, the pseudoclasses work collectively to give buttons their appearance and behavior. Each of the following button images in <A HREF="#77006">Figure 4-3</A> is associated with a different pseudoclass (or attribute, as we discuss in the next section). As soon as the pseudoclass is changed by user interaction (e.g., the user hovers the mouse over the button), the state changes and the effect is one of seamless transition.    <p>The pseudoclass is often appended to another style. Since
<P><CENTER><IMG SRC="foo.gif"></CENTER>    specific CSS style rules inherit from more general rules (see
<P><I>Figure 4-3: <A NAME="77006"></A></I>    the section <a href="#77087">"CSS and Skin Hierarchies</a>"
<I>The different states for buttons in the Modern theme</I>    later in this chapter for more information about this
    inheritance), the example above picks up any styles defined for
<H4><A NAME="77078"></A> Element relation selectors</H4>    the button with the <tt>id</tt> of <tt>forwardButton</tt> (and
<P>Contextual  <!--INDEX relational selectors, CSS -->  <!--INDEX CSS (Cascading Style Sheets):selectors:relational -->  <!--INDEX selectors, CSS:relational --> subgroups-elements appearing within other elements, such as italicized text within a <TT>&lt;p&gt;</TT> element or a <TT>&lt;body&gt;</TT> in HTML-can be grouped in CSS, but this is an extremely inefficient way to style XUL. CSS2 also provides ways to group elements for styling based on their relationship in the object model. <A HREF="#77022">Table 4-1</A> lists these relational selectors.    any class-based information, as well as the basic CSS for a
    button), but substitutes whatever image is used with this
<P><I>Table 4-1: <A NAME="77022"></A></I>    special GIF that represents a button being moused or hovered
<I>Relational selectors</I>    over.</p>
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Selector</B></TD> <TD><B>  Syntax</B></TD> <TD><B>  Example</B></TD></TR>    <p>In Mozilla's Modern skin, the pseudoclasses work
<TR><TD>  Descendent</TD>     <TD> ancestor descendent {</TD></TR>    collectively to give buttons their appearance and behavior.
<TR><TD>  attribute: value;</TD></TR>    Each of the following button images in <a href="#77006">Figure
<TR><TD> }</TD> <TD> toolbar.primary menutitem#F {</TD></TR>    4-3</a> is associated with a different pseudoclass (or
<TR><TD>   border: 1px;</TD></TR>    attribute, as we discuss in the next section). As soon as the
<TR><TD> }</TD></TR>    pseudoclass is changed by user interaction (e.g., the user
<TR><TD>  Parent-Child</TD>     <TD> parent &gt; child {</TD></TR>    hovers the mouse over the button), the state changes and the
<TR><TD>   attribute: value;</TD></TR>    effect is one of seamless transition.</p>
<TR><TD> }</TD> <TD> menu#file &gt; menuitem {</TD></TR>    <div class="c12">
<TR><TD>   font-weight: bold;</TD></TR>      <img src="foo.gif">
<TR><TD> }</TD></TR>    </div>
<TR><TD>  Precedence</TD>     <TD> elBefore + elAfter {</TD></TR>    <p><i>Figure 4-3: <a name="77006"></a></i> <i>The different
<TR><TD>   attribute: value;</TD></TR>    states for buttons in the Modern theme</i></p>
<TR><TD> }</TD> <TD> menuitem#file + menuitem#edit {</TD></TR>    <h4><a name="77078"></a> Element relation selectors</h4>
<TR><TD>   background-color: black;</TD></TR>    <p>Contextual <!--INDEX relational selectors, CSS --> 
<TR><TD> }</TD></TR></TABLE><P>    <!--INDEX CSS (Cascading Style Sheets):selectors:relational -->
    <!--INDEX selectors, CSS:relational --> subgroups-elements
<P>In the descendent example in <A HREF="#77022">Table 4-1</A>, the "F" <TT>menuitem</TT> has a border only when it appears within the <TT>toolbar</TT> whose class is given as "primary." In the parent-child example, all menu items in a menu with the <TT>id</TT> "file" are made bold. Using +, the precedence selector says that the "edit" menu should have a black background only when it comes after the "file" menu. You can use these element relation selectors to create longer descensions (e.g., <TT>toolbar.primary &gt; menu#file &gt; menuitem#new</TT>), but remember that the processing gets more expensive with each new level, and that the descendent operation is particularly processor-intensive.    appearing within other elements, such as italicized text within
<H4><A NAME="77079"></A> The !important keyword</H4>    a <tt>&lt;p&gt;</tt> element or a <tt>&lt;body&gt;</tt> in
<P>As you might  <!--INDEX !important keyword (CSS) -->  <!--INDEX keywords, CSS -->  <!--INDEX CSS (Cascading Style Sheets):!important keyword --> imagine, when you have a technology with such strong notions of precedence as Cascading Style Sheets (the ID-based style trumps the class-based style, inline style attributes trump those loaded from an external stylesheet, etc.), you may need to identify and set aside certain styles as the most important, regardless of where they are found in the cascade.    HTML-can be grouped in CSS, but this is an extremely
<P>This is the role played by the <TT>!important</TT> keyword. Sitting to the right of a style value, it specifies that style rule should take precedence over all of its competitors and that it should be applied all the time. <A HREF="#77034">Example 4-3</A> demonstrates how no borders are rendered on <I>treecells </I>of the class <I>treecell-editor</I> because of the <TT>!important</TT> keyword.    inefficient way to style XUL. CSS2 also provides ways to group
    elements for styling based on their relationship in the object
<P><I>Example 4-3: <A NAME="77034"></A></I>    model. <a href="#77022">Table 4-1</a> lists these relational
<I>!important keyword in CSS</I>    selectors.</p>
<PRE> .treecell-editor,    <p><i>Table 4-1: <a name="77022"></a></i> <i>Relational
     selectors</i></p>
     <table width="100%" border="1">
       <tr>
         <td><b>Selector</b></td>
         <td><b>Syntax</b></td>
         <td><b>Example</b></td>
       </tr>
       <tr>
         <td>Descendent</td>
         <td>ancestor descendent {</td>
       </tr>
       <tr>
         <td>attribute: value;</td>
       </tr>
       <tr>
         <td>}</td>
         <td>toolbar.primary menutitem#F {</td>
       </tr>
       <tr>
         <td>border: 1px;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>Parent-Child</td>
         <td>parent &gt; child {</td>
       </tr>
       <tr>
         <td>attribute: value;</td>
       </tr>
       <tr>
         <td>}</td>
         <td>menu#file &gt; menuitem {</td>
       </tr>
       <tr>
         <td>font-weight: bold;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>Precedence</td>
         <td>elBefore + elAfter {</td>
       </tr>
       <tr>
         <td>attribute: value;</td>
       </tr>
       <tr>
         <td>}</td>
         <td>menuitem#file + menuitem#edit {</td>
       </tr>
       <tr>
         <td>background-color: black;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
     </table>
     <p>In the descendent example in <a href="#77022">Table 4-1</a>,
     the "F" <tt>menuitem</tt> has a border only when it appears
     within the <tt>toolbar</tt> whose class is given as "primary."
     In the parent-child example, all menu items in a menu with the
     <tt>id</tt> "file" are made bold. Using +, the precedence
     selector says that the "edit" menu should have a black
     background only when it comes after the "file" menu. You can
     use these element relation selectors to create longer
     descensions (e.g., <tt>toolbar.primary &gt; menu#file &gt;
     menuitem#new</tt>), but remember that the processing gets more
     expensive with each new level, and that the descendent
     operation is particularly processor-intensive.</p>
     <h4><a name="77079"></a> The !important keyword</h4>
     <p>As you might <!--INDEX !important keyword (CSS) --> 
     <!--INDEX keywords, CSS --> 
     <!--INDEX CSS (Cascading Style Sheets):!important keyword -->
     imagine, when you have a technology with such strong notions of
     precedence as Cascading Style Sheets (the ID-based style trumps
     the class-based style, inline style attributes trump those
     loaded from an external stylesheet, etc.), you may need to
     identify and set aside certain styles as the most important,
     regardless of where they are found in the cascade.</p>
     <p>This is the role played by the <tt>!important</tt> keyword.
     Sitting to the right of a style value, it specifies that style
     rule should take precedence over all of its competitors and
     that it should be applied all the time. <a href=
     "#77034">Example 4-3</a> demonstrates how no borders are
     rendered on <i>treecells</i> of the class
     <i>treecell-editor</i> because of the <tt>!important</tt>
     keyword.</p>
     <p><i>Example 4-3: <a name="77034"></a></i> <i>!important
     keyword in CSS</i></p>
 <pre>
  .treecell-editor,
  .treecell-editor &gt; box {   .treecell-editor &gt; box {
    margin: 0px !important;     margin: 0px !important;
    padding: 0px !important;     padding: 0px !important;
  }   }
  .treecell-editor {   .treecell-editor {
    border: 0px !important;     border: 0px !important;
 }</PRE> }
</pre>
<P>You can search for the <TT>!important</TT> keyword in the LXR Mozilla source code tool and see its use in the Mozilla CSS.    <p>You can search for the <tt>!important</tt> keyword in the
<H4><A NAME="77080"></A> The inherits value</H4>    LXR Mozilla source code tool and see its use in the Mozilla
<P>CSS uses  <!--INDEX inherits value (CSS) -->  <!--INDEX CSS (Cascading Style Sheets):inherits value --> inheritance all over the place. Inheritance is implicit in the way style rules are applied, stylesheets are organized in the chrome, and skins borrow from one another in Mozilla. However, a special CSS value indicates that the selector explicitly inherits its value from the parent element.    CSS.</p>
<P>When a CSS property has a value of <TT>inherit</TT>, that property's real value is pulled from the parent element:    <h4><a name="77080"></a> The inherits value</h4>
<PRE>.child {    <p>CSS uses <!--INDEX inherits value (CSS) --> 
     <!--INDEX CSS (Cascading Style Sheets):inherits value -->
     inheritance all over the place. Inheritance is implicit in the
     way style rules are applied, stylesheets are organized in the
     chrome, and skins borrow from one another in Mozilla. However,
     a special CSS value indicates that the selector explicitly
     inherits its value from the parent element.</p>
     <p>When a CSS property has a value of <tt>inherit</tt>, that
     property's real value is pulled from the parent element:</p>
 <pre>
 .child {
 color: darkblue;  color: darkblue;
 height: inherit;  height: inherit;
 background-color: inherit;  background-color: inherit;
}</PRE>}
<P>This block specifies a dark blue color for the font, but the values of the other two properties are inherited from the parent. In many cases, this has the same effect as not specifying any value at all for the child and letting the style rules above the current one in the document inheritance chain cascade down. However, not all style rules are inherited. Properties such as <TT>!important</TT>, <TT>left</TT>, and <TT>height</TT> are not inherited automatically by child elements, so you must use the <TT>inherit</TT> keyword to pick them up.</pre>
<H4><A NAME="77081"></A> Box layout properties in CSS</H4>    <p>This block specifies a dark blue color for the font, but the
<P>People sometimes  <!--INDEX properties:CSS:box layout -->  <!--INDEX layout, CSS box layout properties -->  <!--INDEX box layout properties (CSS) -->  <!--INDEX CSS (Cascading Style Sheets):properties, box layout --> get confused about the various element spacing properties in CSS, such as <TT>border</TT>, <TT>padding</TT>, and <TT>margin</TT>. Though they work together a lot and often affect or overlap one another, these properties specify different things, as <A HREF="#77024">Table 4-2</A> shows.    values of the other two properties are inherited from the
    parent. In many cases, this has the same effect as not
<P><I>Table 4-2: <A NAME="77024"></A></I>    specifying any value at all for the child and letting the style
<I>CSS spacing and layout properties</I>    rules above the current one in the document inheritance chain
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Property group</B></TD> <TD><B>  Description</B></TD> <TD><B>  Display</B></TD></TR>    cascade down. However, not all style rules are inherited.
<TR><TD> padding</TD>     <TD>  Defines the space between the element's border and the content in the element.</TD></TR>    Properties such as <tt>!important</tt>, <tt>left</tt>, and
<TR><TD> td {padding-left: .25in;}</TD></TR>    <tt>height</tt> are not inherited automatically by child
<TR><TD> td {padding-left: .0125in;}</TD>     <TD></TD></TR></TABLE><P>    elements, so you must use the <tt>inherit</tt> keyword to pick
<P><CENTER><IMG SRC="foo.gif"></CENTER>    them up.</p>
<P><TABLE WIDTH=100% BORDER=1><TR><TD> margin</TD>     <TD>  Defines the space around elements.</TD></TR>    <h4><a name="77081"></a> Box layout properties in CSS</h4>
<TR><TD> td {margin-left: .25in;}</TD>     <TD></TD></TR></TABLE><P>    <p>People sometimes <!--INDEX properties:CSS:box layout --> 
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <!--INDEX layout, CSS box layout properties --> 
<P><TABLE WIDTH=100% BORDER=1><TR><TD> border</TD>     <TD>  Defines the border itself; it can control the thickness, color, style, and other aspects of an element's border.</TD></TR>    <!--INDEX box layout properties (CSS) --> 
<TR><TD> td {border-style: inset;}</TD></TR>    <!--INDEX CSS (Cascading Style Sheets):properties, box layout -->
<TR><TD> td {border-color: blue;}</TD></TR>    get confused about the various element spacing properties in
<TR><TD> td {border-left-width: 15px;}</TD>     <TD></TD></TR></TABLE><P>    CSS, such as <tt>border</tt>, <tt>padding</tt>, and
<P><CENTER><IMG SRC="foo.gif"></CENTER>    <tt>margin</tt>. Though they work together a lot and often
    affect or overlap one another, these properties specify
<H4><A NAME="77082"></A> The position property</H4>    different things, as <a href="#77024">Table 4-2</a> shows.</p>
<P><TT>position</TT> is a  <!--INDEX position property (CSS) -->  <!--INDEX properties:CSS:position -->  <!--INDEX CSS (Cascading Style Sheets):position property --> special CSS property  <!--INDEX alignment, CSS position property --> that specifies whether the given selector uses absolute or relative positioning. Unless you set the <TT>position</TT> property to absolute, you cannot use the related <TT>top</TT> and <TT>left</TT> properties to set the position of the current selector within its parent, as the example in <A HREF="#77026">Table 4-3</A> demonstrates. The <TT>top</TT> and <TT>left</TT> properties, when activated by the absolute position, specify the amount of distance from the top and left of the document, respectively. You can also set <TT>position</TT> to <TT>fixed</TT> to make it stay in one place as other content or UI is scrolled or <!--INDEX ENDRANGE--style definitions -->  <!--INDEX ENDRANGE--CSS (Cascading Style Sheets):style definitions -->  moved.    <p><i>Table 4-2: <a name="77024"></a></i> <i>CSS spacing and
    layout properties</i></p>
<P><I>Table 4-3: <A NAME="77026"></A></I>    <table width="100%" border="1">
<I>The position property</I>      <tr>
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Example</B></TD> <TD><B>  Display</B></TD></TR>        <td><b>Property group</b></td>
<TR><TD> &lt;style&gt;</TD></TR>        <td><b>Description</b></td>
<TR><TD> #abdiv {</TD></TR>        <td><b>Display</b></td>
<TR><TD>  position: absolute;</TD></TR>      </tr>
<TR><TD>  top: 20px;</TD></TR>      <tr>
<TR><TD>  left: 70px;</TD></TR>        <td>padding</td>
<TR><TD>  background-color: lightblue;</TD></TR>        <td>Defines the space between the element's border and the
<TR><TD> }</TD></TR>        content in the element.</td>
<TR><TD> #regdiv {</TD></TR>      </tr>
<TR><TD>  background-color: lightblue;</TD></TR>      <tr>
<TR><TD> }</TD></TR>        <td>td {padding-left: .25in;}</td>
<TR><TD> &lt;/style&gt;</TD></TR>      </tr>
<TR><TD> &lt;div id="regdiv"&gt;other div&lt;/div&gt;</TD></TR>      <tr>
<TR><TD> &lt;div id="abdiv"&gt;abdiv&lt;/div&gt;</TD>     <TD></TD></TR></TABLE><P>        <td>td {padding-left: .0125in;}</td>
<P><CENTER><IMG SRC="foo.gif"></CENTER>        <td>
        </td>
<H3><A NAME="77083"></A> Special Mozilla Extensions</H3>      </tr>
<P>Mozilla skins  <!--INDEX selectors, CSS:extensions -->  <!--INDEX Mozilla:CSS extensions -->  <!--INDEX CSS (Cascading Style Sheets):extensions -->  <!--INDEX properties:CSS:Mozilla extensions -->  <!--INDEX extensions, CSS selectors and properties --> extend  <!--INDEX skins:Mozilla CSS extensions --> upon the CSS standards in just a few notable ways. These Mozilla CSS extensions take the form of special selectors and properties with the special <TT>-moz-</TT> prefix, indicating that they are not part of the actual CSS specifications. You can find a complete list of these CSS keywords by searching for the file <I>nsCSSKeyWordList.h</I> in LXR.    </table>
<P>Generally, these extensions are used to define CSS style and color values that are hardcoded into the C++ code and available for reuse in particular places in the Mozilla themes. You can use a few <I>-moz-</I> extensions, such as properties or special values or even, in some cases, style-related attributes in the XUL (e.g., span[-moz-smiley="s1"], which grabs span elements in the HTML editor whose -<TT>moz-smiley</TT> attribute is set to <TT>s1</TT> and styles them accordingly). Actually, you can use any value in that CSS keyword list. Trial and error or a look in the C++ code will reveal what these values are. The values, like <TT>-moz-fieldtext</TT> and <TT>-moz-mac-menushadow</TT>, usually refer to actual color values. A list of some Mozilla CSS extensions appears in <A HREF="#77028">Table 4-4</A>.    <div class="c12">
      <img src="foo.gif">
<P><I>Table 4-4: <A NAME="77028"></A></I>    </div>
<I>Mozilla CSS extensions</I>    <table width="100%" border="1">
<P><TABLE WIDTH=100% BORDER=1><TR><TD><B>  Property</B></TD>    <TD><B>  Description</B></TD></TR>      <tr>
<TR><TD> -moz-appearance</TD>   <TD>  Specifies that the element should appear, as much as possible, as an operating-system native.</TD></TR>        <td>margin</td>
<TR><TD> -moz-opacity</TD>      <TD>  Controls the opacity of any styleable element with a percentage value. The following example style rule creates a class of buttons that are only half visible above their backgrounds:</TD></TR>        <td>Defines the space around elements.</td>
<TR><TD> .op-butt {</TD></TR>      </tr>
<TR><TD>   -moz-opacity: 50%;</TD></TR>      <tr>
<TR><TD> }</TD></TR>        <td>td {margin-left: .25in;}</td>
<TR><TD> -moz-binding</TD>      <TD>  The property for binding XBL to XUL. The value of </TD><TT>-moz-binding</TT> is a URL pointing to the section in an XML bindings file where the XBL is defined:</TR>        <td>
<TR><TD> new-widget {</TD></TR>        </td>
<TR><TD>   -moz-binding:</TD></TR>      </tr>
<TR><TD>      chrome://xfly/bindings/extras.xml#super-button;</TD></TR>    </table>
<TR><TD> }</TD></TR>    <div class="c12">
<TR><TD> -moz-border-radius,</TD></TR>      <img src="foo.gif">
<TR><TD> -moz-border-radius-bottomleft,</TD></TR>    </div>
<TR><TD> -moz-border-radius-bottomright,</TD></TR>    <table width="100%" border="1">
<TR><TD> -moz-border-radius-topleft,</TD></TR>      <tr>
<TR><TD> -moz-border-radius-topright</TD>       <TD>  Puts rounded corners on regular borders. The degree of rounding depends on the number of pixels you assign. For example, if you set this property to </TD><TT>2px</TT>, you get a slightly rounded border, but if you set it to <TT>8px</TT>, you get a very round border.</TR>        <td>border</td>
<TR><TD> -moz-border-colors,</TD></TR>        <td>Defines the border itself; it can control the
<TR><TD> -moz-border-colors-bottom,</TD></TR>        thickness, color, style, and other aspects of an element's
<TR><TD> -moz-border-colors-left,</TD></TR>        border.</td>
<TR><TD> -moz-border-colors-right,</TD></TR>      </tr>
<TR><TD> -moz-border-colors-top</TD>    <TD>  Sets the border colors on the various sides of an element.</TD></TR>      <tr>
<TR><TD> -moz-user-focus</TD>   <TD>  Indicates whether the given element can have focus. Possible values are </TD><TT>normal</TT> and <TT>ignore</TT>.</TR>        <td>td {border-style: inset;}</td>
<TR><TD> -moz-user-select</TD>  <TD>  Indicates whether the given element can be selected. Possible values are </TD><TT>none</TT> and <TT>normal</TT>.</TR>      </tr>
<TR><TD> -moz-smiley</TD>       <TD>  This is typically given as an attribute to the span element in the HTML in a composer window and can be set to a value such as </TD><TT>s5</TT> to pick up the laughing smiley image, to <TT>s6</TT> to pick up the embarrassed smiley image, and so on.</TR>      <tr>
<TR><TD>  See the following source file for the values that can be set for this special property: </TD><A HREF="http://lxr.mozilla.org/seamonkey/source/editor/ui/composer/content/EditorContent.css">http://lxr.mozilla.org/seamonkey/source/editor/ui/composer/content/EditorContent.css</A>#77.</TR>        <td>td {border-color: blue;}</td>
<TR><TD> -moz-image-region</TD> <TD>  This was added to optimize the way image resources are used in the Mozilla skins. The value of the </TD><TT>-moz-image</TT> region is a set of coordinates that designate an area within an "image sheet" that should be used as an icon in the user interface. The following CSS style definition specifies the top- and leftmost button in the <I>btn1.gif</I> image sheet used in <A HREF="#77006">Figure 4-3</A> to use as the default icon for the Back navigation button:</TR>      </tr>
<TR><TD> .toolbarbutton-1 {</TD></TR>      <tr>
<TR><TD>  list-style-image: url("chrome://navigator/skin/icons/btn1.gif");</TD></TR>        <td>td {border-left-width: 15px;}</td>
<TR><TD>  min-width: 0px;</TD></TR>        <td>
<TR><TD> }</TD></TR>        </td>
<TR><TD> #back-button {</TD></TR>      </tr>
<TR><TD>  -moz-image-region: rect(0 41px 38px 0);</TD></TR>    </table>
<TR><TD> }</TD></TR>    <div class="c12">
<TR><TD>  Of the two default skins, these image sheets are found only in the Modern skin. They are gradually making their way into the skins; as of this writing, there are three or four image sheets in the Modern skin-each corresponding to an area, toolbar, or set of buttons in the browser.</TD></TR>      <img src="foo.gif">
<TR><TD> -moz-box-align</TD>     <TD>  Sets the alignment for a XUL element from CSS. Possible values are </TD><TT>start</TT>, <TT>center</TT>, <TT>end</TT>, <TT>baseline</TT>, and <TT>stretch</TT>.</TR>    </div>
<TR><TD> -moz-box-direction</TD>     <TD>  Sets the direction of a box's child elements. Possible values are </TD><TT>normal</TT> and <TT>reverse</TT>.</TR>    <h4><a name="77082"></a> The position property</h4>
<TR><TD> -moz-box-flex</TD>     <TD>  Sets the flexibility of an element relative to its siblings. The value is an integer.</TD></TR>    <p><tt>position</tt> is a <!--INDEX position property (CSS) -->
<TR><TD> -moz-box-flexgroup</TD>     <TD>  Specifies that a group of elements have the same flex. The value is an integer.</TD></TR>    <!--INDEX properties:CSS:position --> 
<TR><TD> -moz-box-ordinal</TD>     <TD>  Specifies the order of an element relative to its peers in a container. By default, the value of this property is set to 1. When you set a new value, you can change the order, as in this example, which promotes the "View Source" menu item to the top of the menu by demoting the other two:</TD></TR>    <!--INDEX CSS (Cascading Style Sheets):position property -->
<TR><TD> &lt;style&gt;</TD></TR>    special CSS property 
<TR><TD> #q { -moz-box-ordinal: 0; }</TD></TR>    <!--INDEX alignment, CSS position property --> that specifies
<TR><TD> &lt;/style&gt;</TD></TR>    whether the given selector uses absolute or relative
<TR><TD> &lt;menu&gt;</TD></TR>    positioning. Unless you set the <tt>position</tt> property to
<TR><TD>   &lt;menuitem id="e" label="e" /&gt;</TD></TR>    absolute, you cannot use the related <tt>top</tt> and
<TR><TD>   &lt;menuitem id="v" label="v" /&gt;</TD></TR>    <tt>left</tt> properties to set the position of the current
<TR><TD>   &lt;menuitem id="q" label="q" /&gt;</TD></TR>    selector within its parent, as the example in <a href=
<TR><TD> &lt;/menu&gt;</TD></TR>    "#77026">Table 4-3</a> demonstrates. The <tt>top</tt> and
<TR><TD> &lt;/window&gt;</TD></TR>    <tt>left</tt> properties, when activated by the absolute
<TR><TD>  You can also give elements the same ordinal value in CSS and group them, making sure they are not split by new, overlaid items.</TD></TR>    position, specify the amount of distance from the top and left
<TR><TD> -moz-box-orient</TD>     <TD>  Sets the orientation of a container element. The value can be either </TD><TT>horizontal</TT> or <TT>vertical</TT>.</TR>    of the document, respectively. You can also set
<TR><TD> -moz-box-pack</TD>     <TD>  Packs the child elements of a container at the </TD><TT>start</TT>, <TT>center</TT>, or <TT>end</TT>.</TR></TABLE><P>    <tt>position</tt> to <tt>fixed</tt> to make it stay in one
    place as other content or UI is scrolled or 
<H3><A NAME="77084"></A> Referencing Images in CSS</H3>    <!--INDEX ENDRANGE==style definitions --> 
<P>Another basic  <!--INDEX skins:images, referencing -->  <!--INDEX images:skins, referencing -->  <!--INDEX CSS (Cascading Style Sheets):images, referencing -->  <!--INDEX referencing:images, CSS --> function of the CSS in any Mozilla skin is to incorporate images into the user interface. A Mozilla skin can contain literally thousands of images, which are all referenced from particular style statements in the CSS. It's common for a single element to point to different versions of an image to reflect different states-as when a second image is used to give a button a pushed-down look as it is clicked-to create dynamism and provide feedback to the user. <A HREF="#77036">Example 4-4</A> shows the following two style statements handle the regular and active-or depressed-states, respectively.    <!--INDEX ENDRANGE==CSS (Cascading Style Sheets):style definitions -->
    moved.</p>
<P><I>Example 4-4: <A NAME="77036"></A></I>    <p><i>Table 4-3: <a name="77026"></a></i> <i>The position
<I>Image in CSS</I>    property</i></p>
<PRE> button.regular {    <table width="100%" border="1">
       <tr>
         <td><b>Example</b></td>
         <td><b>Display</b></td>
       </tr>
       <tr>
         <td>&lt;style&gt;</td>
       </tr>
       <tr>
         <td>#abdiv {</td>
       </tr>
       <tr>
         <td>position: absolute;</td>
       </tr>
       <tr>
         <td>top: 20px;</td>
       </tr>
       <tr>
         <td>left: 70px;</td>
       </tr>
       <tr>
         <td>background-color: lightblue;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>#regdiv {</td>
       </tr>
       <tr>
         <td>background-color: lightblue;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>&lt;/style&gt;</td>
       </tr>
       <tr>
         <td>&lt;div id="regdiv"&gt;other div&lt;/div&gt;</td>
       </tr>
       <tr>
         <td>&lt;div id="abdiv"&gt;abdiv&lt;/div&gt;</td>
         <td>
         </td>
       </tr>
     </table>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <h3><a name="77083"></a> Special Mozilla Extensions</h3>
     <p>Mozilla skins <!--INDEX selectors, CSS:extensions --> 
     <!--INDEX Mozilla:CSS extensions --> 
     <!--INDEX CSS (Cascading Style Sheets):extensions --> 
     <!--INDEX properties:CSS:Mozilla extensions --> 
     <!--INDEX extensions, CSS selectors and properties --> extend 
     <!--INDEX skins:Mozilla CSS extensions --> upon the CSS
     standards in just a few notable ways. These Mozilla CSS
     extensions take the form of special selectors and properties
     with the special <tt>-moz-</tt> prefix, indicating that they
     are not part of the actual CSS specifications. You can find a
     complete list of these CSS keywords by searching for the file
     <i>nsCSSKeyWordList.h</i> in LXR.</p>
     <p>Generally, these extensions are used to define CSS style and
     color values that are hardcoded into the C++ code and available
     for reuse in particular places in the Mozilla themes. You can
     use a few <i>-moz-</i> extensions, such as properties or
     special values or even, in some cases, style-related attributes
     in the XUL (e.g., span[-moz-smiley="s1"], which grabs span
     elements in the HTML editor whose -<tt>moz-smiley</tt>
     attribute is set to <tt>s1</tt> and styles them accordingly).
     Actually, you can use any value in that CSS keyword list. Trial
     and error or a look in the C++ code will reveal what these
     values are. The values, like <tt>-moz-fieldtext</tt> and
     <tt>-moz-mac-menushadow</tt>, usually refer to actual color
     values. A list of some Mozilla CSS extensions appears in <a
     href="#77028">Table 4-4</a>.</p>
     <p><i>Table 4-4: <a name="77028"></a></i> <i>Mozilla CSS
     extensions</i></p>
     <tt>-moz-binding</tt>is a URL pointing to the section in an XML
     bindings file where the XBL is defined:<tt>2px</tt>, you get a
     slightly rounded border, but if you set it to <tt>8px</tt>, you
     get a very round border.<tt>normal</tt>and
     <tt>ignore</tt>.<tt>none</tt>and <tt>normal</tt>.<tt>s5</tt>to
     pick up the laughing smiley image, to <tt>s6</tt>to pick up the
     embarrassed smiley image, and so on.<a href=
     "http://lxr.mozilla.org/seamonkey/source/editor/ui/composer/content/EditorContent.css">
     http://lxr.mozilla.org/seamonkey/source/editor/ui/composer/content/EditorContent.css</a>#77.<tt>
     -moz-image</tt>region is a set of coordinates that designate an
     area within an "image sheet" that should be used as an icon in
     the user interface. The following CSS style definition
     specifies the top- and leftmost button in the
     <i>btn1.gif</i>image sheet used in <a href="#77006">Figure
     4-3</a>to use as the default icon for the Back navigation
     button:<tt>start</tt>, <tt>center</tt>, <tt>end</tt>,
     <tt>baseline</tt>, and <tt>stretch</tt>.<tt>normal</tt>and
     <tt>reverse</tt>.<tt>horizontal</tt>or
     <tt>vertical</tt>.<tt>start</tt>, <tt>center</tt>, or
     <tt>end</tt>.
     <table width="100%" border="1">
       <tr>
         <td><b>Property</b></td>
         <td><b>Description</b></td>
       </tr>
       <tr>
         <td>-moz-appearance</td>
         <td>Specifies that the element should appear, as much as
         possible, as an operating-system native.</td>
       </tr>
       <tr>
         <td>-moz-opacity</td>
         <td>Controls the opacity of any styleable element with a
         percentage value. The following example style rule creates
         a class of buttons that are only half visible above their
         backgrounds:</td>
       </tr>
       <tr>
         <td>.op-butt {</td>
       </tr>
       <tr>
         <td>-moz-opacity: 50%;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>-moz-binding</td>
         <td>The property for binding XBL to XUL. The value of</td>
       </tr>
       <tr>
         <td>new-widget {</td>
       </tr>
       <tr>
         <td>-moz-binding:</td>
       </tr>
       <tr>
         <td>chrome://xfly/bindings/extras.xml#super-button;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>-moz-border-radius,</td>
       </tr>
       <tr>
         <td>-moz-border-radius-bottomleft,</td>
       </tr>
       <tr>
         <td>-moz-border-radius-bottomright,</td>
       </tr>
       <tr>
         <td>-moz-border-radius-topleft,</td>
       </tr>
       <tr>
         <td>-moz-border-radius-topright</td>
         <td>Puts rounded corners on regular borders. The degree of
         rounding depends on the number of pixels you assign. For
         example, if you set this property to</td>
       </tr>
       <tr>
         <td>-moz-border-colors,</td>
       </tr>
       <tr>
         <td>-moz-border-colors-bottom,</td>
       </tr>
       <tr>
         <td>-moz-border-colors-left,</td>
       </tr>
       <tr>
         <td>-moz-border-colors-right,</td>
       </tr>
       <tr>
         <td>-moz-border-colors-top</td>
         <td>Sets the border colors on the various sides of an
         element.</td>
       </tr>
       <tr>
         <td>-moz-user-focus</td>
         <td>Indicates whether the given element can have focus.
         Possible values are</td>
       </tr>
       <tr>
         <td>-moz-user-select</td>
         <td>Indicates whether the given element can be selected.
         Possible values are</td>
       </tr>
       <tr>
         <td>-moz-smiley</td>
         <td>This is typically given as an attribute to the span
         element in the HTML in a composer window and can be set to
         a value such as</td>
       </tr>
       <tr>
         <td>See the following source file for the values that can
         be set for this special property:</td>
       </tr>
       <tr>
         <td>-moz-image-region</td>
         <td>This was added to optimize the way image resources are
         used in the Mozilla skins. The value of the</td>
       </tr>
       <tr>
         <td>.toolbarbutton-1 {</td>
       </tr>
       <tr>
         <td>list-style-image:
         url("chrome://navigator/skin/icons/btn1.gif");</td>
       </tr>
       <tr>
         <td>min-width: 0px;</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>#back-button {</td>
       </tr>
       <tr>
         <td>-moz-image-region: rect(0 41px 38px 0);</td>
       </tr>
       <tr>
         <td>}</td>
       </tr>
       <tr>
         <td>Of the two default skins, these image sheets are found
         only in the Modern skin. They are gradually making their
         way into the skins; as of this writing, there are three or
         four image sheets in the Modern skin-each corresponding to
         an area, toolbar, or set of buttons in the browser.</td>
       </tr>
       <tr>
         <td>-moz-box-align</td>
         <td>Sets the alignment for a XUL element from CSS. Possible
         values are</td>
       </tr>
       <tr>
         <td>-moz-box-direction</td>
         <td>Sets the direction of a box's child elements. Possible
         values are</td>
       </tr>
       <tr>
         <td>-moz-box-flex</td>
         <td>Sets the flexibility of an element relative to its
         siblings. The value is an integer.</td>
       </tr>
       <tr>
         <td>-moz-box-flexgroup</td>
         <td>Specifies that a group of elements have the same flex.
         The value is an integer.</td>
       </tr>
       <tr>
         <td>-moz-box-ordinal</td>
         <td>Specifies the order of an element relative to its peers
         in a container. By default, the value of this property is
         set to 1. When you set a new value, you can change the
         order, as in this example, which promotes the "View Source"
         menu item to the top of the menu by demoting the other
         two:</td>
       </tr>
       <tr>
         <td>&lt;style&gt;</td>
       </tr>
       <tr>
         <td>#q { -moz-box-ordinal: 0; }</td>
       </tr>
       <tr>
         <td>&lt;/style&gt;</td>
       </tr>
       <tr>
         <td>&lt;menu&gt;</td>
       </tr>
       <tr>
         <td>&lt;menuitem id="e" label="e" /&gt;</td>
       </tr>
       <tr>
         <td>&lt;menuitem id="v" label="v" /&gt;</td>
       </tr>
       <tr>
         <td>&lt;menuitem id="q" label="q" /&gt;</td>
       </tr>
       <tr>
         <td>&lt;/menu&gt;</td>
       </tr>
       <tr>
         <td>&lt;/window&gt;</td>
       </tr>
       <tr>
         <td>You can also give elements the same ordinal value in
         CSS and group them, making sure they are not split by new,
         overlaid items.</td>
       </tr>
       <tr>
         <td>-moz-box-orient</td>
         <td>Sets the orientation of a container element. The value
         can be either</td>
       </tr>
       <tr>
         <td>-moz-box-pack</td>
         <td>Packs the child elements of a container at the</td>
       </tr>
     </table>
     <h3><a name="77084"></a> Referencing Images in CSS</h3>
     <p>Another basic <!--INDEX skins:images, referencing --> 
     <!--INDEX images:skins, referencing --> 
     <!--INDEX CSS (Cascading Style Sheets):images, referencing --> 
     <!--INDEX referencing:images, CSS --> function of the CSS in
     any Mozilla skin is to incorporate images into the user
     interface. A Mozilla skin can contain literally thousands of
     images, which are all referenced from particular style
     statements in the CSS. It's common for a single element to
     point to different versions of an image to reflect different
     states-as when a second image is used to give a button a
     pushed-down look as it is clicked-to create dynamism and
     provide feedback to the user. <a href="#77036">Example 4-4</a>
     shows the following two style statements handle the regular and
     active-or depressed-states, respectively.</p>
     <p><i>Example 4-4: <a name="77036"></a></i> <i>Image in
     CSS</i></p>
 <pre>
  button.regular {
      list-style-image: url(chrome://global/skin/arrow.gif);       list-style-image: url(chrome://global/skin/arrow.gif);
      background-image: url(chrome://global/skin/regbutton.gif);       background-image: url(chrome://global/skin/regbutton.gif);
  }   }
  button.regular:active   button.regular:active
  {   {
      background-image: url(chrome://global/skin/button_pushed.gif);       background-image: url(chrome://global/skin/button_pushed.gif);
 }</PRE> }
</pre>
<P>In <A HREF="#77036">Example 4-4</A>, the second of the two definitions inherits from the first, so it implicitly includes the <I>arrow.gif</I> as a foreground image. The second style definition says that when the XUL button of class <TT>regular</TT> is active, the image <I>button_pushed.gif</I> is used in place of <I>regbutton.gif</I> for the background.    <p>In <a href="#77036">Example 4-4</a>, the second of the two
<P><A HREF="#77036">Example 4-4</A> also illustrates <!--INDEX properties:CSS:referencing images -->  the two common stylesheet properties that reference images: <TT>list-style-image</TT> and <TT>background-image</TT>. The <TT> <!--INDEX list-style-image property (CSS) --> list-style-image</TT> property specifies an image to go in the foreground of the selector; the <TT>background-image</TT> property specifies a separate image for the background. The availability of these two properties allows you to fine-tuning the images used to style the UI, as in this example, where the arrow icon is preserved and the wider, underlying button is swapped out.    definitions inherits from the first, so it implicitly includes
<P>In fact, the navigation buttons in the Modern skin are created by using both properties. In this case, the background is the basic round disk as seen in <A HREF="#77008">Figure 4-4</A>, defined in the <TT>toolbarbutton-1</TT> class in <I>communicator\skin\button.css</I>, and the <TT>list-style-image</TT> is the arrow portion of the button, defined in the button ID and sliced out of a button image sheet with the special <TT>-moz-image-region</TT> property (see <A HREF="#77083">"Special Mozilla Extensions</A>" later in this chapter for a description of image sheets).    the <i>arrow.gif</i> as a foreground image. The second style
<P><CENTER><IMG SRC="foo.gif"></CENTER>    definition says that when the XUL button of class
<P><I>Figure 4-4: <A NAME="77008"></A></I>    <tt>regular</tt> is active, the image <i>button_pushed.gif</i>
<I>Composite styles for the reload button</I>    is used in place of <i>regbutton.gif</i> for the
    background.</p>
<H3><A NAME="77085"></A> Menu Skinning</H3>    <p><a href="#77036">Example 4-4</a> also illustrates 
<P>As an example  <!--INDEX menus:CSS, skinning -->  <!--INDEX skins:menus -->  <!--INDEX CSS (Cascading Style Sheets):menus, skins --> of using CSS in applications, <A HREF="#77038">Example 4-5</A> combines many common selectors described in this chapter in a set of rules for defining the look and basic behavior of menus. The CSS handles the basic look of the menus, their color and style, the look of the menu items when they are hovered over, and the look when they are selected.    <!--INDEX properties:CSS:referencing images --> the two common
    stylesheet properties that reference images:
<P><I>Example 4-5: <A NAME="77038"></A></I>    <tt>list-style-image</tt> and <tt>background-image</tt>. The
<I>Mixing CSS and XUL</I>    <tt><!--INDEX list-style-image property (CSS) -->
<PRE> &lt;menu id="sample"&gt;    list-style-image</tt> property specifies an image to go in the
     foreground of the selector; the <tt>background-image</tt>
     property specifies a separate image for the background. The
     availability of these two properties allows you to fine-tuning
     the images used to style the UI, as in this example, where the
     arrow icon is preserved and the wider, underlying button is
     swapped out.</p>
     <p>In fact, the navigation buttons in the Modern skin are
     created by using both properties. In this case, the background
     is the basic round disk as seen in <a href="#77008">Figure
     4-4</a>, defined in the <tt>toolbarbutton-1</tt> class in
     <i>communicator\skin\button.css</i>, and the
     <tt>list-style-image</tt> is the arrow portion of the button,
     defined in the button ID and sliced out of a button image sheet
     with the special <tt>-moz-image-region</tt> property (see <a
     href="#77083">"Special Mozilla Extensions</a>" later in this
     chapter for a description of image sheets).</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-4: <a name="77008"></a></i> <i>Composite styles
     for the reload button</i></p>
     <h3><a name="77085"></a> Menu Skinning</h3>
     <p>As an example <!--INDEX menus:CSS, skinning --> 
     <!--INDEX skins:menus --> 
     <!--INDEX CSS (Cascading Style Sheets):menus, skins --> of
     using CSS in applications, <a href="#77038">Example 4-5</a>
     combines many common selectors described in this chapter in a
     set of rules for defining the look and basic behavior of menus.
     The CSS handles the basic look of the menus, their color and
     style, the look of the menu items when they are hovered over,
     and the look when they are selected.</p>
     <p><i>Example 4-5: <a name="77038"></a></i> <i>Mixing CSS and
     XUL</i></p>
 <pre>
  &lt;menu id="sample"&gt;
    &lt;menupopup&gt;     &lt;menupopup&gt;
      &lt;menuitem class="m" label="File" /&gt;       &lt;menuitem class="m" label="File" /&gt;
      &lt;menuitem class="m" label="Edit" /&gt;       &lt;menuitem class="m" label="Edit" /&gt;
Line 343  background-color: inherit; Line 1240  background-color: inherit;
  .m { background-color: lightgray; font-size: 9pt; }   .m { background-color: lightgray; font-size: 9pt; }
  .m:hover  { border: 1px; }   .m:hover  { border: 1px; }
  .m:active { background-color: gray; color: white; }   .m:active { background-color: gray; color: white; }
 #q:active { background-color: black }</PRE> #q:active { background-color: black }
</pre>
<P>When you hover over any of the items in the menu generated by the code in <A HREF="#77038">Example 4-5</A>, they display a border. When you select the item, it appears momentarily with a dark gray background and white lettering, like reverse video. The Quit menu item, unlike others, appears with a black background. Note that it also picks up the same white lettering as the other items of the <TT>m</TT> class, since this style information is inherited.    <p>When you hover over any of the items in the menu generated
<H2><A NAME="77086"></A> Mozilla Skins</H2>    by the code in <a href="#77038">Example 4-5</a>, they display a
<P>At an earlier  <!--INDEX chrome:skins, file locations -->  <!--INDEX skins:file locations -->  <!--INDEX files:skins, locations --> point in Mozilla's history, all interface files-the XUL, the CSS, and the images-were stored in directories named after the main Mozilla packages in the application chrome directory. The best way to look at a skin was just to poke around in those directories, change things in the CSS files you found, and reload to see what had changed in the browser. The CSS files are no longer stored in regular directories.    border. When you select the item, it appears momentarily with a
<P>To organize things better and make a smaller footprint for Mozilla, all chrome is stored in special compressed archives in the <I>chrome</I> directory. These archives are Java Archive (JAR) files, whose subdirectory structure reflects the structure of Mozilla's major components, to some extent. There is one JAR archive for every theme. By default, Mozilla is distributed with the Classic and Modern themes, represented in the chrome as <TT>classic.jar</TT> and <TT>modern.jar</TT>. <A HREF="#77010">Figure 4-5</A> shows some of the contents of the <TT>modern.jar</TT> file in a zip utility.    dark gray background and white lettering, like reverse video.
<P><CENTER><IMG SRC="foo.gif"></CENTER>    The Quit menu item, unlike others, appears with a black
<P><I>Figure 4-5: <A NAME="77010"></A></I>    background. Note that it also picks up the same white lettering
<I>The contents of the modern.jar file</I>    as the other items of the <tt>m</tt> class, since this style
    information is inherited.</p>
<H3><A NAME="77087"></A> CSS and Skin Hierarchies</H3>    <h2><a name="77086"></a> Mozilla Skins</h2>
<P>You have  <!--INDEX CSS (Cascading Style Sheets):skins:hierarchy -->  <!--INDEX skins:hierarchy -->  <!--INDEX hierarchy:skins -->  <!--INDEX inheritance:skin hierarchies --> already seen some of the structure inherent to CSS in the previous examples. When an element has both a class-based and an id-based rule, for example (as well as a basic element "look and feel" defined in the global skin), the element style is applied. Then, the more specific class-based rule is applied and overwrites the properties of the general rule if they conflict. Finally, the ID-based rule is applied and overwrites whatever conflicting style values are in the more general selectors. In this way, the most specific style rules inherit from the most basic. This is the "cascade" in Cascading Style Sheets. In addition to this definition, the syntax of CSS allows you to specify selector relationships-such as when you create a parent-child selector and apply a style rule to only the selectors that have some other particular element as a parent in the XUL content model. However, there is also a strong inheritance mechanism in the way that the Mozilla browser uses CSS-in the way skin files are organized in the chrome and applied to the XUL. The strong hierarchical structure present in Mozilla's CSS and the XUL allow the chrome registry to maintain the skin and the various components that get skinned as different modules, but find and apply the right resources whenever they are called for. This structure is described in the <A HREF="#77089">"Basic Skin Structure</A>" section later in this chapter.    <p>At an earlier <!--INDEX chrome:skins, file locations --> 
<H4><A NAME="77088"></A> Skin inheritance and skin modularization</H4>    <!--INDEX skins:file locations --> 
<P>For the sake of  <!--INDEX skins:inheritance -->  <!--INDEX skins:modularization -->  <!--INDEX modularization, skins --> discussion, this book describes two kinds of inheritance: the more basic form, in which a specific skin like <I>navigator.css</I> inherits all style rules from <I>global.css</I>, and modularization, in which navigator skin rules specific to the toolbar are distributed into widget-specific CSS files (e.g., <I>toolbar.css</I> is part of the global skin). The global skin-once a large, unmodular set of style rules contained in <I>global.css-</I>is now spread out over several modularized CSS files, as <A HREF="#77012">Figure 4-6</A> shows.    <!--INDEX files:skins, locations --> point in Mozilla's
<P><CENTER><IMG SRC="foo.gif"></CENTER>    history, all interface files-the XUL, the CSS, and the
<P><I>Figure 4-6: <A NAME="77012"></A></I>    images-were stored in directories named after the main Mozilla
<I>XUL file and skin loading</I>    packages in the application chrome directory. The best way to
    look at a skin was just to poke around in those directories,
<P>This modularization makes it possible for a  <!--INDEX XUL (XML-based User-interface Language):skin modularization --> XUL file to load the <I>global.css</I> file in a single statement and use any of the style rules defined in these skins. We will discuss the global skin in more detail in the section <A HREF="#77093">"Global skin</A>" later in this chapter. Skin inheritance and skin modularization work together to give skins their structure and make it possible to create new skins or apply CSS only to particular parts of the application.    change things in the CSS files you found, and reload to see
<P><A HREF="#77012">Figure 4-6</A> shows a very specific skin, <I>new.css</I>, inheriting the style information from <I>communicator.css</I> and then being loaded into the XUL file. In a situation like this, <I>ex.xul</I> can use any style rule defined in the <I>communicator.css</I> file (or in any CSS file that it imports).    what had changed in the browser. The CSS files are no longer
<H3><A NAME="77089"></A> Basic Skin Structure</H3>    stored in regular directories.</p>
<P>Though they look <!--INDEX themes:structure -->  <!--INDEX skins:structure -->  very different, the Modern and Classic themes that are installed with Mozilla have similar structures. This is because the structure of a theme reflects, in many ways, the structure of the components to which it applies. So, for example, both themes have subdirectories (in the JAR files in which they are stored) where the CSS and image resources for each of the main components are stored. Modern, for example, has a <I>communicator</I> component subdirectory, and that subdirectory has subdirectories representing the various parts of the communicator interface: bookmarks, help, search, sidebar, and so on. <A HREF="#77042">Example 4-7</A> shows the Modern and Classically themed Navigation bars side by side.    <p>To organize things better and make a smaller footprint for
<P><CENTER><IMG SRC="foo.gif"></CENTER>    Mozilla, all chrome is stored in special compressed archives in
<P><I>Figure 4-7: <A NAME="77014"></A></I>    the <i>chrome</i> directory. These archives are Java Archive
<I>Classic and Modern Navigation toolbars</I>    (JAR) files, whose subdirectory structure reflects the
    structure of Mozilla's major components, to some extent. There
<P>Both themes are complete. They each contain all skin resources for the major components of the application.<A NAME="b290"></A><A HREF="#290">[*]</A> The resources themselves vary, but their structures are almost identical. This ability is what makes the skins dynamically changeable.    is one JAR archive for every theme. By default, Mozilla is
<P>Skin developers can, for example, create a skin for a single component in Mozilla (e.g., messenger) and let the Modern theme continue to take     distributed with the Classic and Modern themes, represented in
care of the other components for which they have not created any new CSS information. Which components are skinned by which themes is specified in the <I>installed-chrome.txt</I> file, where a single entry represents the application of the appropriate theme resources to a single component, such as navigator. (See <A HREF="ch06.html#15291">Chapter 6</A> for more information about this file and about how themes and other packages are registered and applied in Mozilla.) This situation does not apply to new applications like xFly, however, for which the XUL is typically a single package and the CSS that applies to it is another single package. Unlike the Mozilla browser, your application will probably have a single manifest and <I>content</I> subdirectory and a single manifest and <I>skin</I> subdirectory:    the chrome as <tt>classic.jar</tt> and <tt>modern.jar</tt>. <a
<PRE>xfly.jar:    href="#77010">Figure 4-5</a> shows some of the contents of the
     <tt>modern.jar</tt> file in a zip utility.</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-5: <a name="77010"></a></i> <i>The contents of
     the modern.jar file</i></p>
     <h3><a name="77087"></a> CSS and Skin Hierarchies</h3>
     <p>You have 
     <!--INDEX CSS (Cascading Style Sheets):skins:hierarchy --> 
     <!--INDEX skins:hierarchy --> <!--INDEX hierarchy:skins --> 
     <!--INDEX inheritance:skin hierarchies --> already seen some of
     the structure inherent to CSS in the previous examples. When an
     element has both a class-based and an id-based rule, for
     example (as well as a basic element "look and feel" defined in
     the global skin), the element style is applied. Then, the more
     specific class-based rule is applied and overwrites the
     properties of the general rule if they conflict. Finally, the
     ID-based rule is applied and overwrites whatever conflicting
     style values are in the more general selectors. In this way,
     the most specific style rules inherit from the most basic. This
     is the "cascade" in Cascading Style Sheets. In addition to this
     definition, the syntax of CSS allows you to specify selector
     relationships-such as when you create a parent-child selector
     and apply a style rule to only the selectors that have some
     other particular element as a parent in the XUL content model.
     However, there is also a strong inheritance mechanism in the
     way that the Mozilla browser uses CSS-in the way skin files are
     organized in the chrome and applied to the XUL. The strong
     hierarchical structure present in Mozilla's CSS and the XUL
     allow the chrome registry to maintain the skin and the various
     components that get skinned as different modules, but find and
     apply the right resources whenever they are called for. This
     structure is described in the <a href="#77089">"Basic Skin
     Structure</a>" section later in this chapter.</p>
     <h4><a name="77088"></a> Skin inheritance and skin
     modularization</h4>
     <p>For the sake of <!--INDEX skins:inheritance --> 
     <!--INDEX skins:modularization --> 
     <!--INDEX modularization, skins --> discussion, this book
     describes two kinds of inheritance: the more basic form, in
     which a specific skin like <i>navigator.css</i> inherits all
     style rules from <i>global.css</i>, and modularization, in
     which navigator skin rules specific to the toolbar are
     distributed into widget-specific CSS files (e.g.,
     <i>toolbar.css</i> is part of the global skin). The global
     skin-once a large, unmodular set of style rules contained in
     <i>global.css-</i>is now spread out over several modularized
     CSS files, as <a href="#77012">Figure 4-6</a> shows.</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-6: <a name="77012"></a></i> <i>XUL file and skin
     loading</i></p>
     <p>This modularization makes it possible for a 
     <!--INDEX XUL (XML-based User-interface Language):skin modularization -->
     XUL file to load the <i>global.css</i> file in a single
     statement and use any of the style rules defined in these
     skins. We will discuss the global skin in more detail in the
     section <a href="#77093">"Global skin</a>" later in this
     chapter. Skin inheritance and skin modularization work together
     to give skins their structure and make it possible to create
     new skins or apply CSS only to particular parts of the
     application.</p>
     <p><a href="#77012">Figure 4-6</a> shows a very specific skin,
     <i>new.css</i>, inheriting the style information from
     <i>communicator.css</i> and then being loaded into the XUL
     file. In a situation like this, <i>ex.xul</i> can use any style
     rule defined in the <i>communicator.css</i> file (or in any CSS
     file that it imports).</p>
     <h3><a name="77089"></a> Basic Skin Structure</h3>
     <p>Though they look <!--INDEX themes:structure --> 
     <!--INDEX skins:structure --> very different, the Modern and
     Classic themes that are installed with Mozilla have similar
     structures. This is because the structure of a theme reflects,
     in many ways, the structure of the components to which it
     applies. So, for example, both themes have subdirectories (in
     the JAR files in which they are stored) where the CSS and image
     resources for each of the main components are stored. Modern,
     for example, has a <i>communicator</i> component subdirectory,
     and that subdirectory has subdirectories representing the
     various parts of the communicator interface: bookmarks, help,
     search, sidebar, and so on. <a href="#77042">Example 4-7</a>
     shows the Modern and Classically themed Navigation bars side by
     side.</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-7: <a name="77014"></a></i> <i>Classic and
     Modern Navigation toolbars</i></p>
     <p>Both themes are complete. They each contain all skin
     resources for the major components of the application.<a name=
     "b290"></a><a href="#290">[*]</a> The resources themselves
     vary, but their structures are almost identical. This ability
     is what makes the skins dynamically changeable.</p>
     <p>Skin developers can, for example, create a skin for a single
     component in Mozilla (e.g., messenger) and let the Modern theme
     continue to take care of the other components for which they
     have not created any new CSS information. Which components are
     skinned by which themes is specified in the
     <i>installed-chrome.txt</i> file, where a single entry
     represents the application of the appropriate theme resources
     to a single component, such as navigator. (See <a href=
     "ch06.html#15291">Chapter 6</a> for more information about this
     file and about how themes and other packages are registered and
     applied in Mozilla.) This situation does not apply to new
     applications like xFly, however, for which the XUL is typically
     a single package and the CSS that applies to it is another
     single package. Unlike the Mozilla browser, your application
     will probably have a single manifest and <i>content</i>
     subdirectory and a single manifest and <i>skin</i>
     subdirectory:</p>
 <pre>
 xfly.jar:
 content/  content/
 contents.rdf  contents.rdf
 &lt;xul content here&gt;  &lt;xul content here&gt;
 skin/  skin/
 contents.rdf  contents.rdf
&lt;css content here&gt;</PRE>&lt;css content here&gt;
<P>An important difference here is that your skin requires a single manifest whereas the Mozilla themes use as many manifests as they have major components to skin. When the application that needs to be skinned is as large as the Mozilla browser, modularity is almost imperative-particularly if that application supports add-on applications (like xFly itself, which will be accessible from the Mozilla Tasks menu when you are done).</pre>
<H3><A NAME="77090"></A> The Modern and Classic Themes</H3>    <p>An important difference here is that your skin requires a
<P>If you haven't <!--INDEX skins:Modern compared to Classic -->  <!--INDEX Modern theme:compared to Classic -->  <!--INDEX Classic theme compared to Modern -->  <!--INDEX themes:Modern:compared to Classic -->  already looked at it, using the skin-switching UI (View Menu &gt; Apply Theme &gt; Modern) in Mozilla will give you an idea about the differences between the two skins that come preinstalled with the browser. The Classic skin is modeled after earlier versions of the Mozilla UI and of the Netscape 4.x Communicator product. It has the familiar light grey box look, with the larger, primary-colored navigation button and a squared-off geometry. The Modern theme is a newer take on the browser interface. It has a smoother overall look, with rounded edges on many of the widgets, subtle color differentiations, gradients, and 3D icons.    single manifest whereas the Mozilla themes use as many
<P>However, both skins sit on top of the same XUL. With one notable exception-a powerful feature of CSS in Mozilla discussed later in this chapter in the <A HREF="#77101">"Binding New Widgets to the Interface Using XBL</A>" section-the applications themselves are identical, and themes themselves provide all the differences in the browser's look and behavior.    manifests as they have major components to skin. When the
<H3><A NAME="77091"></A> Skin Files</H3>    application that needs to be skinned is as large as the Mozilla
<P>Obviously, we cannot describe even a fraction of the CSS files that go into making up a single, overall theme. There are, however, some CSS files that help determine how the Mozilla browser looks. In this section, we will go over some of those files so you can see how they relate to one another, where the browser gets its look, and what strategies you might use to create your own complete skin.    browser, modularity is almost imperative-particularly if that
<P>The following sections provide a brief, representative sampling of the Modern theme. The global skin, the navigator skin, and the communicator skin are discussed as they pertain to the Modern theme in the Mozilla browser.    application supports add-on applications (like xFly itself,
<H4><A NAME="77092"></A> Navigator skin</H4>    which will be accessible from the Mozilla Tasks menu when you
<P>One of the <!--INDEX Modern theme:navigator skin -->  <!--INDEX skins:navigator -->  <!--INDEX navigator skin -->  <!--INDEX themes:Modern:navigator skin -->  most specific and complex skin files in the Modern theme hierarchy is the <I>navigator.css</I> file, which contains style information for the browser itself. When you look through this skin, you will see rules for such things as the Print button. In <A HREF="#77040">Example 4-6</A>, note how several selectors are grouped with a single style rule, and how the parent-child relationship between elements (see the earlier section <A HREF="#77078">"Element relation selectors</A>" for an explanation of this selector) is used to style print buttons appearing in different places (i.e., under different element parents) in the UI.    are done).</p>
    <h3><a name="77090"></a> The Modern and Classic Themes</h3>
<P><I>Example 4-6: <A NAME="77040"></A></I>    <p>If you haven't 
<I>CSS for print button in navigator skin</I>    <!--INDEX skins:Modern compared to Classic --> 
<PRE> #print-button    <!--INDEX Modern theme:compared to Classic --> 
     <!--INDEX Classic theme compared to Modern --> 
     <!--INDEX themes:Modern:compared to Classic --> already looked
     at it, using the skin-switching UI (View Menu &gt; Apply Theme
     &gt; Modern) in Mozilla will give you an idea about the
     differences between the two skins that come preinstalled with
     the browser. The Classic skin is modeled after earlier versions
     of the Mozilla UI and of the Netscape 4.x Communicator product.
     It has the familiar light grey box look, with the larger,
     primary-colored navigation button and a squared-off geometry.
     The Modern theme is a newer take on the browser interface. It
     has a smoother overall look, with rounded edges on many of the
     widgets, subtle color differentiations, gradients, and 3D
     icons.</p>
     <p>However, both skins sit on top of the same XUL. With one
     notable exception-a powerful feature of CSS in Mozilla
     discussed later in this chapter in the <a href=
     "#77101">"Binding New Widgets to the Interface Using XBL</a>"
     section-the applications themselves are identical, and themes
     themselves provide all the differences in the browser's look
     and behavior.</p>
     <h3><a name="77091"></a> Skin Files</h3>
     <p>Obviously, we cannot describe even a fraction of the CSS
     files that go into making up a single, overall theme. There
     are, however, some CSS files that help determine how the
     Mozilla browser looks. In this section, we will go over some of
     those files so you can see how they relate to one another,
     where the browser gets its look, and what strategies you might
     use to create your own complete skin.</p>
     <p>The following sections provide a brief, representative
     sampling of the Modern theme. The global skin, the navigator
     skin, and the communicator skin are discussed as they pertain
     to the Modern theme in the Mozilla browser.</p>
     <h4><a name="77092"></a> Navigator skin</h4>
     <p>One of the <!--INDEX Modern theme:navigator skin --> 
     <!--INDEX skins:navigator --> <!--INDEX navigator skin --> 
     <!--INDEX themes:Modern:navigator skin --> most specific and
     complex skin files in the Modern theme hierarchy is the
     <i>navigator.css</i> file, which contains style information for
     the browser itself. When you look through this skin, you will
     see rules for such things as the Print button. In <a href=
     "#77040">Example 4-6</a>, note how several selectors are
     grouped with a single style rule, and how the parent-child
     relationship between elements (see the earlier section <a href=
     "#77078">"Element relation selectors</a>" for an explanation of
     this selector) is used to style print buttons appearing in
     different places (i.e., under different element parents) in the
     UI.</p>
     <p><i>Example 4-6: <a name="77040"></a></i> <i>CSS for print
     button in navigator skin</i></p>
 <pre>
  #print-button
    {     {
      -moz-binding :       -moz-binding :
        url("chrome://communicator/skin/menubuttonBindings.xml#menubutton-dual-foo");         url("chrome://communicator/skin/menubuttonBindings.xml#menubutton-dual-foo");
      list-style-image : url("chrome://global/skin/print.gif");       list-style-image : url("chrome://global/skin/print.gif");
      margin           : 6px 6px 0px 6px;       margin           : 6px 6px 0px 6px;
    }     }
 #print-button</TD>[disabled="true"], #print-button&lt;/td&gt;[disabled="true"],
 #print-button</TD>[disabled="true"]:hover, #print-button&lt;/td&gt;[disabled="true"]:hover,
 #print-button</TD>[disabled="true"]:hover:active, #print-button&lt;/td&gt;[disabled="true"]:hover:active,
 #print-button</TD>[disabled="true"] &gt; .menubutton-dual-stack &gt; .menubutton-dual-button, #print-button&lt;/td&gt;[disabled="true"] &gt; .menubutton-dual-stack &gt; .menubutton-dual-button,
 #print-button</TD>[disabled="true"] &gt; .menubutton-dual-stack &gt; #print-button&lt;/td&gt;[disabled="true"] &gt; .menubutton-dual-stack &gt;
      .menubutton-dual-button:hover,       .menubutton-dual-button:hover,
 #print-button</TD>[disabled="true"] &gt; .menubutton-dual-stack &gt; #print-button&lt;/td&gt;[disabled="true"] &gt; .menubutton-dual-stack &gt;
      .menubutton-dual-button:hover:active       .menubutton-dual-button:hover:active
    {     {
      list-style-image      : url("chrome://global/skin/print-disabled.gif");       list-style-image      : url("chrome://global/skin/print-disabled.gif");
Line 421  contents.rdf Line 1482  contents.rdf
    {     {
      margin-left       : 19px;       margin-left       : 19px;
      margin-top        : 22px;       margin-top        : 22px;
   }</PRE>   }
</pre>
<H4><A NAME="77093"></A> Global skin</H4>    <h4><a name="77093"></a> Global skin</h4>
<P>Almost all <!--INDEX Modern theme:global skin -->  <!--INDEX skins:global -->  <!--INDEX global skin -->  <!--INDEX themes:Modern:global skin -->  of the most specific skin files (e.g., <I>navigator.css</I>) inherit from the global skin, which includes but is not limited to the <I>global.css</I> file located in <I>chrome://modern.jar!/skin/global/skin/</I>.    <p>Almost all <!--INDEX Modern theme:global skin --> 
<P>The global skin includes other stylesheets that define localizable settings and general global formatting, which the <I>global.css</I> file loads at runtime. If you look at the top of the <I>global.css</I> file as shown in <A HREF="#77042">Example 4-7</A>, you can see the stylesheet import statements that collect these skins into a single global skin:    <!--INDEX skins:global --> <!--INDEX global skin --> 
    <!--INDEX themes:Modern:global skin --> of the most specific
<P><I>Example 4-7: <A NAME="77042"></A></I>    skin files (e.g., <i>navigator.css</i>) inherit from the global
<I>CSS Import statements in global skin</I>    skin, which includes but is not limited to the
<PRE> /* ===== global.css ======================================================    <i>global.css</i> file located in
     <i>chrome://modern.jar!/skin/global/skin/</i>.</p>
     <p>The global skin includes other stylesheets that define
     localizable settings and general global formatting, which the
     <i>global.css</i> file loads at runtime. If you look at the top
     of the <i>global.css</i> file as shown in <a href=
     "#77042">Example 4-7</a>, you can see the stylesheet import
     statements that collect these skins into a single global
     skin:</p>
     <p><i>Example 4-7: <a name="77042"></a></i> <i>CSS Import
     statements in global skin</i></p>
 <pre>
  /* ===== global.css ======================================================
     == Styles that apply everywhere.      == Styles that apply everywhere.
     ======================================================================= */      ======================================================================= */
  /* all localizable skin settings shall live here */   /* all localizable skin settings shall live here */
  @import url("chrome://global/locale/intl.css");   @import url("chrome://global/locale/intl.css");
  @import url("chrome://global/skin/formatting.css");   @import url("chrome://global/skin/formatting.css");
 @namespace url("<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>"); @namespace url("<a href=
 "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>");
  /* ::::: XBL bindings ::::: */   /* ::::: XBL bindings ::::: */
 toolbarbutton</TD>[type="menu-button"] { toolbarbutton&lt;/td&gt;[type="menu-button"] {
     -moz-binding: url("chrome://global/skin/globalBindings.xml#toolbar-menu-button");      -moz-binding: url("chrome://global/skin/globalBindings.xml#toolbar-menu-button");
  }   }
  .menulist-compact {   .menulist-compact {
     -moz-binding:      -moz-binding:
        url("chrome://global/content/bindings/menulist.xml#menulist-compact");         url("chrome://global/content/bindings/menulist.xml#menulist-compact");
  }   }
 ...</PRE> ...
</pre>
<P>The <I>global.css</I> serves as a base into which these other skins can be loaded. When you load <I>global.css</I> into your XUL file by means of a <TT>xul-stylesheet</TT> processing instruction, you in effect load these skins.    <p>The <i>global.css</i> serves as a base into which these
<P>Also included in <A HREF="#77042">Example 4-7</A> are a couple of binding attachments, which attach content to elements that match certain style rules. On a related note, most global skins on a widget-per-widget basis are now included in the binding themselves, as opposed to being imported in a global skin, which used to be the case. Take this button stylesheet inclusion from the XBL file <TT>button.xml</TT> as a case in point:    other skins can be loaded. When you load <i>global.css</i> into
<PRE>&lt;resources&gt;    your XUL file by means of a <tt>xul-stylesheet</tt> processing
     instruction, you in effect load these skins.</p>
     <p>Also included in <a href="#77042">Example 4-7</a> are a
     couple of binding attachments, which attach content to elements
     that match certain style rules. On a related note, most global
     skins on a widget-per-widget basis are now included in the
     binding themselves, as opposed to being imported in a global
     skin, which used to be the case. Take this button stylesheet
     inclusion from the XBL file <tt>button.xml</tt> as a case in
     point:</p>
 <pre>
 &lt;resources&gt;
 &lt;stylesheet src="chrome://global/skin/button.css"/&gt;  &lt;stylesheet src="chrome://global/skin/button.css"/&gt;
&lt;/resources&gt;</PRE>&lt;/resources&gt;
<P>Here the XBL specific <TT>&lt;stylesheet&gt;</TT> element includes the stylesheet, which can be included in a binding and then inherited by other button bindings.</pre>
<H4><A NAME="77094"></A> The communicator skin</H4>    <p>Here the XBL specific <tt>&lt;stylesheet&gt;</tt> element
<P>Like <I>global.css</I>,  <!--INDEX Modern theme:communicator skin -->  <!--INDEX skins:communicator -->  <!--INDEX communicator skin -->  <!--INDEX themes:Modern:communicator skin --> the <I>communicator.css</I> file (<A HREF="#77044">Example 4-8</A>) is another CSS file that does imports to build up the communicator skin. The CSS style rules in the file itself are minimal, but if you look at the top, you can see that many styles that the communicator component uses come from the CSS files also located in the <I>communicator</I> subdirectory of the current skin.    includes the stylesheet, which can be included in a binding and
    then inherited by other button bindings.</p>
<P><I>Example 4-8: <A NAME="77044"></A></I>    <h4><a name="77094"></a> The communicator skin</h4>
<I>CSS information from communicator.css</I>    <p>Like <i>global.css</i>, 
<PRE> /* ==== communicator.css ====================================================    <!--INDEX Modern theme:communicator skin --> 
     <!--INDEX skins:communicator --> 
     <!--INDEX communicator skin --> 
     <!--INDEX themes:Modern:communicator skin --> the
     <i>communicator.css</i> file (<a href="#77044">Example 4-8</a>)
     is another CSS file that does imports to build up the
     communicator skin. The CSS style rules in the file itself are
     minimal, but if you look at the top, you can see that many
     styles that the communicator component uses come from the CSS
     files also located in the <i>communicator</i> subdirectory of
     the current skin.</p>
     <p><i>Example 4-8: <a name="77044"></a></i> <i>CSS information
     from communicator.css</i></p>
 <pre>
  /* ==== communicator.css ====================================================
     == Styles shared everywhere throughout the Communicator suite.      == Styles shared everywhere throughout the Communicator suite.
     ========================================================================== */      ========================================================================== */
  @import url("chrome://global/skin/");   @import url("chrome://global/skin/");
Line 465  contents.rdf Line 1564  contents.rdf
  @import url("chrome://communicator/skin/brand.css");   @import url("chrome://communicator/skin/brand.css");
  @import url("chrome://communicator/skin/button.css");   @import url("chrome://communicator/skin/button.css");
  @import url("chrome://communicator/skin/formatting.css");   @import url("chrome://communicator/skin/formatting.css");
 @namespace url("<a href=
 @namespace url("<A HREF="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</A>");"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul</a>");
 
  /* ::::: online/offline icons ::::: */   /* ::::: online/offline icons ::::: */
 #offline-status&lt;/td&gt;[offline="true"] {
 #offline-status</TD>[offline="true"] { 
    list-style-image: url("chrome://communicator/skin/icons/offline.gif");     list-style-image: url("chrome://communicator/skin/icons/offline.gif");
  }   }
   
  #offline-status {   #offline-status {
    list-style-image: url("chrome://communicator/skin/icons/online.gif");     list-style-image: url("chrome://communicator/skin/icons/online.gif");
  }   }
   
  /* ::::: directional button icons ::::: */   /* ::::: directional button icons ::::: */
   
  .up {   .up {
    min-width: 0px;     min-width: 0px;
    list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");     list-style-image: url("chrome://global/skin/arrow/arrow-up.gif");
  }   }
 .up&lt;/td&gt;[disabled="true"] {
 .up</TD>[disabled="true"] { 
    list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");     list-style-image: url("chrome://global/skin/arrow/arrow-up-dis.gif");
  }   }
   
  .down {   .down {
    min-width: 0px;     min-width: 0px;
    list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");     list-style-image: url("chrome://global/skin/arrow/arrow-dn.gif");
  }   }
 .down&lt;/td&gt;[disabled="true"] {
 .down</TD>[disabled="true"] { 
    list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");     list-style-image: url("chrome://global/skin/arrow/arrow-dn-dis.gif");
  }   }
   
  .up {   .up {
    list-style-image:url("chrome://global/skin/scroll-up.gif");     list-style-image:url("chrome://global/skin/scroll-up.gif");
    min-width: 0px;     min-width: 0px;
  }   }
 .up</TD>[disabled="true"] { .up&lt;/td&gt;[disabled="true"] {
    list-style-image:url("chrome://global/skin/scroll-up-disabled.gif");     list-style-image:url("chrome://global/skin/scroll-up-disabled.gif");
  }   }
  .down {   .down {
    min-width: 0px;     min-width: 0px;
    list-style-image:url("chrome://global/skin/scroll-down.gif");     list-style-image:url("chrome://global/skin/scroll-down.gif");
  }   }
 .down</TD>[disabled="true"] { .down&lt;/td&gt;[disabled="true"] {
    list-style-image:url("chrome://global/skin/scroll-down-disabled.gif");     list-style-image:url("chrome://global/skin/scroll-down-disabled.gif");
  }   }
  .sidebarTree {   .sidebarTree {
Line 519  contents.rdf Line 1609  contents.rdf
  /* ::::: download manager ::::: */   /* ::::: download manager ::::: */
  #downloadView &gt; treechildren:-moz-tree-image(Name) {   #downloadView &gt; treechildren:-moz-tree-image(Name) {
    margin-right: 2px;     margin-right: 2px;
 }</PRE> }
</pre>
<H2><A NAME="77095"></A> Creating New Skins</H2>    <h2><a name="77095"></a> Creating New Skins</h2>
<P>You have  <!--INDEX skins:creating --> already created the highest level of the directory structure you will need to create a skin for the xFly     <p>You have <!--INDEX skins:creating --> already created the
application (See "Creating the Hello xFly Package" in <A HREF="ch02.html#77048">Chapter 2</A>). So far, you have created three subdirectories corresponding to different parts of the package and you have added XUL to the <I>xfly/content </I>subdirectory. In the <I>xfly/skin</I> subdirectory, you will tell the xFly content where to expect to find its skin resources. As just mentioned, Mozilla applications outside of the browser itself typically restrict their skin to a single subdirectory and their skin manifest to a single RDF/XML file.    highest level of the directory structure you will need to
<P>Since the <I>skin</I> subdirectory in your xFly package is already registered, you can create a new CSS file called <I>xfly.css</I>, save it in the <I>skins </I>subdirectory, and load it from your <I>xfly.xul</I> file by adding the following stylesheet loading instruction at the top:    create a skin for the xFly application (See "Creating the Hello
<PRE>&lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css" ?&gt;</PRE>    xFly Package" in <a href="ch02.html#77048">Chapter 2</a>). So
<P>You will recall that the chrome pointer in the <I>href</I> resolves to a file named <I>xfly.css</I> (named after the directory) in the following <I>registered</I> directory in the chrome:    far, you have created three subdirectories corresponding to
<PRE>chrome/xfly/skin/</PRE>    different parts of the package and you have added XUL to the
<P>This CSS file will be the worksheet for all CSS for the xFly application. Any style rules you add here and associated with XUL elements in the xFly XUL code will affect the layout and presentation of that code on restart.    <i>xfly/content</i> subdirectory. In the <i>xfly/skin</i>
<H3><A NAME="77096"></A> Importing the Global Skin</H3>    subdirectory, you will tell the xFly content where to expect to
<P>As you <!--INDEX skins:creating:importing global skin -->  <!--INDEX global skin:importing, creating new skins -->  <!--INDEX importing:global skin, creating new skins -->  create a new skin for your application, the first step is to make sure that the application imports the global skin in which the most basic look and feel of the XUL widgets is defined. Even if you create a skin that looks completely different than the skins installed with Mozilla, you should import the global skin to avoid having to recreate so much of the basic presentation and behavior of the XUL widgets.    find its skin resources. As just mentioned, Mozilla
<P>As much as possible, the global skin avoids providing theme-specific styles, and instead provides just enough information to make buttons, for example, look like buttons and menu items look like menu items. Increasingly, basic styles are also being defined in the XBL bindings for widgets. For instance, when you use a <TT>toolbar</TT> widget, you use a binding in which certain intrinsic looks and behaviors are defined in a way that's transparent to you and to the user of the application. The style for these bindings is located in the content subdirectories with the binding XML files. In this way, they "stay with" the widget and not with the selected skin. You can easily extend or overwrite any of the style information you pick up from the global skin, but loading the skin is a good place to start.    applications outside of the browser itself typically restrict
<P>To do this, verify that you have the following line at the top of the <I>xfly.xul</I> file:    their skin to a single subdirectory and their skin manifest to
<PRE>&lt;?xml-stylesheet href="chrome://global/skin" type="text/css" ?&gt;</PRE>    a single RDF/XML file.</p>
<P>If you do not have this line, add it now to the <I>xfly.xul</I> file and restart Mozilla. You ought to see a plain, UI-like collection of widgets in the XUL window. In the screenshots in <A HREF="#77016">Figure 4-8</A>, you can see how loading the global skin affects the XUL file.    <p>Since the <i>skin</i> subdirectory in your xFly package is
<P><CENTER><IMG SRC="foo.gif"></CENTER>    already registered, you can create a new CSS file called
<P><I>Figure 4-8: <A NAME="77016"></A></I>    <i>xfly.css</i>, save it in the <i>skins</i> subdirectory, and
<I>Stylesheet additions to a XUL file</I>    load it from your <i>xfly.xul</i> file by adding the following
    stylesheet loading instruction at the top:</p>
<P>The first screenshot in <A HREF="#77016">Figure 4-8</A> shows a XUL file loaded in Mozilla with no skin information. The second is the same XUL file with the global skin loading instruction at the top. The third is a screenshot of that XUL file with an instruction for loading your own stylesheet, which in turn imports the global skin:<pre>
<PRE>&lt;?xml-stylesheet href="chrome://xfly/skin/sample.css" type="text/css" ?&gt;</PRE>&lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css" ?&gt;
<P>The CSS information in the skin file <I>sample.css</I> loaded above looks like this:</pre>
<PRE>@import url(chrome://global/skin/)    <p>You will recall that the chrome pointer in the <i>href</i>
     resolves to a file named <i>xfly.css</i> (named after the
     directory) in the following <i>registered</i> directory in the
     chrome:</p>
 <pre>
 chrome/xfly/skin/
 </pre>
     <p>This CSS file will be the worksheet for all CSS for the xFly
     application. Any style rules you add here and associated with
     XUL elements in the xFly XUL code will affect the layout and
     presentation of that code on restart.</p>
     <h3><a name="77096"></a> Importing the Global Skin</h3>
     <p>As you <!--INDEX skins:creating:importing global skin --> 
     <!--INDEX global skin:importing, creating new skins --> 
     <!--INDEX importing:global skin, creating new skins --> create
     a new skin for your application, the first step is to make sure
     that the application imports the global skin in which the most
     basic look and feel of the XUL widgets is defined. Even if you
     create a skin that looks completely different than the skins
     installed with Mozilla, you should import the global skin to
     avoid having to recreate so much of the basic presentation and
     behavior of the XUL widgets.</p>
     <p>As much as possible, the global skin avoids providing
     theme-specific styles, and instead provides just enough
     information to make buttons, for example, look like buttons and
     menu items look like menu items. Increasingly, basic styles are
     also being defined in the XBL bindings for widgets. For
     instance, when you use a <tt>toolbar</tt> widget, you use a
     binding in which certain intrinsic looks and behaviors are
     defined in a way that's transparent to you and to the user of
     the application. The style for these bindings is located in the
     content subdirectories with the binding XML files. In this way,
     they "stay with" the widget and not with the selected skin. You
     can easily extend or overwrite any of the style information you
     pick up from the global skin, but loading the skin is a good
     place to start.</p>
     <p>To do this, verify that you have the following line at the
     top of the <i>xfly.xul</i> file:</p>
 <pre>
 &lt;?xml-stylesheet href="chrome://global/skin" type="text/css" ?&gt;
 </pre>
     <p>If you do not have this line, add it now to the
     <i>xfly.xul</i> file and restart Mozilla. You ought to see a
     plain, UI-like collection of widgets in the XUL window. In the
     screenshots in <a href="#77016">Figure 4-8</a>, you can see how
     loading the global skin affects the XUL file.</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-8: <a name="77016"></a></i> <i>Stylesheet
     additions to a XUL file</i></p>
     <p>The first screenshot in <a href="#77016">Figure 4-8</a>
     shows a XUL file loaded in Mozilla with no skin information.
     The second is the same XUL file with the global skin loading
     instruction at the top. The third is a screenshot of that XUL
     file with an instruction for loading your own stylesheet, which
     in turn imports the global skin:</p>
 <pre>
 &lt;?xml-stylesheet href="chrome://xfly/skin/sample.css" type="text/css" ?&gt;
 </pre>
     <p>The CSS information in the skin file <i>sample.css</i>
     loaded above looks like this:</p>
 <pre>
 @import url(chrome://global/skin/)
 box#bbox { background-color: lightgrey; }  box#bbox { background-color: lightgrey; }
button#rd { background-color: red; color: white; }</PRE>button#rd { background-color: red; color: white; }
<P>Taking advantage of the modularity of Mozilla skins, you can design a decent interface (if the last screenshot above can count as that) with just a few lines of code.</pre>
<P>Once you import the global skin and see what it buys you in terms of look and feel, you can begin to create your own skin for the xFly, overriding global styles where appropriate, extending them by "cascading" new, more specific style rules for your widgets, or adding new styles.    <p>Taking advantage of the modularity of Mozilla skins, you can
<P>Before you begin to add styles to the <I>xfly.css</I> file, import it (as a blank skin) into <I>xfly.xul</I> so you can see your progress as you go. Add the following line to the top of the <I>xfly.xul</I> file to import the xFly skin from the proper subdirectory of the xFly package:    design a decent interface (if the last screenshot above can
<PRE>&lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css" ?&gt;</PRE>    count as that) with just a few lines of code.</p>
<P>You won't see anything extra when you quit and restart the application, but you now have the skin structure in place so you can see your work progress.    <p>Once you import the global skin and see what it buys you in
<H3><A NAME="77097"></A> Getting Started with Custom Styles</H3>    terms of look and feel, you can begin to create your own skin
<P>When you  <!--INDEX skins:creating:general custom styles -->  <!--INDEX CSS (Cascading Style Sheets):skins:defining general custom styles --> make a new skin, it's a good idea to define the most general styles for your application first. As we described above, more specific CSS rules tend to inherit from more general ones. For the xFly application, the most general aspects of the style are the rules that apply to the xFly windows themselves. You can create styles for all windows using the element name, <I>window</I>, or you can define different classes for windows if your application supports them. In the <I>xfly.xul</I> file, for example, the root <TT>&lt;window&gt;</TT> element has the attribute <TT>class="main"</TT>, so it will pick up style rules given for <I>window.main</I>, as shown in <A HREF="#77046">Example 4-9</A>.    for the xFly, overriding global styles where appropriate,
<P>The xFly application has both a main window and pop-up windows, so you might create style rules like the ones that follow to establish the basic look of the xFly application.    extending them by "cascading" new, more specific style rules
    for your widgets, or adding new styles.</p>
<P><I>Example 4-9: <A NAME="77046"></A></I>    <p>Before you begin to add styles to the <i>xfly.css</i> file,
<I>CSS rules for xFly window</I>    import it (as a blank skin) into <i>xfly.xul</i> so you can see
<PRE> window.main {    your progress as you go. Add the following line to the top of
     the <i>xfly.xul</i> file to import the xFly skin from the
     proper subdirectory of the xFly package:</p>
 <pre>
 &lt;?xml-stylesheet href="chrome://xfly/skin" type="text/css" ?&gt;
 </pre>
     <p>You won't see anything extra when you quit and restart the
     application, but you now have the skin structure in place so
     you can see your work progress.</p>
     <h3><a name="77097"></a> Getting Started with Custom
     Styles</h3>
     <p>When you <!--INDEX skins:creating:general custom styles --> 
     <!--INDEX CSS (Cascading Style Sheets):skins:defining general custom styles -->
     make a new skin, it's a good idea to define the most general
     styles for your application first. As we described above, more
     specific CSS rules tend to inherit from more general ones. For
     the xFly application, the most general aspects of the style are
     the rules that apply to the xFly windows themselves. You can
     create styles for all windows using the element name,
     <i>window</i>, or you can define different classes for windows
     if your application supports them. In the <i>xfly.xul</i> file,
     for example, the root <tt>&lt;window&gt;</tt> element has the
     attribute <tt>class="main"</tt>, so it will pick up style rules
     given for <i>window.main</i>, as shown in <a href=
     "#77046">Example 4-9</a>.</p>
     <p>The xFly application has both a main window and pop-up
     windows, so you might create style rules like the ones that
     follow to establish the basic look of the xFly application.</p>
     <p><i>Example 4-9: <a name="77046"></a></i> <i>CSS rules for
     xFly window</i></p>
 <pre>
  window.main {
     background-color:            #cccccc;      background-color:            #cccccc;
      display:                    block;       display:                    block;
      overflow:                   hidden;       overflow:                   hidden;
Line 564  button#rd { background-color: red; color Line 1748  button#rd { background-color: red; color
      padding:                    0px;       padding:                    0px;
  }   }
  window.popup{   window.popup{
   
      background-color:           #cccccc;       background-color:           #cccccc;
      display:                    block;       display:                    block;
      overflow:                   hidden;       overflow:                   hidden;
Line 572  button#rd { background-color: red; color Line 1755  button#rd { background-color: red; color
      padding:                    2px;       padding:                    2px;
      width:                      auto;       width:                      auto;
      height:                     auto;       height:                     auto;
 }</PRE> }
</pre>
<P>Now, with the two stylesheets (<I>global.css</I> and the <I>xfly.css</I>) referenced at the top, you already have a window that is starting to look like an application.    <p>Now, with the two stylesheets (<i>global.css</i> and the
<H3><A NAME="77098"></A> Creating Styles for the xFly Buttons</H3>    <i>xfly.css</i>) referenced at the top, you already have a
<P>Now that <!--INDEX skins:creating:button styles -->  <!--INDEX buttons:styles, creating for custom skins -->  you have created a single custom style for the xFly application, you can see how easy it is to associate cascading style rules with any element in your interface. The next logical step is to style the buttons in the xFly sample application, since they make up such a large portion of the interface itself.    window that is starting to look like an application.</p>
<P>When you use the button widget without any extra style information, you already get a lot of the button-like presentation and behavior. The button has different looks, for example, when you hover over it and when you click it, and it has a basic three-dimensional shape as seen in <A HREF="#77018">Figure 4-9</A>.    <h3><a name="77098"></a> Creating Styles for the xFly
<P><CENTER><IMG SRC="foo.gif"></CENTER>    Buttons</h3>
<P><I>Figure 4-9: <A NAME="77018"></A></I>    <p>Now that <!--INDEX skins:creating:button styles --> 
<I>XUL button with no style</I>    <!--INDEX buttons:styles, creating for custom skins --> you
    have created a single custom style for the xFly application,
<P>A common update to regular XUL buttons is to give them images, like the navigation buttons in the main Mozilla browser window. Adding the class-based style rule in <A HREF="#77048">Example 4-10</A> to the xFly stylesheet (and, of course, the GIF image itself to the <I>skin</I> subdirectory) will give all the "fly" buttons background images with flies in them.    you can see how easy it is to associate cascading style rules
    with any element in your interface. The next logical step is to
Example 4-10<A NAME="77048"></A>    style the buttons in the xFly sample application, since they
<I>Custom styles for buttons</I>    make up such a large portion of the interface itself.</p>
<PRE> button.fly {    <p>When you use the button widget without any extra style
     information, you already get a lot of the button-like
     presentation and behavior. The button has different looks, for
     example, when you hover over it and when you click it, and it
     has a basic three-dimensional shape as seen in <a href=
     "#77018">Figure 4-9</a>.</p>
     <div class="c12">
       <img src="foo.gif">
     </div>
     <p><i>Figure 4-9: <a name="77018"></a></i> <i>XUL button with
     no style</i></p>
     <p>A common update to regular XUL buttons is to give them
     images, like the navigation buttons in the main Mozilla browser
     window. Adding the class-based style rule in <a href=
     "#77048">Example 4-10</a> to the xFly stylesheet (and, of
     course, the GIF image itself to the <i>skin</i> subdirectory)
     will give all the "fly" buttons background images with flies in
     them. Example 4-10<a name="77048"></a> <i>Custom styles for
     buttons</i></p>
 <pre>
  button.fly {
    list-style-image: url("chrome://xfly/skin/btnfly.gif");     list-style-image: url("chrome://xfly/skin/btnfly.gif");
  }   }
 button.fly</TD>[disabled="true"] { button.fly&lt;/td&gt;[disabled="true"] {
    list-style-image: url("chrome://xfly/skin/btnfly-dis.gif ");     list-style-image: url("chrome://xfly/skin/btnfly-dis.gif ");
  }   }
  button.fly#hover {   button.fly#hover {
    list-style-image: url("chrome://xfly/skin/btnfly-hov.gif ");     list-style-image: url("chrome://xfly/skin/btnfly-hov.gif ");
 }</PRE> }
</pre>
<H3><A NAME="77099"></A> Describing the Skin in RDF</H3>    <h3><a name="77099"></a> Describing the Skin in RDF</h3>
<P>As described  <!--INDEX skins:creating:RDF manifest files -->  <!--INDEX RDF (Resource Description Framework):files:creating skins -->      <p>As described <!--INDEX skins:creating:RDF manifest files -->
<!--INDEX manifests:creating skins -->  <!--INDEX files:mainfest, creating skins --> in <A HREF="ch06.html#15291">Chapter 6</A>, a manifest must accompany and describe the skin so it can be found and registered. The manifest is an RDF file called <I>contents.rdf</I> that sits at the highest level of the skin (i.e., at the top of the JAR or immediately under the <I>modern</I> directory when extracted to disk). Since the content, skin, and locale of an application are considered different packages, each must have its own manifest.    <!--INDEX RDF (Resource Description Framework):files:creating skins -->
<P>The listing in <A HREF="#77050">Example 4-11</A> shows the <I>contents.rdf</I> manifest that accompanies the xFly skin resources in the <I>xfly.jar!/skin/</I> directory.    <!--INDEX manifests:creating skins --> 
    <!--INDEX files:mainfest, creating skins --> in <a href=
Example 4-11<A NAME="77050"></A>    "ch06.html#15291">Chapter 6</a>, a manifest must accompany and
<I>Skin manifest for the xFly sample</I>    describe the skin so it can be found and registered. The
<PRE> &lt;?xml version="1.0"?&gt;    manifest is an RDF file called <i>contents.rdf</i> that sits at
 &lt;RDF:RDF xmlns:RDF="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#    the highest level of the skin (i.e., at the top of the JAR or
    xmlns:chrome="<A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#"&gt;    immediately under the <i>modern</i> directory when extracted to
     disk). Since the content, skin, and locale of an application
     are considered different packages, each must have its own
     manifest.</p>
     <p>The listing in <a href="#77050">Example 4-11</a> shows the
     <i>contents.rdf</i> manifest that accompanies the xFly skin
     resources in the <i>xfly.jar!/skin/</i> directory. Example
     4-11<a name="77050"></a> <i>Skin manifest for the xFly
     sample</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#
     xmlns:chrome="<a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
    &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;     &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
      &lt;RDF:li resource="urn:mozilla:skin:classic/1.0" /&gt;       &lt;RDF:li resource="urn:mozilla:skin:classic/1.0" /&gt;
    &lt;/RDF:Seq&gt;     &lt;/RDF:Seq&gt;
Line 616  Example 4-11<A NAME="77050"></A> Line 1833  Example 4-11<A NAME="77050"></A>
        &lt;/RDF:Seq&gt;         &lt;/RDF:Seq&gt;
      &lt;/chrome:packages&gt;       &lt;/chrome:packages&gt;
    &lt;/RDF:Description&gt;     &lt;/RDF:Description&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<P>As you can see, the basic form of the manifest is something like, "This is the classic skin we have (given as a direct child of the RDF root element), which applies to the following packages: <I>xfly</I>." The second group of RDF in this manifest provides a list of packages to which the skin should apply. In the case of the xFly application, all XUL code is a single package. In Mozilla, a <I>contents.rdf</I> file in a package subdirectory of the <I>modern.jar</I>, for example, would describe the communicator package in a similar way, but it would be a composite of other package manifests in the theme to create a single, overarching manifest for the whole theme. <A HREF="#77052">Example 4-12</A> shows the manifest for just the Mozilla communicator package.    <p>As you can see, the basic form of the manifest is something
    like, "This is the classic skin we have (given as a direct
Example 4-12<A NAME="77052"></A>    child of the RDF root element), which applies to the following
<I>Manifest for the communicator package of the modern skin in Mozilla</I>    packages: <i>xfly</i>." The second group of RDF in this
<PRE> &lt;?xml version="1.0"?&gt;    manifest provides a list of packages to which the skin should
 &lt;RDF:RDF xmlns:RDF="<A HREF="http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</A>#"    apply. In the case of the xFly application, all XUL code is a
          xmlns:chrome="<A HREF="http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</A>#"&gt;    single package. In Mozilla, a <i>contents.rdf</i> file in a
     package subdirectory of the <i>modern.jar</i>, for example,
     would describe the communicator package in a similar way, but
     it would be a composite of other package manifests in the theme
     to create a single, overarching manifest for the whole theme.
     <a href="#77052">Example 4-12</a> shows the manifest for just
     the Mozilla communicator package. Example 4-12<a name=
     "77052"></a> <i>Manifest for the communicator package of the
     modern skin in Mozilla</i></p>
 <pre>
  &lt;?xml version="1.0"?&gt;
  &lt;RDF:RDF xmlns:RDF="<a href=
 "http://www.w3.org/1999/02/22-rdf-syntax-ns">http://www.w3.org/1999/02/22-rdf-syntax-ns</a>#"
           xmlns:chrome="<a href=
 "http://www.mozilla.org/rdf/chrome">http://www.mozilla.org/rdf/chrome</a>#"&gt;
    &lt;!-- List all the skins being supplied by this theme --&gt;     &lt;!-- List all the skins being supplied by this theme --&gt;
    &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;     &lt;RDF:Seq about="urn:mozilla:skin:root"&gt;
      &lt;RDF:li resource="urn:mozilla:skin:modern/1.0" /&gt;       &lt;RDF:li resource="urn:mozilla:skin:modern/1.0" /&gt;
Line 637  Example 4-12<A NAME="77052"></A> Line 1868  Example 4-12<A NAME="77052"></A>
        &lt;/RDF:Seq&gt;         &lt;/RDF:Seq&gt;
      &lt;/chrome:packages&gt;       &lt;/chrome:packages&gt;
    &lt;/RDF:Description&gt;     &lt;/RDF:Description&gt;
 &lt;/RDF:RDF&gt;</PRE> &lt;/RDF:RDF&gt;
</pre>
<P>This RDF/XML file describes a skin to the chrome registry so it can be registered properly. All new packages must be accompanied by these sorts of RDF-based descriptions if they will be made available to users.    <p>This RDF/XML file describes a skin to the chrome registry so
<H2><A NAME="77100"></A> What Is Possible in a Skin?</H2>    it can be registered properly. All new packages must be
<P>In this final section, we describe a few things that make CSS in Mozilla particularly powerful and cases when this power is curtailed because of the security restrictions.    accompanied by these sorts of RDF-based descriptions if they
<H3><A NAME="77101"></A> Binding New Widgets to the Interface Using XBL</H3>    will be made available to users.</p>
<P>A  <!--INDEX CSS (Cascading Style Sheets):widgets, binding with XBL -->  <!--INDEX widgets:binding with XBL -->  <!--INDEX skins:widgets,     <h2><a name="77100"></a> What Is Possible in a Skin?</h2>
binding with XBL -->  <!--INDEX bindings:XBL:widgets -->  <!--INDEX XBL (eXtensible Binding Language):widgets --> description of skins wouldn't be complete without a mention of binding widgets by using XBL, a very powerful feature of CSS in Mozilla. The <TT>-moz-binding</TT> keyword described in <A HREF="#77028">Table 4-4</A> is the key to binding special, prefabricated widgets to your XUL. The language in which these widgets are defined is another XML-based language called the Extensible Bindings Language. <A HREF="ch07.html#77027">Chapter 7</A> describes this language in more detail.    <p>In this final section, we describe a few things that make
<P>To see how XBL works, go back and look at the first style rule for "print-button" in <A HREF="#77040">Example 4-6</A>. The first style statement in that block has a property called <TT>-moz-</TT> <TT>binding</TT>. This property defines a <I>binding</I> for the XUL element styled by this style rule. The <I>chome URL</I> that the <TT>-moz-binding</TT> property points to is where an XBL-based definition of a print button is located.    CSS in Mozilla particularly powerful and cases when this power
<P>Creating a style rule in which your XUL element (in this case, a button in which the ID is "print-button") and the use of the <TT>-moz-binding</TT> to point to the XBL defines new properties, behavior, or content for that XUL element, you can add to or totally recreate any widget in your interface. The binding itself is described in XBL, but XBL also provides structures (such as the <TT>&lt;content&gt;</TT> and <TT>&lt;handlers&gt;</TT> child elements) in which you can define new XUL content, new JavaScript, and new XPConnected interfaces. CSS glues the XUL together with the XBL.    is curtailed because of the security restrictions.</p>
<P>In the first part of the snippet in <A HREF="#77054">Example 4-13</A>, for example, the CSS rule binds the toolbar button to an XBL binding called <I>menu-button</I>, which adds a button and an image.    <h3><a name="77101"></a> Binding New Widgets to the Interface
    Using XBL</h3>
Example 4-13<A NAME="77054"></A>    <p>A 
<I>CSS and XBL example</I>    <!--INDEX CSS (Cascading Style Sheets):widgets, binding with XBL -->
<PRE> // In the CSS:    <!--INDEX widgets:binding with XBL --> 
 toolbarbutton</TD>[type="menu-button"] {    <!--INDEX skins:widgets, 
     binding with XBL --> <!--INDEX bindings:XBL:widgets --> 
     <!--INDEX XBL (eXtensible Binding Language):widgets -->
     description of skins wouldn't be complete without a mention of
     binding widgets by using XBL, a very powerful feature of CSS in
     Mozilla. The <tt>-moz-binding</tt> keyword described in <a
     href="#77028">Table 4-4</a> is the key to binding special,
     prefabricated widgets to your XUL. The language in which these
     widgets are defined is another XML-based language called the
     Extensible Bindings Language. <a href="ch07.html#77027">Chapter
     7</a> describes this language in more detail.</p>
     <p>To see how XBL works, go back and look at the first style
     rule for "print-button" in <a href="#77040">Example 4-6</a>.
     The first style statement in that block has a property called
     <tt>-moz-</tt> <tt>binding</tt>. This property defines a
     <i>binding</i> for the XUL element styled by this style rule.
     The <i>chome URL</i> that the <tt>-moz-binding</tt> property
     points to is where an XBL-based definition of a print button is
     located.</p>
     <p>Creating a style rule in which your XUL element (in this
     case, a button in which the ID is "print-button") and the use
     of the <tt>-moz-binding</tt> to point to the XBL defines new
     properties, behavior, or content for that XUL element, you can
     add to or totally recreate any widget in your interface. The
     binding itself is described in XBL, but XBL also provides
     structures (such as the <tt>&lt;content&gt;</tt> and
     <tt>&lt;handlers&gt;</tt> child elements) in which you can
     define new XUL content, new JavaScript, and new XPConnected
     interfaces. CSS glues the XUL together with the XBL.</p>
     <p>In the first part of the snippet in <a href="#77054">Example
     4-13</a>, for example, the CSS rule binds the toolbar button to
     an XBL binding called <i>menu-button</i>, which adds a button
     and an image. Example 4-13<a name="77054"></a> <i>CSS and XBL
     example</i></p>
 <pre>
  // In the CSS:
  toolbarbutton&lt;/td&gt;[type="menu-button"] {
     -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu-button");      -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu-button");
  }   }
  // In the XBL file toolbarbutton.xml:   // In the XBL file toolbarbutton.xml:
Line 661  Example 4-13<A NAME="77054"></A> Line 1928  Example 4-13<A NAME="77054"></A>
    &lt;resources&gt;     &lt;resources&gt;
      &lt;stylesheet src="chrome://global/skin/toolbarbutton.css"/&gt;       &lt;stylesheet src="chrome://global/skin/toolbarbutton.css"/&gt;
    &lt;/resources&gt;     &lt;/resources&gt;
   
    &lt;content&gt;     &lt;content&gt;
      &lt;children includes="observes|template|menupopup|tooltip"/&gt;       &lt;children includes="observes|template|menupopup|tooltip"/&gt;
      &lt;xul:toolbarbutton class="box-inherit toolbarbutton-menubutton-button"       &lt;xul:toolbarbutton class="box-inherit toolbarbutton-menubutton-button"
Line 671  Example 4-13<A NAME="77054"></A> Line 1937  Example 4-13<A NAME="77054"></A>
      &lt;xul:dropmarker type="menu-button" class="toolbarbutton-menubutton-dropmarker"       &lt;xul:dropmarker type="menu-button" class="toolbarbutton-menubutton-dropmarker"
                          xbl:inherits="align,dir,pack,orient,disabled"/&gt;                           xbl:inherits="align,dir,pack,orient,disabled"/&gt;
    &lt;/content&gt;     &lt;/content&gt;
 &lt;/binding&gt;</PRE> &lt;/binding&gt;
</pre>
<P>When you use the Modern skin, you can see in <A HREF="#77020">Figure 4-10</A> that the menu button is a composite of the toolbar button, a dropmarker image resource, and a <TT>menupopup</TT> making the drop-down history available.    <p>When you use the Modern skin, you can see in <a href=
<P><CENTER><IMG SRC="foo.gif"></CENTER>    "#77020">Figure 4-10</a> that the menu button is a composite of
Figure 4-10<A NAME="77020"></A>    the toolbar button, a dropmarker image resource, and a
<I>Modern menu button</I>    <tt>menupopup</tt> making the drop-down history available.</p>
    <div class="c12">
<P>You might also notice in <A HREF="#77054">Example 4-13</A> that this binding pulls in an external stylesheet (<TT>toolbarbutton.css</TT>),       <img src="foo.gif">
which is contained in the <TT>&lt;resources&gt;</TT> section of the binding. This stylesheet provides all the styles and theme information for a toolbar button, including the type of <TT>menu-button</TT>. More information on stylesheets in XBL can be found in <A HREF="ch07.html#70326">Chapter 7</A>.    </div>
<H3><A NAME="77102"></A> User Stylesheets</H3>    Figure 4-10<a name="77020"></a> <i>Modern menu button</i> 
<P>In  <!--INDEX user stylesheets -->  <!--INDEX stylesheets:user -->  <!--INDEX CSS (Cascading Style Sheets):user stylesheets -->  <!--INDEX userChrome.css -->  <!--INDEX userContent.css --> addition to the many CSS stylesheets that give the user interface its look, Mozilla also lets you create personal stylesheets that apply to all of the chrome and content you view in the browser. Two CSS files, <I>userChrome.css</I> and <I>userContent.css</I>, located in the <I>chrome</I> subdirectory of your user profile, can define rules that apply to all of the Mozilla application interfaces and all web pages you view, respectively. When these two files are present-sometimes they are installed in the user profile and sometimes you create them yourself-they come with example rules that are commented out. However, you can uncomment them and add your own rules to personalize the look of the browser and its content.    <p>You might also notice in <a href="#77054">Example 4-13</a>
<P><A HREF="#77056">Example 4-14</A> shows the default commented rules in <I>userChrome.css</I>. Note the use of the <TT>!important</TT> keyword to specify that these rules should take precedence over rules that come from stylesheets in the current theme.    that this binding pulls in an external stylesheet
    (<tt>toolbarbutton.css</tt>), which is contained in the
Example 4-14<A NAME="77056"></A>    <tt>&lt;resources&gt;</tt> section of the binding. This
<I>userChrome.css style rules</I>    stylesheet provides all the styles and theme information for a
<PRE> /*    toolbar button, including the type of <tt>menu-button</tt>.
     More information on stylesheets in XBL can be found in <a href=
     "ch07.html#70326">Chapter 7</a>.</p>
     <h3><a name="77102"></a> User Stylesheets</h3>
     <p>In <!--INDEX user stylesheets --> 
     <!--INDEX stylesheets:user --> 
     <!--INDEX CSS (Cascading Style Sheets):user stylesheets --> 
     <!--INDEX userChrome.css --> <!--INDEX userContent.css -->
     addition to the many CSS stylesheets that give the user
     interface its look, Mozilla also lets you create personal
     stylesheets that apply to all of the chrome and content you
     view in the browser. Two CSS files, <i>userChrome.css</i> and
     <i>userContent.css</i>, located in the <i>chrome</i>
     subdirectory of your user profile, can define rules that apply
     to all of the Mozilla application interfaces and all web pages
     you view, respectively. When these two files are
     present-sometimes they are installed in the user profile and
     sometimes you create them yourself-they come with example rules
     that are commented out. However, you can uncomment them and add
     your own rules to personalize the look of the browser and its
     content.</p>
     <p><a href="#77056">Example 4-14</a> shows the default
     commented rules in <i>userChrome.css</i>. Note the use of the
     <tt>!important</tt> keyword to specify that these rules should
     take precedence over rules that come from stylesheets in the
     current theme. Example 4-14<a name="77056"></a>
     <i>userChrome.css style rules</i></p>
 <pre>
  /*
   * This file can be used to customize the look of Mozilla's user interface    * This file can be used to customize the look of Mozilla's user interface
   * You should consider using !important on rules which you want to    * You should consider using !important on rules which you want to
   * override default settings.    * override default settings.
Line 708  Example 4-14<A NAME="77056"></A> Line 2002  Example 4-14<A NAME="77056"></A>
   * }    * }
   */    */
  /*   /*
  * For more examples see <A HREF="http://www.mozilla.org/unix/customizing.html">http://www.mozilla.org/unix/customizing.html</A>  * For more examples see <a href=
  */</PRE>"http://www.mozilla.org/unix/customizing.html">http://www.mozilla.org/unix/customizing.html</a>
  */
<P>If you want to make the content in all your <TT>menu</TT> widgets white so you can read them better, get rid of these defaults and do something like this:</pre>
<PRE>menu {    <p>If you want to make the content in all your <tt>menu</tt>
     widgets white so you can read them better, get rid of these
     defaults and do something like this:</p>
 <pre>
 menu {
 background-color: white !important;  background-color: white !important;
 color: darkblue !important;  color: darkblue !important;
 padding: 5px !important;  padding: 5px !important;
}</PRE>}
<P>You can also use these stylesheets to change or do away with aspects of the user interface you don't like. The following rule, for example, shrinks the navigation buttons in the Modern theme:</pre>
<PRE>.toolbarbutton-menubutton-button &gt; .toolbarbutton-box,    <p>You can also use these stylesheets to change or do away with
     aspects of the user interface you don't like. The following
     rule, for example, shrinks the navigation buttons in the Modern
     theme:</p>
 <pre>
 .toolbarbutton-menubutton-button &gt; .toolbarbutton-box,
 .toolbarbutton-1 &gt; .toolbarbutton-box  .toolbarbutton-1 &gt; .toolbarbutton-box
 {  {
 max-width: 40px !important;  max-width: 40px !important;
 text-align: center !important;  text-align: center !important;
}</PRE>}
<P>Or, if you can think of the appropriate selectors, you can use <I>userContent.css</I> to change the way banner images are displayed (or not displayed), how basic text is presented, or where certain elements of a web page are positioned.</pre>
<H3><A NAME="77103"></A> Theme Security Restrictions</H3>    <p>Or, if you can think of the appropriate selectors, you can
<P>To prevent  <!--INDEX themes:security considerations -->  <!--INDEX security:themes --> the wholesale overriding of the basic XUL application,     use <i>userContent.css</i> to change the way banner images are
various restrictions are placed on themes. In other words, you can do some things in XUL that you cannot do in CSS. The two preinstalled themes in Mozilla, Modern, and Classic use technologies like XBL, JavaScript, and XPConnect to provide additional behavior to the application. They are considered full-blown packages, like entirely separate interfaces (see <A HREF="ch06.html#15291">Chapter 6</A> for a description the various types of packages and installations). When you install new themes, however, those themes do not have "script access" and have limited access to XBL bindings.    displayed (or not displayed), how basic text is presented, or
<P>Code in the <TT>&lt;implementation&gt;</TT> and <TT>&lt;handler&gt;</TT> structures of an XBL binding are ignored, as are event handlers written in the <TT>&lt;content&gt;</TT> structures.    where certain elements of a web page are positioned.</p>
<P>You can write these XBL goodies into your theme if you want (or develop a theme out of the Modern theme, where there is plenty of XBL, and see them disabled in your theme when they were working in that preinstalled version), but Mozilla will not read or execute them. You can use XBL to define new XUL content for a widget by way of CSS, but unless you create an "evil skin," that content has to be simple XUL to show up in your theme at all.    <h3><a name="77103"></a> Theme Security Restrictions</h3>
<BLOCKQUOTE><HR><A NAME="62192"></A> Evil Skins    <p>To prevent <!--INDEX themes:security considerations --> 
<P>In the  <!--INDEX evil skins -->  <!--INDEX skins:evil skins --> Mozilla community, the term "evil skins" is sometimes used to describe skins with unlimited script access. An evil skin is a skin for which the security restrictions above do not apply. They can access the DOM of the web page and XUL content, use XPConnect to connect to the Mozilla services in XPCOM, or implement new application code in XBL widgets.    <!--INDEX security:themes --> the wholesale overriding of the
<P>Remember that when you develop skins for Mozilla and package them for installation as skins, the script part of your skins will be disabled.     basic XUL application, various restrictions are placed on
However, if you create a skin and then install it as a new package, your skin will not be as limited, and you will have full access to XBL, XPConnect, and the script. To see how to install an evil skin and other new packages in Mozilla, see <A HREF="ch06.html#15291">Chapter 6</A>.<HR></BLOCKQUOTE>    themes. In other words, you can do some things in XUL that you
    cannot do in CSS. The two preinstalled themes in Mozilla,
<HR>    Modern, and Classic use technologies like XBL, JavaScript, and
<HR><A NAME="290"></A><A HREF="#b290">[Back]</A>    XPConnect to provide additional behavior to the application.
<A NAME="77059"></A>    They are considered full-blown packages, like entirely separate
There are just a couple of exceptions to this rule.    interfaces (see <a href="ch06.html#15291">Chapter 6</a> for a
The    description the various types of packages and installations).
<I>content</I>    When you install new themes, however, those themes do not have
 directory of a package (typically the place where just the    "script access" and have limited access to XBL bindings.</p>
XUL and JS are stored) sometimes holds a file called    <p>Code in the <tt>&lt;implementation&gt;</tt> and
<I>xul.css</I>    <tt>&lt;handler&gt;</tt> structures of an XBL binding are
. This file    ignored, as are event handlers written in the
defines style information that is so fundamental to the way widgets are    <tt>&lt;content&gt;</tt> structures.</p>
rendered    <p>You can write these XBL goodies into your theme if you want
more fundamental, even, then    (or develop a theme out of the Modern theme, where there is
<I>global.css</I>    plenty of XBL, and see them disabled in your theme when they
 and its    were working in that preinstalled version), but Mozilla will
siblings    not read or execute them. You can use XBL to define new XUL
that it is set apart from the regular skin and put in with the    content for a widget by way of CSS, but unless you create an
content, where it is loaded automatically. It's not a good idea to edit    "evil skin," that content has to be simple XUL to show up in
this file.    your theme at all.</p>
<HR><BR><BR>    <blockquote>
File a <a href="http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a> for chapter 4.      <hr>
<!-- ?php require(NOTES); ? -->      <a name="62192"></a> Evil Skins 
<?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch04'; require(NOTES); ?>      <p>In the <!--INDEX evil skins --> 
</BODY>      <!--INDEX skins:evil skins --> Mozilla community, the term
</HTML>      "evil skins" is sometimes used to describe skins with
       unlimited script access. An evil skin is a skin for which the
       security restrictions above do not apply. They can access the
       DOM of the web page and XUL content, use XPConnect to connect
       to the Mozilla services in XPCOM, or implement new
       application code in XBL widgets.</p>
       <p>Remember that when you develop skins for Mozilla and
       package them for installation as skins, the script part of
       your skins will be disabled. However, if you create a skin
       and then install it as a new package, your skin will not be
       as limited, and you will have full access to XBL, XPConnect,
       and the script. To see how to install an evil skin and other
       new packages in Mozilla, see <a href=
       "ch06.html#15291">Chapter 6</a>.</p>
       <hr>
     </blockquote>
     <hr>
     <hr>
     <a name="290"></a><a href="#b290">[Back]</a> <a name=
     "77059"></a> There are just a couple of exceptions to this
     rule. The <i>content</i> directory of a package (typically the
     place where just the XUL and JS are stored) sometimes holds a
     file called <i>xul.css</i> . This file defines style
     information that is so fundamental to the way widgets are
     rendered more fundamental, even, then <i>global.css</i> and its
     siblings that it is set apart from the regular skin and put in
     with the content, where it is loaded automatically. It's not a
     good idea to edit this file. 
     <hr>
     <br>
     <br>
     File a <a href=
     "http://mozdev.org/bugs/enter_bug.cgi?product=books">Bug</a>
     for chapter 4. <!-- ?php require(NOTES); ? -->
     <?php $post_to_list=NO; $author='reviewers@mozdev.org'; $target_page='ch04'; require(NOTES); ?>

Removed from v.1.7  
changed lines
  Added in v.1.8


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>