Skip to content

Layouts

A document's body is a box on the screen. Position it, give it a size, and lay its contents out with block and flex layout.

A HUD in a corner

<rml>
<head>
  <link type="text/rcss" href="/sagl/ui/theme/base.rcss"/>
  <style>
    body { position: absolute; right: 24dp; top: 210dp; width: 220dp; }
    .panel { display: block; width: 192dp; padding: 10dp 14dp; }
    .title { display: block; font-family: sa-menu; font-size: 16dp; color: #2fb3a0;
             font-effect: outline(2dp #000000); margin-bottom: 4dp; }
    .team { display: flex; flex-direction: row; justify-content: space-between; }
    .cops { color: #6a8cff; }
    .robbers { color: #ff4a4a; }
  </style>
</head>
<body>
  <div class="panel">
    <span class="title">Round 3 - 04:12</span>
    <div class="team"><span class="cops">Cops</span><span id="cops">12</span></div>
    <div class="team"><span class="robbers">Robbers</span><span id="robbers">9</span></div>
  </div>
</body>
</rml>

That HUD in game

Open it with { input: false } so the player keeps playing.

Keep clear of the game's HUD

The game draws its clock, weapon, health and money top right, and the radar bottom left. Start corner HUDs below about top: 200dp on the right.

Give panels a width

A .panel inside an absolutely positioned body may shrink to nothing and lose its background. Give it display: block and a width.

A centred dialog

body { width: 100%; height: 100%; background-color: #00000060; }  /* dims the game */
.panel {
  position: absolute;
  left: 50%; top: 45%;
  width: 480dp;
  margin-left: -240dp;
  transform: translateY(-50%);
}

Open it with input (the default) so the cursor shows and Esc closes it. For yes/no questions, prefer sagl.ui.messageBox().

A full-screen menu

Like SAGL's pause menu: header, a page that takes the space left, and a row of options at the bottom. Flexbox does it:

body { width: 100%; height: 100%; }
.menu {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  box-sizing: border-box;
  padding: 28dp 40dp 20dp 40dp;
  background-color: #000000b0;
  display: flex; flex-direction: column;
}
.header  { flex: 0 0 auto; }
.content { flex: 1 1 0; position: relative; overflow-y: auto; }
.options {
  flex: 0 0 auto;
  display: flex; flex-direction: row; flex-wrap: wrap; justify-content: center;
}

flex-wrap: wrap puts options that don't fit on a second row.

Pause menu pages

A page's RML is the body of a page inside the pause menu: no <rml> or <head>, just content. It fills the area between the menu's header and its options row (scrolling if it's taller), and the pause menu's styles apply:

Class
h2.first A heading with no space above (the first on the page).
.subtitle, .note Light blue text.
.list .item Selectable rows.
.row, .label, .control Settings-style rows: a label on the left, a control on the right.
button Menu items.
.status A status line.
<h2 class="first">Garage</h2>
<div class="row"><span class="label">Colour</span>
  <div class="control"><input type="range" id="colour" min="0" max="126"/></div></div>
<div class="row"><span class="label">Neon</span>
  <div class="control"><input type="checkbox" id="neon"/></div></div>
<button id="buy">Buy - $5,000</button>

Sizes and units

  • dp scales with the screen's height: 1dp is 1px at 800 pixels high, 0.9px at 720p, 1.35px at 1080p (never below 0.7px). Use it for everything, and layouts keep their proportions.
  • % of the parent works for widths, heights and positions.
  • em follows the font size.

Images

<img src="icons/pistol.png" width="32dp" height="32dp"/>

Give images both a width and a height (or one and let the other follow). For a background that covers an element, use a decorator:

.banner { height: 120dp; decorator: image(banner.jpg cover); }
.fade   { decorator: vertical-gradient(#00000000 #000000e0); }

Scrolling

overflow-y: auto on a box with a fixed height scrolls it. The theme styles scrollbars thinly; restyle scrollbarvertical, slidertrack and sliderbar to change them.

Keyboard and gamepad

Documents with input can be driven with arrow keys, Enter and a gamepad. Elements need tab-index: auto and nav: auto (the theme gives them to buttons, list items and inputs) to take focus; :focus-visible styles the focused one.