Opera Show Documentation: Stylesheets

This page will try to give a brief overview of several aspects of the default Opera Show stylesheets that deserve attention. This is not an Opera Show tutorial, but documentation of some key style rules. For brevity not all style declarations are included, but only the more relevant ones. Complete stylesheets are found in the documents created by the Opera Show Generator.

Stylesheet Info

The following lines should be places at the top of each stylesheet, so that editors can determine whether a known or unknown stylesheet is being used, when the file is imported.

/* Stylesheet info 			*/
/* Name: Opera				*/
/* Author: Opera Software 		*/

Slidecounter

For various presentational purposes it is important to have a slide counter, which is increased for each slide. It can be added with the following CSS

div.slide { 
	counter-increment: slide; 
	}
.slide:before { 
	content: "Slide " counter(slide); 
	float:right; 
	}

This counter will be used in several of the examples in this document.

Layout elements

All layout elements are contained inside the <div class="layout">. Often these elements are only needed in specific mediatypes and should be hidden in others. To achieve this, all the children of the .layout are initially set to display:none; for all mediatypes.

.layout > * { display: none; }

Another display value can be set for a specific mediatype.

Media Queries

Opera 7 has experimental support for CSS3 Media Queries. These are used to set the base font-size in projection mode, depending on your screen resolution.

/* projection styles */
/* basic fontsize is roughly screenwidth/50 */
@media projection and (max-device-width:640px) { body { font-size: 12px; }}
@media projection and (min-device-width:640px) { body { font-size: 13px; }}
@media projection and (min-device-width:800px) { body { font-size: 16px; }}
@media projection and (min-device-width:1024px) { body { font-size: 22px; }}
@media projection and (min-device-width:1280px) { body { font-size: 26px; }}
@media projection and (min-device-width:1600px) { body { font-size: 32px; }}

One could also choose to determine and set the base font-size with JavaScript.

@media projection styles

There are many styles which are only applied during projection mode.

Preliminaries

By removing the paddings and margins from body, html, .presentation, you make sure that you don't run into unexpected margins/paddings on the first and last slide. The 100% on the height makes it possible to absolutely position elements with respect to the screen, as will be discussed in the slide numbering section.

html, body, .presentation { height: 100%; margin: 0px; padding: 0px; }
div.notes, div.handout { display:none; }

The actual Opera Show is a result of the page-break-after: always; rule. One could also decide to use page-break-before to achieve a similar effect, but the JavaScript addons check for page-break-after in order to work, so authors are adviced to use the latter.

A very important style rule is the max-height rule, in combination with the overflow. This rule makes sure that the slide fits on the screen and that PageDown will always take you to the next slide, even when there is more content than fits on the screen.

/* slide is given a max-height so that pagedown will still work ...
when there's too much content to fit on screen */

div.slide { 
	page-break-after: always; 
	margin: 3em 3em 0em 3em; 
	padding: 0.2em 1em; 
	min-height: 50%; 
	max-height:80%; 
	overflow: visible; 
}

It is also very important NOT to specify a bottom-margin on the .slide because due to a bug, they will 'leak' through onto the next page, which may yield strange results.

Slide numbering

It is also possible to have automatic slide numbering in full-screen. This is done with CSS 2.1 Generated Content, but there are several pitfalls that authors have to be aware of!

Make sure that position:absolute; is used, not position:fixed; because with the latter, all slidecounters will be stacked on top of eachother, resulting in an unreadable mess. The position:absolute will be positioned with respect to the nearest positioned ancestor and if there is none, it will be positioned with respect to the initial containing block. That is why we set height:100% on the html, body, .presentation! That allows us to position from the bottom.

/* use position absolute for the slide counter, not fixed! ...
Otherwise they'll all get stacked on top of eachother */
/* make sure that the .slide or any of its ancestors do not have a ...
position: value set, because then the viewport will no longer be used */

div.slide:after { 
	content: "Slide " counter(slide); 
	position: absolute; 
	z-index:3; 
	bottom: 0px; 
	width: 50%; 
	text-align:right; 
	margin-left:-2em; 
	line-height: 2em; 
	display:block; 
	font-size: 0.5em; 
}
div.presentation:after { 
	content: "\00A0 of "counter(slide); 
	position: fixed; 
	z-index:3; 
	bottom: 0px; 
	right:0px; 
	width: 50%; 
	text-align:left; 
	line-height: 2em; 
	display:block; 
	font-size: 0.5em; 
}

