diff --git a/.changeset/clean-rivers-deny.md b/.changeset/clean-rivers-deny.md new file mode 100644 index 000000000..c99c2d2a0 --- /dev/null +++ b/.changeset/clean-rivers-deny.md @@ -0,0 +1,5 @@ +--- +'@cloudfour/patterns': minor +--- + +Add `o-media--1-by-X` modifier so we can size media objects and content relative to each other. This is especially useful when you want to align the object of one media element with another. diff --git a/.changeset/polite-gorillas-wave.md b/.changeset/polite-gorillas-wave.md new file mode 100644 index 000000000..6dd00d7ba --- /dev/null +++ b/.changeset/polite-gorillas-wave.md @@ -0,0 +1,7 @@ +--- +'@cloudfour/patterns': minor +--- + +`o-deck` automatically creates columns so sometimes there are multiple columns when only 1 column is desired. The `o-deck--X-column@Y` modifier has been updated so we can specify when we want 1 column. + +When using multiple media objects inside of a deck, some media objects were top-aligned and some were middle-aligned. To fix the mismatched alignment, we've also added the `o-deck--align-start` modifier, which forces all content to align-top. diff --git a/src/objects/deck/deck.scss b/src/objects/deck/deck.scss index 73a3b0987..0d950834e 100644 --- a/src/objects/deck/deck.scss +++ b/src/objects/deck/deck.scss @@ -45,10 +45,18 @@ * maximum or to coordinate with adjacent elements. */ -@for $i from 2 through 4 { +@for $i from 1 through 4 { .o-deck--#{$i}-column { @include media-query.breakpoint-classes($from: s, $to: xl) { grid-template-columns: repeat(#{$i}, 1fr); } } } + +/** + * Content alignment modifier + */ + +.o-deck--align-start { + align-items: start; +} diff --git a/src/objects/deck/deck.stories.mdx b/src/objects/deck/deck.stories.mdx index d53a0130d..aef605be1 100644 --- a/src/objects/deck/deck.stories.mdx +++ b/src/objects/deck/deck.stories.mdx @@ -1,6 +1,7 @@ import { Story, Canvas, Meta } from '@storybook/addon-docs'; import articles from './demo/articles.json'; import articlesDemo from './demo/articles.twig'; +import alignmentDemo from './demo/alignment.twig'; const articlesStory = (args) => articlesDemo({ items: articles, ...args }); // Custom function for generating story source from args given const articlesTemplateSource = (_src, storyContext) => { @@ -38,10 +39,11 @@ const articlesTemplateSource = (_src, storyContext) => { horizontalBreakpoint: 'none', }} argTypes={{ + class: { type: { name: 'string' } }, columns: { control: { type: 'range', - min: 2, + min: 1, max: 4, step: 1, }, @@ -83,11 +85,21 @@ By default, the `o-deck` class will use CSS Grid Layout to arrange child element +## Alignment + +The `o-deck--align-start` modifier can be used to top-align deck items. This modifier is helpful when the deck items have different alignment. For example, the `o-media` object can be middle or top aligned depending on the length of the content. The modifier forces all deck objects to have the same alignment. + + + ## Specifying Columns While automatic columns are convenient, there are times when a specific column count is desired. For example, you may want to limit a design to three columns at larger breakpoints to align with adjacent elements. -To do this, add a modifier class in the format of `o-deck--X-column@Y`, where `X` is the desired column count (from 2 to 4) and `Y` is the desired [breakpoint](/docs/design-tokens-breakpoint--page) (from `s` to `xl`). In this example, we force the grid to display three columns starting from the `m` breakpoint. +To do this, add a modifier class in the format of `o-deck--X-column@Y`, where `X` is the desired column count (from 1 to 4) and `Y` is the desired [breakpoint](/docs/design-tokens-breakpoint--page) (from `s` to `xl`). In this example, we force the grid to display three columns starting from the `m` breakpoint.
+ {% endblock %} + {% endembed %} + {% embed '@cloudfour/objects/media/media.twig' %} + {% block object %} + {% include '@cloudfour/components/avatar/avatar.twig' with { + "src": "https://placeimg.com/200/200/animals", + "sizes": "60px" + } only %} + {% endblock %} + {% block content %} ++ Lorem ipsum dolor sit amet, consectetur adipiscing elit. +
+ {% endblock %} + {% endembed %} + {% embed '@cloudfour/objects/media/media.twig' %} + {% block object %} + {% include '@cloudfour/components/avatar/avatar.twig' with { + "src": "https://placeimg.com/200/200/animals", + "sizes": "60px" + } only %} + {% endblock %} + {% block content %} ++ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. +
+ {% endblock %} + {% endembed %} + {% endblock %} +{% endembed %} diff --git a/src/objects/media/media.scss b/src/objects/media/media.scss index 268103fcc..5796f7a23 100644 --- a/src/objects/media/media.scss +++ b/src/objects/media/media.scss @@ -1,32 +1,29 @@ +@use '../../compiled/tokens/scss/breakpoint'; @use '../../compiled/tokens/scss/size'; +@use '../../mixins/media-query'; /** - * We could use CSS Grid for this pattern and save ourselves some child element - * styles, but it's such a simple component that it feels sort of unnecessary to - * provide a bunch of fallback CSS. - * * 1. Middle-align child elements. This will take effect when the content is * shorter than the object. */ .o-media { align-items: center; /* 1 */ - display: flex; + display: grid; + grid-gap: size.$spacing-media-gap; + grid-template-columns: minmax(0, auto) 1fr; } /** * 1. This will take effect when the object is shorter than the content, making * the whole element appear top-aligned in that case. - * 2. Prevent unintended distortion of this element's dimensions. - * 3. To encourage a semantic document outline, we decouple this element's + * 2. To encourage a semantic document outline, we decouple this element's * visual order from its markup order. */ .o-media__object { - align-self: flex-start; /* 1 */ - flex: none; /* 2 */ - margin-right: size.$spacing-media-gap; - order: -1; /* 3 */ + align-self: start; /* 1 */ + order: -1; /* 2 */ } /** @@ -36,17 +33,25 @@ */ .o-media--reverse .o-media__object { - margin-left: size.$spacing-media-gap; - margin-right: 0; order: 1; } /** - * Without this style, shorter flex content will not fill the available space. - * This can have unexpected consequences if the box is ever made visible via a - * background color, border, etc. + * Modifier: Content Sizing + * + * This modifier lets us use fractional units to size media content in relation + * to the object. This should make it easier to align the content of multiple + * media elements, even when the objects differ in size. */ -.o-media__content { - flex: 1; +@for $i from 1 through 4 { + .o-media--1-by-#{$i} { + @include media-query.breakpoint-classes($from: s, $to: xl) { + grid-template-columns: 1fr #{$i}fr; + + .o-media__object { + justify-self: center; + } + } + } } diff --git a/src/objects/media/media.stories.mdx b/src/objects/media/media.stories.mdx index 30995b353..d5985f5ae 100644 --- a/src/objects/media/media.stories.mdx +++ b/src/objects/media/media.stories.mdx @@ -48,6 +48,7 @@ const imageDemoTransformSource = (_src, storyContext) => { argTypes={{ imgSrc: { type: { name: 'string', required: true } }, text: { type: { name: 'string' } }, + class: { type: { name: 'string' } }, reverse: { type: { name: 'boolean' } }, }} /> @@ -93,6 +94,26 @@ The order of `o-media__object` and `o-media__content` will not affect this patte +## Specifying Content Size + +`o-media__object` and `o-media__content` can be sized relative to each other using fractional units. This is useful when you want to align the content of a media object with other media objects. + +To do this, use the modifier class `o-media--1byX@Y`. The number `1` represents the width of `o-media__object` and `X` represents the relative size of `o-media__content` (from 1 to 4). Y can be used to specify the desired breakpoint (from `s` to `xl`). + + + ## Checkbox Label In this example, `o-media` is applied to a `