Try an online XSL-FO class for free!
Additional Resources

Blocks and Inlines

In this lesson of the XML tutorial, you will learn...
  1. To format blocks of content.
  2. To format inline text.
  3. To work with lists.
  4. To work with whitespace.

Formatting Blocks

Although the output of our Winnie the Pooh story from the previous lesson is readable, it isn't formatted very nicely. In this section, we'll examine how we can use Cascading Style Sheet (CSS) properties to apply formatting to block FOs.

Box Model

Before we look at the specific attributes for formatting blocks, we'll take a look at a diagram that illustrates how width, border, padding and indent attributes all fit together.

The diagram shows two block elements in a block-container, which has a width of one inch. Each block contains a single word.

  • Padding is used to create one inch of space between the content and the edge of the box.
  • A one-centimeter border is then added to the edge of each block.
  • The bottom block is indented half an inch from the left.

Now let's look at some of the attributes of block FOs.

Border

By default, block FOs have no border; however, you can easily add one with the border-style and border-width attributes. You can also change the border color with the border-color attribute. As the table below shows, these properties can be applied to portions of the border as well through the use of more specific attributes.

Border Attributes
Attribute Values
border-width
  • <length> - A non-negative length
  • medium
  • thick
  • thin
border-top-width Same as border-width.
border-bottom-width Same as border-width.
border-left-width Same as border-width.
border-right-width Same as border-width.
border-color <color>
border-top-color <color>
border-bottom-color <color>
border-left-color <color>
border-right-color <color>
border-style
  • dashed
  • dotted
  • double
  • groove
  • hidden
  • inset
  • none
  • outset
  • ridge
  • solid
border-top-style Same as border-style.
border-bottom-style Same as border-style.
border-left-style Same as border-style.
border-right-style Same as border-style.

The diagrams below show the output of border-width and border-style attributes.

Space, Indent and Padding

Space attributes are used to separate FOs from other FOs on the page.

Indent attributes are used to indent FOs from the left and right borders of their containers.

Padding attributes are used to separate the content of FOs from the borders or edges of the block.

Space Attributes
Attribute Values
space-before <length> - A non-negative length
space-after <length> - A non-negative length

The values of space attributes are not cumulative. Notice that the space between the first two blocks is the same (10px) as the space between the second block, which wants 10px of space between it and the following block, and third block, which wants 10px of space between it and the preceding block.

Indent Attributes
Attribute Values
start-indent
  • <length> - A non-negative length
  • <percentage> - A percentage of the containing block
end-indent Same as start-indent

Indents can be specified in length (e.g, 30px) or percentage of the containing block (e.g, 50%).

Padding is specified in length and is used to create a buffer between the content and the border or edge of a block.

Padding Attributes
Attribute Values
padding <length> - A non-negative length
padding-top Same as padding
padding-bottom Same as padding
padding-left Same as padding
padding-right Same as padding

Background

Background attributes are used to set the background properties of a FO.

Background Attributes
Attribute Values
background-color color
background-image path to image
background-position-vertical
  • <length> - A non-negative length
  • <percentage> - n% from the top of the image is n% from the top of the containing area
  • top
  • center
  • bottom
background-position-horizontal
  • <length> - A non-negative length
  • <percentage> - n% from the left of the image is n% from the left of the containing area
  • left
  • center
  • right
background-repeat
  • no-repeat- doesn't tile
  • repeat-x - tiles horizontally
  • repeat-y - tiles vertically
  • repeat - tiles horizontally and vertically

A Formatting Example

The following example shows how some of these attributes can be applied to our "Hello-World" example.

