PageSourceSearch

https://cube.fyi/assets/js/8.5c6d22e2.js

js cube.fyi collected 2026-10-03 22:02:24 UTC 10,988 bytes, 1 lines download raw bytes

1(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{280:function(t,a,e){"use strict";e.r(a);var s=e(14),n=Object(s.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"composition"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#composition"}},[t._v("#")]),t._v(" Composition")]),t._v(" "),a("p",[t._v("In CUBE CSS, the composition layer "),a("strong",[t._v("extends CSS")]),t._v(" and is very much a "),a("strong",[t._v("high level macro view")]),t._v("—even when applied in smaller, component-level contexts.")]),t._v(" "),a("p",[t._v("The composition layer’s job is to create flexible, component-agnostic layout systems that support as many variants of content as possible.")]),t._v(" "),a("p",[t._v("This links back to the "),a("a",{attrs:{href:"/principles"}},[t._v("principle")]),t._v(" that "),a("strong",[t._v("the browser should be hinted with flexible CSS rules, rather than micro-managed with strict CSS rules")]),t._v(". With the composition layer, we are "),a("em",[t._v("suggesting")]),t._v(" layout rules and "),a("strong",[t._v("allowing the browser to make the right judgements")]),t._v(", based on the context it finds itself in.")]),t._v(" "),a("h2",{attrs:{id:"why-macro-level-thinking"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#why-macro-level-thinking"}},[t._v("#")]),t._v(" Why macro-level thinking?")]),t._v(" "),a("p",[t._v("Even when you are working with tiny, reusable components, you have to, at some point, consider how they will be applied in a larger context: such as a page or view.")]),t._v(" "),a("p",[t._v("The composition layer is designed to "),a("em",[t._v("aid")]),t._v(" this process by providing a "),a("strong",[t._v("skeletal layout structure")]),t._v(" that shouldn’t interfere with the components (or block, in the context of CUBE CSS) that are featured, but also, support any variant of a component.")]),t._v(" "),a("h2",{attrs:{id:"what-should-the-composition-layer-do"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#what-should-the-composition-layer-do"}},[t._v("#")]),t._v(" What should the composition layer do?")]),t._v(" "),a("ul",[a("li",[t._v("Provide high-level, flexible layouts")]),t._v(" "),a("li",[t._v("Determine how elements interact with each other")]),t._v(" "),a("li",[t._v("Create consistent flow and rhythm")])]),t._v(" "),a("h2",{attrs:{id:"what-shouldn-t-the-composition-layer-do"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#what-shouldn-t-the-composition-layer-do"}},[t._v("#")]),t._v(" What shouldn’t the composition layer do?")]),t._v(" "),a("ul",[a("li",[t._v("Provide visual treatment such as colour or font style")]),t._v(" "),a("li",[t._v("Provide decorative styles such as shadows and patterns")]),t._v(" "),a("li",[t._v("Force a browser to generate a pixel-perfect layout instead of a flexible, progressive layout")])]),t._v(" "),a("h2",{attrs:{id:"examples"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),a("p",[t._v("Here are two simple examples of composition. First, a traditional layout and second, a flexible rhythm and flow solution.")]),t._v(" "),a("h3",{attrs:{id:"layout"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#layout"}},[t._v("#")]),t._v(" Layout")]),t._v(" "),a("p",[t._v("Let’s take a look at this classic layout:")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://piccalilli.imgix.net/images/cube/composition-1.svg?format=auto&q=60&w=1500",alt:"A line illustration of a basic layout withcomponents"}})]),t._v(" "),a("p",[t._v("A good ol’ classic hero and cards situation with a 3 column grid.")]),t._v(" "),a("p",[t._v("We’ve got various elements here that themselves are individual components. The "),a("strong",[t._v("composition")]),t._v(" of this layout is what controls the overall layout and rhythm of elements. Think of the composition as a "),a("strong",[t._v("skeleton")]),t._v(".")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://piccalilli.imgix.net/images/cube/composition-2.svg?format=auto&q=60&w=1500",alt:"The same illustration but the components are gone and a skeletal structure remains"}})]),t._v(" "),a("p",[t._v("As you can see, the composition handles how things stitch together, regardless of what component they happen to be.")]),t._v(" "),a("p",[t._v("To illustrate this further, we can put whatever components we like in our "),a("strong",[t._v("skeleton")]),t._v(". Like this example, we replace a card with a call to action instead:")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://piccalilli.imgix.net/images/cube/composition-3.svg?format=auto&q=60&w=1500",alt:"The initial illustration but one of the cards has been replaced with a new component"}})]),t._v(" "),a("p",[t._v("Our call to action isn’t out of place because the composition of this view handles all of the layout for us.")]),t._v(" "),a("h3",{attrs:{id:"flow-and-rhythm"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#flow-and-rhythm"}},[t._v("#")]),t._v(" Flow and Rhythm")]),t._v(" "),a("p",[t._v("To create flow and rhythm between elements, we can use the composition layer to generate a rule that sibling elements apply a margin that is either globally set, or contextually set.")]),t._v(" "),a("div",{staticClass:"language-css extra-class"},[a("pre",{pre:!0,attrs:{class:"language-css"}},[a("code",[a("span",{pre:!0,attrs:{class:"token selector"}},[t._v(".flow > * + *")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v("margin-top")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("var")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("--flow-space"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" 1em"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}
1")]),t._v("\n")])])]),a("p",[t._v("Then, using the card example, we’d apply it like this:")]),t._v(" "),a("div",{staticClass:"language-html extra-class"},[a("pre",{pre:!0,attrs:{class:"language-html"}},[a("code",[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("article")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("card"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("img")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("card__image"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("alt")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),a("span",{pre:!0,attrs:{class:"token attr-value"}},[a("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("[ card__content ] [ flow ]"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n    "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("\x3c!-- our content in here will auto-flow now --\x3e")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("</")]),t._v("div")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token tag"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("</")]),t._v("article")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n")])])]),a("p",[t._v("This means now that each element within "),a("code",[t._v("card__content")]),t._v(" will have a top margin of "),a("code",[t._v("1em")]),t._v(", unless "),a("code",[t._v("--flow-space")]),t._v(" is defined.")]),t._v(" "),a("p",[a("img",{attrs:{src:"https://piccalilli.imgix.net/images/cube/composition-4.svg?format=auto&q=60&w=1500",alt:"Content elements have a consistent 1em spacing"}})]),t._v(" "),a("p",[t._v("The default state when either --flow-space is not defined or we are in a globally set state.")]),t._v(" "),a("p",[t._v("We can then define "),a("code",[t._v("--flow-space")]),t._v(" in context, like this:")]),t._v(" "),a("div",{staticClass:"language-css extra-class"},[a("pre",{pre:!0,attrs:{class:"language-css"}},[a("code",[a("span",{pre:!0,attrs:{class:"token selector"}},[t._v(".card__content")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),a("span",{pre:!0,attrs:{class:"token property"}},[t._v("--flow-space")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" 1.4rem"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}
1")]),t._v("\n")])])]),a("p",[a("img",{attrs:{src:"https://piccalilli.imgix.net/images/cube/composition-5.svg?format=auto&q=60&w=1500",alt:"Content elements have a consistent 1.4rem spacing"}})]),t._v(" "),a("p",[t._v("Because "),a("code",[t._v("--flow-space")]),t._v(" is set in context, we can see the larger spacing.")]),t._v(" "),a("p",[t._v("This flow system is almost identical to the "),a("a",{attrs:{href:"https://every-layout.dev/layouts/stack/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Stack layout in Every Layout"),a("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);a.default=n.exports}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.