Home

Surfaces

The surface, which is associated with an HTML <div>, is the primary type of renderable in Famo.us.

There are several kinds of surfaces associated with various HTML tags.

All surfaces can take in arbitrary HTML content and CSS styling. Famo.us is completely agnostic to what you do within a surface — whether it’s rendered from a template, or used within an MVC platform to bind data to its content.

However, if you want to independently animate a chunk of HTML, or bind DOM listeners that interact with the rest of your app, we suggest you encapsulate that inside a surface. A surface’s content is reserved for HTML that is static — or at least that which doesn’t update often.

(Note: Surfaces are the atomic renderable unit in Famo.us, but we also support more complex composited renderables called views.)

Our first surface

Let’s use a surface to create the simplest possible Famo.us application: a box with some text. You can think of a surface as a rectangle that can contain formatted content. We’ll set our first surface’s content to the text string "Hello world!".

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group surface1
var Engine = famous.core.Engine;
var Surface = famous.core.Surface;

var mainContext = Engine.createContext();

var firstSurface = new Surface({
  content: 'Hello world!'
});

mainContext.add(firstSurface);
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group surface1
// @famous-block-filename en.md
// @famous-block-option textPanelActive true
// @famous-block-option pictureInPicture true
# Hello Surface!

Here, we create the simplest possible surface: just some text, no formatting, no background color, no frills.

We haven't set the size of this surface (more on that later), so it expands to fill the size of the context. By default, its background color is transparent.

Adding content to a surface

The content of a surface can include more than just plain text. Surfaces can contain mixed content, marked up with HTML. You can put formatted text, inline images — even <div> elements — inside surfaces. Anything you can put into an HTML <div> you can put inside of a surface.

There are two ways to set the content of a surface:

Here’s an example that shows both techniques:

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var surface = famous.core.Surface;

var mainContext = Engine.createContext();

// You can put HTML tags in the content.
var firstSurface = new surface({
  content: '<em>Hello</em> <strong>world</strong>!'
});

// This *overwrites* the content we set above.
firstSurface.setContent('<h1>Hello world!</h1>');

mainContext.add(firstSurface);

Styling a surface

Styling a surface in Famo.us is simple, too. When we instantiate a surface, we can add a properties object that contains style information. Writing properties is similar to writing CSS style rules, except the style properties are written using camel-case instead of with dashes. (For example, we would write background-color as backgroundColor.)

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
var Engine = famous.core.Engine;
var surface = famous.core.Surface;

var mainContext = Engine.createContext();

// The same surface, with properties added.
var firstSurface = new surface({
  content: 'hello world',
  properties: {
    color: 'white',
    textAlign: 'center',
    backgroundColor: '#fa5c4f'
  }
});

mainContext.add(firstSurface);

Sizing surfaces

By default, surfaces inherit the size of the context they are displayed in. If you want a surface to be a certain size, you need to set it explicitly, using the size property in the constructor options.

The size option takes an array of two values. Normally, you would set these values to numbers that represent the size of the surface in pixels. But you can also use the value undefined and/or the value true to size the surface relative to the surface’s context, or to its own content, respectively.

You can combine true and undefined size with numeric values if you want to get absolute sizing in one dimension and relative sizing in another. For example, [undefined, 200] would give you a surface whose width expands to the size of its parent, but whose height is exactly 200 pixels.

// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group surface2
// @famous-block-option textPanelActive true
var Engine = famous.core.Engine;
var surface = famous.core.Surface;

var mainContext = Engine.createContext();

var firstSurface = new surface({
  size: [200, 400],
  content: 'Hello world!',
  properties: {
    color: 'white',
    textAlign: 'center',
    backgroundColor: '#fa5c4f'
  }
});

mainContext.add(firstSurface);
// @famous-block
// @famous-block-option preset famous-0.3.0-globals
// @famous-block-group surface2
// @famous-block-filename en.md
# All About Size

Number sizes equate to pixels, `undefined` equates to "expand to fill the container," and `true` equates to "collapse down to my content."

Try changing the value `200` to the value `undefined` and watch what happens. Next, try changing it to `true`. Note the difference!

ContainerSurface

There’s one other special surface type to mention, called a ContainerSurface, which is associated with a <div> that can nest one or more surfacecs within it. ContainerSurface is used primarily for clipping when overflow: hidden is set as a CSS property. A container surface will enforce the following properties on all the surfaces it contains:

Container surfaces should be used sparingly, since they actually create a new Famo.us context inside the existing one, potentially causing performance issues with 3D animations due to the extra layer of DOM nesting.

FormContainerSurface

FormContainerSurface is just like a ContainerSurface, except it is associated with a <form> element in the DOM instead of a plain <div>.

Next: Modifiers »