Code Sample: BlocksAndInlines/Demos/HelloWorld2.fo

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

 <fo:layout-master-set>
  <fo:simple-page-master master-name="hello" page-height="11in" 
   page-width="8.5in" margin-top="1in" margin-bottom="1in" 
   margin-left="1in" margin-right="1in">
   <fo:region-body margin-top="1in" margin-bottom=".5in"/>
   <fo:region-before extent=".5in" background-color="silver"/>
   <fo:region-after extent=".5in" background-color="silver"/>
  </fo:simple-page-master>
 </fo:layout-master-set>
 
 <fo:page-sequence master-reference="hello">
  <fo:static-content flow-name="xsl-region-before">
   <fo:block font-size="24pt">Hello World!</fo:block>
  </fo:static-content>
  <fo:static-content flow-name="xsl-region-after">
   <fo:block font-size="24pt" text-align="right">
    Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
   </fo:block>
  </fo:static-content>
  <fo:flow flow-name="xsl-region-body"> 
   <fo:block font-size="36pt" font-weight="bold" text-align="center"
     space-before="2in" space-after="1in"
     start-indent="1.5in" end-indent="1.5in"
     border-color="red" border-style="solid" border-width="1mm"
     padding="1cm" background-color="#aaaaff">
    Hello World!
   </fo:block>
   <fo:block background-color="red">
    Goodbye!
   </fo:block>
   <fo:block id="last-page"/>
  </fo:flow>
 </fo:page-sequence>
 
</fo:root>
Code Explanation

The example above will render as follows.

Formatting Text

Font and text formatting can be applied at the block level with the following attributes.

Text Formatting Attributes
Attribute Values
font-family
  • font name
  • cursive
  • fantasy
  • monospace
  • sans-serif
  • serif
font-size
  • length
font-style
  • normal
  • italic
font-variant
  • normal
  • small-caps
font-weight
  • normal
  • bold
  • bolder
  • lighter
color
  • color
text-decoration
  • none
  • underline
  • overline
  • line-through

The example below shows some of these attributes in effect.

Code Sample: BlocksAndInlines/Demos/HelloWorld3.fo

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">

 <fo:layout-master-set>
  <fo:simple-page-master master-name="hello" page-height="11in" 
   page-width="8.5in" margin-top="1in" margin-bottom="1in" 
   margin-left="1in" margin-right="1in">
   <fo:region-body margin-top="1in" margin-bottom=".5in"/>
   <fo:region-before extent=".5in" background-color="silver"/>
   <fo:region-after extent=".5in" background-color="silver"/>
  </fo:simple-page-master>
 </fo:layout-master-set>
 
 <fo:page-sequence master-reference="hello">
  <fo:static-content flow-name="xsl-region-before">
   <fo:block font-size="24pt">Hello World!</fo:block>
  </fo:static-content>
  <fo:static-content flow-name="xsl-region-after">
   <fo:block font-size="24pt" text-align="right">
    Page <fo:page-number/> of <fo:page-number-citation ref-id="last-page"/>
   </fo:block>
  </fo:static-content>
  <fo:flow flow-name="xsl-region-body">
   <fo:block font-size="18pt" font-style="italic">
    Hello World!
   </fo:block>
   <fo:block font-size="18pt" font-family="monospace">
    Hello World!
   </fo:block>
   <fo:block font-size="18pt" font-weight="bold">
    Hello World!
   </fo:block>
   <fo:block font-size="18pt" font-variant="small-caps">
    Hello World!
   </fo:block>
   <fo:block font-size="18pt" text-decoration="line-through">
    Hello World!
   </fo:block>
   <fo:block id="last-page"/>
  </fo:flow>
 </fo:page-sequence>
 
</fo:root>
Code Explanation

The example above will render as follows. Note that only the top left quarter of the page is shown.

Inline Elements

An inline element is an element that does not cause a block to be created; for example, to apply formatting to text within a block. Inline elements are denoted with the inline tag. The following example illustrates the use of inline.

Code Sample: BlocksAndInlines/Demos/HelloWorldInline.fo

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
---- Code Omitted ----
<fo:page-sequence master-reference="hello"> <fo:static-content flow-name="xsl-region-before"> <fo:block font-size="24pt">Hello <fo:inline font-weight="bold" text-decoration="underline">World!</fo:inline> </fo:block> </fo:static-content>
---- Code Omitted ----
</fo:page-sequence> </fo:root>
Code Explanation

