Migrating from Foundation 6

Yeti is not Foundation 7 in the sense of being version 6 with new names. It is what Foundation would be if it were written today, for browsers that have container queries, popovers, dialogs, anchor positioning and cascade layers, and if the JavaScript were allowed to be almost nothing. So a port is not a rename. This page gives you the map, then the five habits that change.

The map

The table covers the grid and every component in the version 6 kitchen sink. "None" means Yeti does not have it and says why; most of those are things the browser now does.

Grid

Foundation 6 Yeti Notes
.grid-container center with data-max the reading column
.grid-x with .cell.medium-N columns with data-span on children equal shares unless a child says otherwise
.medium-8 beside .medium-4 columns with data-span="2" on the wider child shares, not twelfths
.grid-x.grid-margin-x columns with data-gap the gap is a token, not a gutter class
.small-up-3 / .large-up-4 grid with data-columns as many columns as fit; data-fold for a fixed count above a width
.grid-y stack vertical rhythm, no grid needed
.grid-frame / .cell-block cover and scroller full-height frame; a region that scrolls
.float-left / .float-right none floats are for text wrapping; a layout is a sidebar or a cluster
.show-for-medium / .hide-for-small none a component changes shape at its own threshold instead of being duplicated and hidden
.text-center and friends data-align and data-justify on the layout alignment is a layout's attribute, not a text utility

Components

Foundation 6 Yeti Notes
.button, .button.primary, .hollow, .clear button with data-variant and data-emphasis emphasis replaces hollow and clear
.button-group buttons a named group of buttons
.callout alert for a message, box with data-border for a plain panel the callout did two jobs
.card card the figure bleeds on its own; data-stretch for a whole-card link
.label and .badge badge one component, sized by data-size
.table, .hover, .stack table with data-hover, data-striped; a scroller for width the stacking table is gone, a table stays a table
.top-bar nav collapses behind a toggle at its own threshold
.title-bar with .off-canvas nav with data-panel="drawer" the drawer is the nav's own panel
.menu, .menu.vertical a cluster or stack of links; nav for a site menu a menu is a list of links
.dropdown-pane dropdown a popover, so no script and no z-index
.dropdown.menu submenus dropdown inside a nav item one level; a mega menu is not shipped
.accordion-menu, .drilldown none a site tree is a list of links in a stack; the browser's <details> disclosure for a section
.reveal dialog, opened by a button with data-open the native dialog; the module opens it modally
.tooltip tooltip hover and focus, no script
.accordion accordion native <details>; name for one-at-a-time
.tabs tabs roving focus from the module
.orbit carousel scroll snap; dots that are links
.progress, .progress-meter progress on the native <progress> indeterminate when no value
.slider field around a native input type="range" the native control, filled track from --yeti-range-value
.switch field around a native checkbox with role="switch" native, styled
.breadcrumbs breadcrumbs with aria-current on the last
.pagination pagination with aria-current on the current page
.close-button the dismiss button inside alert, data-close inside nav a close button belongs to what it closes
.sticky none one native position: sticky declaration on any element; nothing to add
.magellan none a table of contents is a stack of links; scroll spying is script the page can add if it must
.responsive-embed / .flex-video frame with data-ratio native aspect-ratio
.thumbnail frame in a box with data-border two primitives
.media-object media the recipe, or sidebar and frame yourself
.input-group affix inside field the joined control and button share a border; the field still owns the label
.help-text, .form-error data-hint and data-error inside field tied to the input with aria-describedby
.is-invalid-input aria-invalid="true" on the input state is ARIA, not a class
Abide none native validation attributes; the field shows the browser's state
Equalizer none columns and grid align heights on their own
Interchange none <picture> and srcset
Toggler none popover, <details>, and aria-expanded cover every case it had
Motion UI none components transition on the motion tokens; reduced motion is honoured through them

The five habits

Attributes, not modifier classes. .button.primary.large.hollow becomes class="button" data-variant="primary" data-size="lg" data-emphasis="medium". Each attribute has a fixed list of values, and a value outside the list is a validator error. Your own classes never collide with Yeti's, because Yeti only ever has one.

Native state, not is- classes. There is no .is-active, .is-open, .is-invalid-input. An open accordion has the open attribute, the current page has aria-current="page", an invalid field has aria-invalid="true", a selected tab has aria-selected="true". Screen readers read those; they never read a class.

A threshold, not a breakpoint. There are no small-, medium-, large- prefixes and no visibility classes. A component changes shape at its own width, chosen from six stops with data-threshold or data-max. The responsive guide is the whole story.

Nothing to initialise. There is no Foundation.init(), no data- attributes for plugins, no jQuery. Six components have an optional module; you load it with one script tag, anywhere, and it finds its own elements. Without the module the component still works, minus what the module adds.

The browser does the opening and closing. Dropdowns and the nav's menu are popovers; the dialog is a dialog; the accordion is <details>. Escape, light dismiss, the focus trap and the expanded state come from the platform. If you find yourself writing script to open something, look for the attribute that already does.