[See also: http://my.opera.com/customize/skins/specs/]
Use at own risk etc etc. This file is probably full of typos.
Please consider spending efforts on creating a few really good skins instead of many
quick and half-finished bad ones..
The current state of the skin support in Opera 7 is admittedly a bit "It can do
what we needed for the standard skin, and not much more". However, there should
be more than enough possibilities to create varied and high quality skins.
There are plans to give more credit to those that spend time and effort on
creating good Opera skins. Stay tuned to my.opera.com for more on this later.
Please feel free to spread this file around. There will probably appear some
better looking documention in html format later.. but I'm too lazy to do that
An Opera 7 skin file is a zipped file with extension .zip that contains a "skin.ini" file at root level and a bunch of images making up the skin.
The "skin.ini" file contains the whole skin specification. All other files in the zip file are pointed to by the specification in "skin.ini".
Default install of Opera 7 contains a "standard.zip" and "windows.zip", standard being the default skin and windows being a more lightweight classic windows look skin.
Even when selecting a different skin, the standard skin acts as a fallback when the skin manager cannot find certain elements in the selected skin. That is why the windows skin only contains and replaces a few skin elements compared to the standard skin.
The "skin.ini" file is like other ".ini" files split into sections containing one or more "key = value" entries. It looks like this:
[Name of section]
Name of key = value
Name of another key = value
When reading the following documentation, you would benefit a lot by having the skin.ini file from standard.zip and windows.zip available to look at.
In any case, developing a skin will require some trial and error..
The [Info] section is normally placed first and should contain the following:
Name=name of skin
Author=name of author
Version should be 2, otherwise Opera 7 will reject the skin.
The [Options] section is normally placed after the info section and can contain the following:
Native Skin = 0 or 1
Only set this to 1 if you want Opera to draw controls to look nativly (to the system). Default is 0, so you would normally leave this option out. To be more specific, if you set this to 1, like the "windows" skin does, certain skin elements will be drawn by code that is built into Opera. This code uses the system's own functions for drawing controls and borders.
Pagebar max button width =
Pagebar min button width =
Use these to specify in pixels the min and max width of pagebar buttons. Normally, you would not specify this, so leave them out.
Fallback foreground = 0 or 1
Fallback background = 0 or 1
These options specify if Opera should fall back to the standard skin if a skin element of either foreground or background type was not found.
Typically Fallback foreground should be 1 and Fallback background should be 0. In other words that foreground elements like button images that the new skin does not have are fetched from standard, but that background images are not fetched (the look of the windows etc).
This is based on the assumption that most skins will not bother to replace all foreground images of a full skin, but will at least change all of the background.
The rest of Skin.ini is all about skin elements. Whenever Opera draws something, it draws a skin element, specified by a name. You can specify a skin element in 2 ways: the full method and the short method.
The full method means that you specify the skin element in its own section, like this:
[Name of skin element]
Or you specify it using the short method, in which case it's not its own section, but an entry under the [Images] section.
Name of skin element = ...data...
If you look at the skin.ini in standard.zip you will see that all toolbar button images etc. are specified under [Images], while skin elements that define the look of the windows are full sections.
The important thing to understand is that this is just for simplicity! From Opera's point of view there is no difference between a skin element for the Back button image and the skin element for the window background.
In other words, "Back" is specified under [Images], but it could just as well have been its own section, consisting of a complex 9-pieces setup of images, but since normally button images are just one image, it is specified under [Images] to avoid cluttering up the skin file!
So the short method, by putting the skin element as an entry under [Images], is used when the skin element only consist of one image and doesn't need the flexibility of its own full element section.
There is also another short method, putting the element under the [Boxes] section. This is just like the [Images] section used for simplicity in certain cases. More on this later.
When a skin element is defined as a full section, it will be like this:
[Name of skin element]
Where data is one or more "key = value" entries.
Below follows the available keys and the meaning of their values. All keys have a default value, and just leave the key out if you just desire its default value.
Type = Image or Box or BoxTile. Default is Image.
Image as type is rarely used for a full-section defined element, since Image type is for skin elements with only one image, and in that case you would instead list the element using the short method, under the [Images] section as explained previously. If you do use this type, its single image should be specified using the "Tile Center" key (see below), and you must also specify its Width and Height (see below).
BoxTile is the most used one. For a BoxTile, you specify up to 9 images using the "Tile" and "Corner" keys described below. These 9 images will be used to draw the full skin element. If one or more is missing, Opera will still draw whatever makes sense out of those images available. For example, a typical Page Bar tab will often only need 6 images.
Tile Center = center.png Tile Left = left.png Tile Top = top.png Tile Bottom = bottom.png Tile Right = right.png Corner Topleft = topleft.png Corner Topright = topright.png Corner Bottomleft = bottomleft.png Corner Bottomright = bottomright.png
These are the 9 keys specifying the various images that make up a BoxTile or Box. The values on the right are filenames of the images contained somewhere in the zip file.
How these images make up a full element should be obvious from the name of their keys...
IMPORTANT! Opera will only load a specific image file once and only once, no matter how many places in the skin.ini file the image is used. So don't worry about using a certain "topleft.png" image everywhere, it will be only loaded once and not slow down loading or waste memory. Also, each skin element is loaded on demand the first time it is drawn, to minimize Opera startup time and memory usage.
""Child0"" = Name of another skin element Child1 = Yet Another skin element Child2 = Yet Another skin element ...
In some cases, those 9 images of a BoxTile won't be enough to draw a certain skin element. To solve this, you can specify any number of children that will be drawn afterwards, on top of the skin element. A child is simply another skin element, which could be of any type. Using images with alpha channel, you could use this to blend images together, but have in mind that this could quickly slow down drawing of your skin. You are free to name the child elements whatever you want, Opera will simply draw whatever element in the skin.ini file it can find with that name, just like with any other skin elements.
IMPORTANT! If using children, never create a "cycle" (ie. where a child is parent of itself somehow). Opera would not detect such a cycle... and crash.. :)
Child elements aren't often used, but sometimes they come in handy. See the advanced examples later.
Margin Left = 0 Margin Top = 0 Margin Bottom = 0 Margin Right = 0 Padding Left = 2 Padding Top = 2 Padding Right = 2 Padding Bottom = 2
These keys specify margins and padding for a certain element. 0 is default for various margins, 2 is default for the padding.
Currently, it varies a bit what Opera uses these values for. For example, specifying padding for the [Window Skin] element will NOT create padding around the interior of the window.
However, they will work where they are most needed: toolbars, buttons and their images.
For toolbar skin elements, like "Mainbar Skin", margin is not used, but padding specifies spacing between the edge of the toolbar and its content.
For button skin elements, like "Pagebar Button Skin", margins are used to create spacing around the button, while padding is used to create spacing inside the button, around its content.
For button images, like "Back", margins are used for spacing around the image.
Also, for all skin elements, if they have any children, those child elements will be drawn after the parent's padding AND the child's margin has been used to indent the drawing area.
Width = Height =
These keys are rarely used. The reason is that it varies if it has any meaning to define that a skin element has a certain width and height. Take the [Window Skin], it will have the "width" and "height" of whatever size the window has right now, so it has no meaning to define them in the skin file.
However images inside buttons do indeed need to have Width and Height defined, since they are used to find out how much room a toolbar needs. But since almost all such button images are specified using the short method inside the [Images] section, where Opera will default the width and height of the skin element to be the actual width and height of the image file, you fill find that there is few places where the Width and Height keys are needed.
Text Bold = 0 or 1 Text Color = #rrggbb Text Underline = 0 or 1
These keys are used to specify how text should be drawn on top of this skin element. You would normally not specify these unless you want to force a certain style.
Text Zoom = 0 or 1
This is a special option that only has meaning for button skin elements and even when set to 1, it will only take effect if the buttons are set to "Image and text below", the system supports text zooming (windows 2000 and newer), and special effects are enabled. See advanced examples later.
Color = #rrggbb
This key specifies a background color that is drawn before any image tiles of this element are drawn.
Colorize = 0 or 1
This key specifies if this skin element should be affected by any Color Scheme selected by the user. NOTE! Default is 1!
Blend = 0 to 100, where 100 is default.
This key specifies the blending that is used to draw a skin element for hover state. In other words, it has only meaning when specified for a ".hover" skin element. (see blow for state explaination). If a hover element exist, that element is drawn on top of the same non-hover element, with the amount of blending specified.
Clone = some other skin element
Clone is used to avoid having to retype the exact same data for many similiar skin elements. You can still specify various keys, they will override the ones from the one you cloned.
Note that clone is just used to simplify skin.ini, not to avoid loading images more than once since this is never done anyway.
When a skin element is of type Image, the easiest thing to do is to specify it using one line of text under the [Images] section, like this:
[Images] Back = small_buttons/general_back.png Forward = small_buttons/general_forward.png
You can also specify a few more things about the skin element without having to use its own section:
Name of element = filename, colorize, margin left, margin top, margin right, margin bottom
Or as an example:
Back = back.png, 1, 2, 2, 2, 2
Again, this is just used for simplicity, since some skins would like various button images to adhere to the color scheme and have non-standard margins, and still avoid having to use the full section method.
IMPORTANT! While Colorize was default to 1 (on) when using the full method, the default for skin elements defined in [Images] is 0 (off). Yet again, this is for simplicity, since most icons etc specified under [Images] should not be affected by the color scheme, while all background elements (usually the ones using the full section method) should be affected.
Skin element of Box type was explained earlier, and sometimes you want to specify a Box that only include one image instead of 9, and in that case you could skip using the full section method and instead list it under the [Boxes] section.
This is basicly like the [Images] section method, but there is one important difference:
Elements listed under [Images] will end up being stretched if drawn to a size that is different than their original size, but elements listed under [Boxes] will simply be centered.
Like described earlier, every skin element has a name which is used to look it up in the skin.ini file. Typical examples are "Window Skin" used for drawing window backgrounds and "Back" used for drawing the back button image.
In addition to just its name, a skin element can have certain type and state modifiers. To be more precise, a skin element can optionally have one type modifier and/or one or more state modifiers.
To define a skin element that has a certain type and state, you append the name of the type and states at the end of the skin element name, seperated by periods. It could look like this:
[Images] Back.large = large/back.png ... [Pagebar Button Skin.hover] ..data..
Notice the .large and .hover extensions to the skin element names.
The .large is an example of a type modifier, while .hover is an example of a state modifier. The type modifier should come before any state modifiers.
When Opera draws a skin element, it tries to look for the named skin element that has the type and state that matches what kind of type and state the element has internally. If it doesn't exist, Opera falls back to the closest match, which might be the base skin element without any type or state modifiers.
The types currently available are:
This one is used for button images when the user has selected "large images" for the toolbars.
.left or .top or .bottom or .right
These ones are used for toolbar skin elements (like "Mainbar Skin"). In other words, you could specify different skin elements for various toolbars, depending on their position.
The state modifiers currently available are (with examples):
.attention - page bar buttons when page is done loading .disabled - any disabled button or other ui widget .hover - when mouse hovers a button (see the comment of the Blend key earlier) .selected - when a button or other ui widget is considered selected .pressed - when a button is pressed .open - when something is considered open, like a folder icon.
Currently it varies a lot if it works or makes sense to define certain states for a skin element. One would for example like the mail button to have attention when new mail arrives, but this doesn't work in 7.0 final. Also, defining Window Skin.hover won't work.. Opera won't redraw whole of the window just because the mouse cursor hovers it..
For disabled state, you normally don't have to specify anything, because Opera will blend the non-disabled skin element into the background anyway, creating a disabled look for it.
In the same way, Opera will add a glow to button images when they are hovered. This cannot be changed in Opera 7.0 final, but more control over this is planned.
I sugged you look at the standard skin.ini file and try things out.
Here's two examples that show some sort of advanced skin element definitions.
1. The main bar button text zoom effect taken from standard.zip.
Notice these: (also look in skin.ini)
[Toolbar Button Skin.large] Type = BoxTile Text Zoom = 1 [Toolbar Button Skin.large.pressed] Type = BoxTile Padding Left = 3 Padding Top = 3 Padding Right = 1 Padding Bottom = 1 [Images] ... Back.large = 2nice/back.png, 1, 0, 0, 0, -13 Forward.large = 2nice/forward.png, 1, 0, 0, 0, -13 ...
The .large means that this is only for toolbars that have "large images" set, and since it has no tiles or corners defined, the button has no graphics at all really, except the action image inside it, which is another skin element and has nothing to do with the button itself really.
Since the first one specifies no padding, the defaults of 2 is used. The ".pressed" one has slightly different padding that causes the image to be drawn one pixel down and to the right, creating a typical pressed effect.
Back.large shows how the Back action image has a specific image made for a toolbar using large images, and the options behind the filename specifies that this image should be affected by the color scheme.
The last option behind the filname specifies a bottom padding of -13, and this together with the Text Zoom option used for the toolbar button creates the clever effect of the text zooming onto the bottom part of the back image. The back image has been designed for this, having a reflection as part of the image at the bottom.
It seems like a few skin authors didn't understand how this trick was created, which meant that a few skin have be created where the text end up on top of the actual button image. So remember to remove this negative padding if your design isn't made for it.
2. Edit field child skin element example taken from standard.zip
Look at these:
[Edit Skin] Type = BoxTile Margin Left = 2 Margin Top = 2 Margin Right = 2 Margin Bottom = 2 Padding Left = 2 Padding Top = 2 Padding Right = 2 Padding Bottom = 2 Tile Left = edit/left.png Tile Top = edit/top.png Tile Right = edit/right.png Tile Bottom = edit/bottom.png Corner Topleft = edit/topleft.png Corner Topright = edit/topright.png Corner Bottomright = edit/bottomright.png Corner Bottomleft = edit/bottomleft.png ""Child0"" = Edit Interior Skin [Edit Interior Skin] Color = Window
The Edit skin is a typical boxtile skin element, but notice these things:
Margins are set to 2 so that several search boxes on a toolbar beside eachother gets a little spacing.
Tile center is missing, so it wouldn't have any graphics inside it unless it wasn't for the Child0 key that points to a new skin element called Edit Interior Skin.
Since the edit/left.png etc. files have been designed to create a 2 pixel border for the Edit Skin, this will match the Padding which is set to 2 pixels and therefore the Edit Interior Skin child element will be drawn exactly within the borders.
The Edit Interior Skin includes only a single Color key that has the value Window. This is one of currently 2 supported "magic" values that can be used instead of defining a color using the #rrggbb value method.
Using the "Window" value causes Opera to use the system's defined color for window interiors. So this is how standard.zip, even though it ignores many system defined settings, at least adheres to edit field background color. The other value supported like this is "Window disabled".
The whole point of this example is the use of the Child0 key, because why isn't simply the Edit Skin element using "Color = Window" directly without any children? The reason is that then the whole background of the edit field would be filled with the Window color before the border tiles are drawn. Since the border tiles include alpha blending, the resulting image would be that borders would always blend and become shades of the interior color.
However, when using the Child0 element, since the interior is filled exactly inside the borders (because of the padding of 2 pixels), the borders are drawn and blended with whatever graphics that lies under the edit field. This has the desired effect that edit fields in web pages will have borders that are shades of the web page background and therefore look better.