The example above will render as follows. Note that only the top left quarter of the page is shown.

The same text-formatting attributes shown for block FOs can be used for inline FOs.

Inheritance

Many properties are inherited from parent or ancestor FOs. For example, if you set the font-family in the page-sequence FO, all text in descendant FOs will be in that font family unless it is overridden by a closer ancestor. Generally, properties that you would think should inherit (e.g, font properties, colors, alignment, etc.) do inherit. The example below illustrates inheritance.

Code Sample: BlocksAndInlines/Demos/Inheritance.fo

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master master-name="page" page-height="11in" page-width="8.5in" margin="1in">
   <fo:region-body margin=".5in"/>
  </fo:simple-page-master>
 </fo:layout-master-set>
 <fo:page-sequence master-reference="page" font-size="18pt" font-weight="bold" start-indent="1cm">
  <fo:flow flow-name="xsl-region-body">
    <fo:block space-after=".5cm">
     Hello World!
    </fo:block>
    <fo:block space-after=".5cm" font-weight="normal" start-indent="0cm">
     Hello World!
    </fo:block>
    <fo:block>
     Hello <fo:inline font-weight="normal">World</fo:inline>!
    </fo:block>
  </fo:flow>
 </fo:page-sequence>
</fo:root>
Code Explanation

The output is shown below:

wrapper

In some cases, you will have large sections of a printed document that needs to be formatted differently from the main document. The wrapper FO is used to assign values to inheriting properties. It can be used in an inline or block element and does not contain its own direct content.

Code Sample: BlocksAndInlines/Demos/Wrapper.fo

<?xml version="1.0" encoding="utf-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master master-name="page" page-height="11in" page-width="8.5in" margin="1in">
   <fo:region-body margin=".5in"/>
  </fo:simple-page-master>
 </fo:layout-master-set>
 <fo:page-sequence master-reference="page" font-size="18pt" font-weight="bold" start-indent="1cm">
  <fo:flow flow-name="xsl-region-body">
    <fo:block space-after=".5cm">
     Hello World!
    </fo:block>
    <fo:wrapper text-decoration="underline">
     <fo:block space-after=".5cm" font-weight="normal" start-indent="0cm">
      Hello World!
     </fo:block>
     <fo:block>
      <fo:wrapper color="silver">Hello <fo:inline font-weight="normal">World</fo:inline></fo:wrapper>!
     </fo:block>
    </fo:wrapper>
  </fo:flow>
 </fo:page-sequence>
</fo:root>
Code Explanation

The output is shown below:

Creating Lists

Lists are created with the list-block FO, which contains one or more list-item FOs. Each list-item FO must contain two child FOs: list-item-label and list-item-body. The syntax is shown below.

Syntax
<fo:list-block start-indent="20pt">
 <fo:list-item>
  <fo:list-item-label end-indent="label-end()">
   <fo:block font-weight="bold">
    <!--bullet character or number-->
   </fo:block>
  </fo:list-item-label>
  <fo:list-item-body start-indent="body-start()">
   <fo:block>
    <!--list item content-->
   </fo:block>
  </fo:list-item-body>
 </fo:list-item>
 <fo:list-item>
  <fo:list-item-label end-indent="label-end()">
   <fo:block font-weight="bold">
    <!--bullet character or number-->
   </fo:block>
  </fo:list-item-label>
  <fo:list-item-body start-indent="body-start()">
   <fo:block>
    <!--list item content-->
   </fo:block>
  </fo:list-item-body>
 </fo:list-item>
</fo:list-block>

Below is a different view of how these tags are nested. The plus sign (+) indicates that list-item can be repeated.

list-block

The list-block FO contains the entire list. It can take many formatting attributes. A common one is start-indent, which can be used to indent the entire list. The list-block FO contains one or more list-item FOs.

