Layouts: How Things Get Positioned
Here's the one idea that, once it lands, makes Ext JS layouts stop fighting you: you do not size things with CSS. The parent's layout sizes its children.
Coming from the web, that's backwards. Normally you slap width: 50% on a div and you're done. In Ext JS, you can set width and height on a component and still watch it render at zero pixels — or vanish entirely — because a container doesn't ask its children how big they want to be. It runs its layout, and the layout decides each child's box. The child is a passenger; the parent's layout is driving.
💡 Reframe everything you'll read below through that lens. Every layout in this phase is just a different strategy a parent uses to size and place its
items.fitmeans "one child, fill me."hboxmeans "lay children left to right."bordermeans "children claim edges." Same job, different rule.
Every container has a layout config. If you don't set one, you get the default — auto — and auto is exactly where beginners get burned, so let's start there.
The default auto layout (and why it disappoints)
A container with no layout set uses layout: 'auto'. It does almost nothing: it stacks its children as plain block-level elements, top to bottom, each taking its natural content height and no managed width or height at all.
Ext.;
What just happened: The panel is 400px tall, but auto doesn't divide that 400px between the grid and the form. It drops them in as blocks unsized. The grid, having no managed height, often collapses to almost nothing — and you stare at an empty panel wondering where your grid went. Nothing is broken; the parent never told the grid how tall to be. This single misunderstanding is behind most "my Ext JS screen is blank" panic.
The fix is always the same shape: pick a layout that actually sizes the children. Let's walk the ones you'll meet daily.
fit — one child, fill the box
fit is the simplest useful layout. The container has exactly one child, and that child is stretched to fill the container completely — full width, full height.
Ext.;
What just happened: The grid now fills the entire 600×400 panel because fit told it to. This is the canonical pattern for "a panel that wraps a single grid" — and you'll see it constantly in legacy code as a window whose only job is to frame one component.
⚠️
fitis built for one child. If you give it multipleitems, only the first one shows — the rest are still created but laid out on top / hidden behind it. If you put two things in afitcontainer and the second vanished, that's not a bug, that'sfitdoing exactly what it says. You wantedhbox/vboxorcard.
hbox / vbox — rows and columns with flex
The box layouts are your workhorses. hbox lays children out in a horizontal row; vbox lays them in a vertical column. The magic ingredient is flex: a number on each child that says how to divide the available space along the main axis proportionally.
Ext.;
What just happened: hbox puts the grid and form side by side. flex: 2 and flex: 1 split the horizontal space two-to-one, so the grid gets twice the width of the form. align: 'stretch' is the part beginners forget — it stretches both children to the full height of the panel on the cross-axis. Without it, each child would only be as tall as its own content, and the grid could collapse again. For vbox, swap the roles: flex divides the height, and align: 'stretch' gives children full width.
Two more knobs worth knowing:
flexvs fixed size: you can mix them. A child with a fixedwidth(inhbox) keeps that width, and theflexchildren share whatever's left over.packandalign:packcontrols distribution along the main axis ('start','center','end') — handy for, say, right-aligning toolbar buttons.aligncontrols the cross-axis ('stretch','top'/'left','middle'/'center','bottom').
💡 Mental shortcut: in
hbox,flexis about width andalignis about height. Invbox, flip them. The "main axis" is the direction the box lays children out; the "cross axis" is the other one.
border — the classic app shell
border is the layout that screams "this is an Ext JS app." Children declare a region — one of 'north', 'south', 'east', 'west', or 'center' — and the layout pins them to the edges of the container. center soaks up whatever space is left.
flowchart TB
subgraph BORDER[border layout]
N[north - toolbar / header]
subgraph MID[ ]
direction LR
W[west - nav] --- C[center - takes the rest]
end
S[south - status bar]
end
N --> MID --> S
Here's the users admin shell — a west nav and a center work area:
Ext.;
What just happened: The Viewport fills the whole browser window, and border carves it up. The west nav gets a fixed width: 220, collapsible: true gives it a collapse tool, and split: true adds a draggable splitter so the user can resize it. The center region claims everything that's left and, via its own layout: 'fit', hands all that space to the grid. North/south regions take a fixed height; east/west take a fixed width; center never gets a size from you — it just absorbs the remainder.
⚠️ A
borderlayout must have exactly onecenterregion. This is non-negotiable — leave outcenterand Ext JS throws an error (older versions) or renders a broken, empty shell. If aborderscreen is blank, the very first thing to check is: does it have acenter? You can have multiple north/south/east/west regions in some setups, but one and only one center, always.
card — show one child at a time
card stacks all its children in the same space but shows only one at a time. Think wizards, step-by-step flows, or the body of a tab panel. You switch which child is visible with setActiveItem.
var wizard = Ext.;
// later, on a "Next" button:
wizard..;
What just happened: All three forms exist, but only card 0 is visible at first. setActiveItem(1) swaps the display to the second form — no re-creation, just a visibility switch. You almost certainly already use this without knowing it: Ext.tab.Panel uses a card layout under the hood, and clicking a tab is just setActiveItem for that tab's body.
anchor — sizing relative to the container
anchor sizes children as a percentage (or offset) of the container. You'll meet it in older code:
What just happened: anchor: '100%' makes the textfield span the container's full width; anchor: '100% 50%' gives the grid full width and half the container's height. It works, but it's the older approach — for new work the box layouts (hbox/vbox) are usually preferred because flex handles proportional sizing more cleanly. Recognize anchor in legacy screens; reach for box layouts when you write fresh ones.
Layouts nest — and that's the whole trick
No single layout builds a real screen. Real screens are layouts inside layouts. The users admin is the textbook case: a border viewport whose center region is itself a vbox holding the grid above the form.
Ext.;
What just happened: The outer border handles the app shell (nav on the left, work area filling the rest). The center region then runs its own vbox: the grid gets flex: 1 so it grows to fill the leftover vertical space, while the form keeps a fixed height: 180 at the bottom. align: 'stretch' makes both span the full width of the center region. Each container only worries about its own children — nest them and arbitrarily complex screens fall out of simple rules.
⚠️ "Nothing shows up" — the troubleshooting section
This is the most valuable habit in this entire phase, so internalize it:
💡 If a component is invisible or zero-size, suspect the PARENT'S layout first — not the component. Nine times out of ten the child is fine; the parent never gave it a box.
When something won't render, walk this checklist in order:
- Is the parent on
autolayout? Nolayoutconfig meansauto, which doesn't size children. A grid or panel with no managed height collapses to nothing. Give the parent a real layout (fit,vbox,border...). - Is there a
borderlayout with nocenter? Missingcenterbreaks the whole container. Add exactly onecenterregion. - Is a child missing its
region? In aborderlayout, every child needs aregion. A child with noregion(or a typo'd one) doesn't know where to go and won't lay out. - Box layout with no size on the cross-axis? In
hbox/vbox, children with noflexand no fixed size on the main axis get zero, and withoutalign: 'stretch'they get zero on the cross-axis too. Addflex, a fixedwidth/height, oralign: 'stretch'.
⚠️ A telltale sign: the component shows up in the DOM and in the component tree (you can find it), but it's 0px tall or 0px wide. That is always a layout problem, never a "the component is broken" problem. Stop inspecting the child's config and go look at how its parent is laying things out.
Recap
- The parent's
layoutsizes its children — not CSS. This is the core mental model; settingwidth/heighton a child often does nothing because the layout overrides it. - The default
autolayout barely sizes anything, which is why unconfigured panels look empty. Pick a real layout. fit= one child fills the box;hbox/vbox= rows/columns sized byflex(andalign: 'stretch'on the cross-axis);border= edgeregions with exactly one requiredcenter;card= one child visible at a time viasetActiveItem.- Layouts nest — a
bordercenter region can hold avbox, and that's how real screens (like the users admin) get built. - When "nothing shows up," check the parent's layout first:
autolayout, a missingcenter, a missingregion, or a box child with no size are the usual culprits.
Quick check
Test the instincts that matter — what sizes a child, and how to read a blank screen:
[
{
"q": "You put a grid in a panel, give the grid height: 300, and it still renders at zero height. What's the most likely cause?",
"choices": ["The grid's store is empty", "The parent panel's layout (probably 'auto') isn't sizing the grid", "You forgot renderTo", "Grids can't have a fixed height"],
"answer": 1,
"explain": "In Ext JS the parent's layout sizes children. An 'auto' layout doesn't manage height, so the child collapses no matter what height you set on it."
},
{
"q": "Which statement about the border layout is correct?",
"choices": ["You must have exactly one 'center' region", "The 'center' region needs a fixed width", "You can have at most one 'west' region and no 'center'", "Regions are optional and default to 'north'"],
"answer": 0,
"explain": "A border layout requires exactly one center region; it absorbs the space left after the edge regions take their fixed sizes."
},
{
"q": "In an hbox layout, what does flex: 2 on one child and flex: 1 on another do?",
"choices": ["Stretches both to full height", "Splits the available WIDTH two-to-one between them", "Splits the available HEIGHT two-to-one", "Shows only the first child"],
"answer": 1,
"explain": "In hbox, flex divides the available space along the main (horizontal) axis, so flex 2 vs 1 gives the first child twice the width. Cross-axis height is controlled by align: 'stretch'."
}
]
← Phase 3: Components & the Containment Tree · Guide overview · Phase 5: The Data Package →
Check your understanding
1. You put a grid in a panel, give the grid height: 300, and it still renders at zero height. What's the most likely cause?
2. Which statement about the border layout is correct?
3. In an hbox layout, what does flex: 2 on one child and flex: 1 on another do?