Positioning layout elements

Remember that all the layout elements have display:none; set to them, so in order to make them visible in projection mode, you have to explicitly set another value for display. The .layout must be placed before the classname of the element, to achieve the needed specificity to override the .layout > * rule described earlier.

When positioning the .topleft, .topright etc. you have to take into account the stacking order and if necessary arrange them with appropriate z-index. In the example stylesheets for instance, only the .topleft and .bottomleft have a background-color and the other two are transparent to prevent overlapping of elements. Also realize that if you put images inside these elements (e.g. logo) the height will expand. That is why they are position:fixed to take them out of the flow.

/* only topleft and topright have background-color, to prevent obscuring */
.layout .topleft { 
	position: fixed; 
	top: 0px; 
	left: 0px; 
	line-height: 1.5em; 
	width: 100%; 
	background-color:#c00; 
	border-bottom: 0.1em white solid; 
	color: #FFD100;
	display:block;
	}
.layout .topright { 
	z-index:2; 
	position: fixed; 
	top: 0px; 
	right: 0px; 
	background-color: transparent; 
	line-height: 1.5em; 
	width: 50%; 
	text-align: right; 
	color: #FFD100;
	display:block;
	}
.layout .bottomleft { display:block; }
.layout .bottomright { display:block; }

.topleft img { position:fixed; top: 0px; left: 0px; max-height:25%;}

Also take note of the max-height of the image, that prevents the logo from becoming too big on low-resolution projectors.

@media print styles

To make handy handouts of your presentation, on which people can make notes during the presentation, you can employ all the power that CSS has to offer :)

NB: make sure that you have "Print page background" enabled under "print options" otherwise it will look ugly.

Page-breaks

You can set the UA to avoid putting page-breaks inside your slides by using page-break-inside:avoid;.

@media print { 
.slide { 
	width: 70%; 
	border: 1px black solid; 
	page-break-inside: avoid; 
	position:relative; 
	min-height:200px;
}

The limited width of the slides and notes creates a white column to the right of your slides, where people can write comments and questions.

Generated Content

With Generated Content you can spice up your stylesheet even more! Adding slide numbers is trivial, because we already introduced a slide counter earlier.

.slide:before { 
	content: "Slide " counter(slide); 
	float:right; 
}

Things get interesting when we use CSS to retrieve all the meta information from the document and print it at the top. That way you get a presentation summary at the top of the document, with author name, presenation title, etc.!

/* following code extracts all the relevant metadata ...
and shows it with Generated Content */
/* code could have been saved by using CSS3 content, ...
but this is compatible with Mozilla */

head { 
	display: block; 
	border: 1px black solid; 
	}
head:before {
	content: "Presentation information"; 
	display:block; 
	}
title { 
	display: block; 
	padding: 0px; 
	margin: 0px; 
	}
title:before { 
	content: "Title: "; 
	font-weight: bold;
	}
meta { 
	display:block; 
	}
meta:before { 
	text-transform: capitalize; 
	font-weight:bold;
	}
meta[name="presdate"]:after, /* add all relevant metatags here */ { 
	content: ": " attr(content); 
	}
meta[name="presdate"]:after, /* add all relevant metatags here */ { 
 	content: attr(name);  
	}
/* this shows the target of links even when printed, so people can visit the site later if they're interested */
a[href]:after { 
	content: " [url: " attr(href) "]"; font-style:italic;
	}
.presentation:before { 
	float:right; 
	width: 25%; 
	content: "Add notes in this column"; 
	border-bottom: 1px black solid; 
	}

If you want to have some text repeated on each page, you can use position:fixed. In the example stylesheets this is done on Generated Content.

.presentation:after { 
   position:fixed; 
	right: 0px; 
	bottom: 3cm; 
	width: 25%; 
	content: "Add notes in this column"; 
	border-top: 1px black solid; 
}

Page margins

If you want to set certain page margins, you can do that with CSS as well. However take into account that most printers have certain default margins outside which they cannot print, so setting your page-margins too small may cause information not to be printed correctly.

@page { 
	margin-top: 1cm; 
	margin-bottom: 1cm; 
	margin-left: auto; 
	margin-right: auto; 
	}