list-item

The list-item FOs each contain two child FOs: list-item-label and list-item-body.

list-item-label

The list-item-label FO contains the symbol or character used to label the list; for example, a bullet or a number. It often takes the end-indent attribute with a value of label-end(), indicating that the label should not be indented more than its natural width.

character

The character FO is used to output a character using its character code. For example, the following would output a standard bullet.

<fo:character character="&#x2022;"/>

list-item-body

The list-item-body FO contains the actual content of the list item. It often takes the start-indent attribute with the value of body-start(), indicating that the body of the list item should start at the beginning of the list-item-body box.

Let's take a look at an example.

Code Sample: BlocksAndInlines/Demos/ShoppingList.fo

<?xml version="1.0" encoding="UTF-8"?>
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <fo:layout-master-set>
  <fo:simple-page-master master-name="List" page-height="11in" 
   page-width="8.5in" margin-top="1in" margin-bottom="1in" 
   margin-left="1in" margin-right="1in">
   <fo:region-body margin-top="1in" margin-bottom=".5in"/>
  </fo:simple-page-master>
 </fo:layout-master-set>
 <fo:page-sequence master-reference="List">
  <fo:flow flow-name="xsl-region-body">
   <fo:block space-after="24pt" font-weight="bold">
    Shopping List
   </fo:block>
   <fo:list-block start-indent="2in">
    <fo:list-item>
     <fo:list-item-label end-indent="label-end()">
      <fo:block font-weight="bold">
       <fo:character character="&#x2022;"/>
      </fo:block>
     </fo:list-item-label>
     <fo:list-item-body start-indent="body-start()">
      <fo:block>Pizza</fo:block>
     </fo:list-item-body>
    </fo:list-item>
    <fo:list-item>
     <fo:list-item-label end-indent="label-end()">
      <fo:block font-weight="bold">
       <fo:character character="&#x2022;"/>
      </fo:block>
     </fo:list-item-label>
     <fo:list-item-body start-indent="body-start()">
      <fo:block>Coke</fo:block>
     </fo:list-item-body>
    </fo:list-item>
   </fo:list-block>
  </fo:flow>
 </fo:page-sequence>
</fo:root>
Code Explanation

The example above will render as follows.

Exercise: Creating a List

Duration: 10 to 15 minutes.

In this exercise, you will practice transforming an XML document into a list for output as PDF.

  1. Open BlocksAndInlines/Exercises/Beatles.xml and examine the code.
  2. Open BlocksAndInlines/Exercises/Beatles.xsl for editing.
  3. Notice that the list block has already been started:
    <fo:list-block start-indent="20pt">
     <xsl:apply-templates/>
    </fo:list-block>
  4. At the bottom of the document is a template matching beatle.
  5. Fill in this template so that a list item is created for each Beatle.
  6. To test your solution, transform BlocksAndInlines/Exercises/Beatles.xml against BlocksAndInlines/Exercises/Beatles.xsl.

Code Sample: BlocksAndInlines/Exercises/Beatles.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
   xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <xsl:output method="xml" indent="yes"/>
 <xsl:template match="/beatles">
  <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
   <fo:layout-master-set>
    <fo:simple-page-master master-name="list" page-height="11in" 
     page-width="8.5in" margin-top=".5in" margin-bottom=".5in" 
     margin-left=".5in" margin-right=".5in">
     <fo:region-body margin-top="1in" margin-bottom="1in"/>
     <fo:region-before extent=".5in"/>
     <fo:region-after extent=".5in"/>
    </fo:simple-page-master>
   </fo:layout-master-set>
   <fo:page-sequence master-reference="list">
    <fo:static-content flow-name="xsl-region-before" text-align="center">
     <fo:block font-size="20pt" font-weight="bold">
      The Beatles
     </fo:block>
    </fo:static-content>
    <fo:flow flow-name="xsl-region-body">
     <fo:block space-after="24pt" font-weight="bold">
      The Beatles
     </fo:block>
     <fo:list-block start-indent="20pt">
      <xsl:apply-templates/>
     </fo:list-block>
    </fo:flow>
   </fo:page-sequence>
  </fo:root>
 </xsl:template>
 <xsl:template match="beatle">
 <!--
  Fill in this template so that a list item is created for each Beatle
 -->
 </xsl:template>
</xsl:stylesheet>

Note that lists can be nested. For an example see BlocksAndInlines/Demos/ShoppingListNested.fo.

Whitespace

There are five attributes that affect how whitespace is handled: linefeed-treatment, white-space-collapse, wrap-option, white-space-treatment, and white-space. The table below shows possible values for these attributes.

Whitespace Attributes
Attribute Values
linefeed-treatment
  • ignore
  • preserve
  • treat-as-space
  • treat-as-zero-width-space
white-space-collapse
  • false
  • true
wrap-option
  • no-wrap
  • wrap
white-space-treatment
  • ignore
  • preserve
  • ignore-if-before-linefeed
  • ignore-if-after-linefeed
  • ignore-if-surrounding-linefeed
white-space
  • normal
  • pre
  • nowrap

The white-space attribute is a shorthand for setting values for the other four attributes, as shown below.

  • normal
    • linefeed-treatment = "treat-as-space"
    • white-space-collapse = "true"
    • white-space-treatment = "ignore-if-surrounding-linefeed"
    • wrap-option = "wrap"
  • pre
    • linefeed-treatment = "preserve"
    • white-space-collapse = "false"
    • white-space-treatment = "preserve"
    • wrap-option = "no-wrap"
  • nowrap
    • linefeed-treatment = "treat-as-space"
    • white-space-collapse = "true"
    • white-space-treatment = "ignore-if-surrounding-linefeed"
    • wrap-option = "no-wrap"

The example below shows how these whitespace attributes can be used to maintain linefeeds in output while also allowing long lines to wrap.

Code Sample: BlocksAndInlines/Demos/Poem.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="Poem.xsl"?>
<Poem>
 <Title>Casey at the Bat</Title>
 <Author>Ernest Lawrence Thayer</Author>
 <Content>
The outlook wasn't brilliant for the Mudville nine that day:
The score stood four to two, with but one inning more to play,
And then when Cooney died at first, and Barrows did the same,
A pall-like silence fell upon the patrons of the game.

A straggling few got up to go in deep despair. The rest
Clung to that hope which springs eternal in the human breast;
They thought, "If only Casey could but get a whack at that—
We'd put up even money now, with Casey at the bat.

But Flynn preceded Casey, as did also Jimmy Blake,
And the former was a hoodoo, while the latter was a cake;
So upon that stricken multitude grim melancholy sat,
For there seemed but little chance of Casey getting to the bat.

But Flynn let drive a single, to the wonderment of all,
And Blake, the much despisèd, tore the cover off the ball;
And when the dust had lifted, and men saw what had occurred,
There was Jimmy safe at second and Flynn a-hugging third.

Then from five thousand throats and more there rose a lusty yell;
It rumbled through the valley, it rattled in the dell;
It pounded on the mountain and recoiled upon the flat,
For Casey, mighty Casey, was advancing to the bat.

There was ease in Casey's manner as he stepped into his place;
There was pride in Casey's bearing and a smile lit Casey's face.
And when, responding to the cheers, he lightly doffed his hat,
No stranger in the crowd could doubt 'twas Casey at the bat.

Ten thousand eyes were on him as he rubbed his hands with dirt;
Five thousand tongues applauded when he wiped them on his shirt;
Then while the writhing pitcher ground the ball into his hip,
Defiance flashed in Casey's eye, a sneer curled Casey's lip.

And now the leather-covered sphere came hurtling through the air,
And Casey stood a-watching it in haughty grandeur there.
Close by the sturdy batsman the ball unheeded sped—
"That ain't my style," said Casey. "Strike one!" the umpire said.

From the benches, black with people, there went up a muffled roar, 
Like the beating of the storm-waves on a stern and distant shore;
"Kill him! Kill the umpire!" shouted someone on the stand; 
And it's likely they'd have killed him had not Casey raised his hand.

With a smile of Christian charity great Casey's visage shone;
He stilled the rising tumult; he bade the game go on;
He signaled to the pitcher, and once more the dun sphere flew;
But Casey still ignored it and the umpire said, "Strike two!"

"Fraud!" cried the maddened thousands, and echo answered "Fraud!"
But one scornful look from Casey and the audience was awed.
They saw his face grow stern and cold, they saw his muscles strain,
And they knew that Casey wouldn't let that ball go by again.

The sneer is gone from Casey's lip, his teeth are clenched in hate,
He pounds with cruel violence his bat upon the plate;
And now the pitcher holds the ball, and now he lets it go,
And now the air is shattered by the force of Casey's blow.

Oh, somewhere in this favoured land the sun is shining bright,
The band is playing somewhere, and somewhere hearts are light;
And somewhere men are laughing, and somewhere children shout,
But there is no joy in Mudville—mighty Casey has struck out.
</Content>
</Poem>

Code Sample: BlocksAndInlines/Demos/Poem.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
 <xsl:output method="xml" indent="yes"/>
 
 <xsl:template match="/">
  <fo:root>
  
   <fo:layout-master-set>
   
    <fo:simple-page-master master-name="Poem" page-height="11in" page-width="8.5in" 
     margin="1in">
     <fo:region-body margin="1in"/>
    </fo:simple-page-master>
    
   </fo:layout-master-set>
   
   <fo:page-sequence master-reference="Poem">
    <fo:flow flow-name="xsl-region-body">
     <fo:block font-weight="bold" font-size="18pt" font-family="Times" id="{generate-id(Title)}" break-before="page">
      <xsl:value-of select="//Title"/>
     </fo:block>
     <fo:block font-size="16pt" font-style="italic" font-family="Times" 
      margin-bottom=".1in" margin-left=".2in">
       - <xsl:value-of select="//Author"/>
     </fo:block>
     <fo:block linefeed-treatment="preserve" white-space-collapse="false" wrap-option="wrap" white-space-treatment="preserve" font-size="16pt">
      <xsl:value-of select="//Content"/>
     </fo:block>
    </fo:flow>
   </fo:page-sequence>
   
  </fo:root>
 </xsl:template>
 
</xsl:stylesheet>

Blocks and Inlines Conclusion

In this lesson of the XML tutorial, you have learned the basic building blocks of XSL-FO, including block FOs, inline FOs, and list-block FOs. You have also learned how to format these blocks with formatting and whitespace attributes.

To continue to learn XML go to the top of this page and click on the next lesson in this XML Tutorial's Table of Contents.

Use of http://www.learn-xsl-fo-tutorial.com (Website) implies agreement to the following:

Copyright Information

All pages and graphics on Website are the property of Webucator, Inc. unless otherwise specified.

None of the content on Website may be redistributed or reproduced in any way, shape, or form without written permission from Webucator, Inc.

No Printing or saving of pages or content on Website

This content may not be printed or saved. It is for online use only.


Linking to Website

You may link to any of the pages on Website; however, you may not include the content in a frame or iframe without written permission from Webucator, Inc.


Warranties

Website is provided without warranty of any kind. There are no guarantees that use of the site will not be subject to interruptions. All direct or indirect risk related to use of the site is borne entirely by the user. All code and explanations provided on this site are provided without warranties to correctness, performance, fitness, merchantability, and/or any other warranty (whether expressed or implied).


For individual private use only

You agree not to use this online manual to deliver or receive training. If you are delivering or attending a class that is making use of this online manual, you are in violation of our terms of service. Please report any abuse to courseware@webucator.com. If you would like to deliver or receive training using this manual, please fill out the form at http://www.webucator.com/Contact.cfm