// vf-card @import 'package.variables.scss'; // Debug information from component's `package.json`: // --- /*! * Component: #{map-get($componentInfo, 'name')} * Version: #{map-get($componentInfo, 'version')} * Location: #{map-get($componentInfo, 'location')} */ @import 'vf-card.variables.scss'; .vf-card { --card-text-color: var(--vf-card-theme-color--foreground, #{text-color(primary)}); --card-background-color: var(--vf-card-theme-color--background , #{ui-color(white)}); align-content: start; background-color: var(--card-background-color); /* border: 1px solid var(--vf-card-theme-color--border, var(--card-border-color, #{set-color(vf-grey--lightest)})); */ box-shadow: 0 .125rem .25rem rgba(color(grey--dark), .5); display: grid; position: relative; } .vf-card__image { height: auto; min-height: 16rem; // This provides a fallback for when aspect-ratio is not supported object-fit: cover; object-position: center; width: 100%; @supports (aspect-ratio: 1 / 1) { aspect-ratio: var(--vf-card__image--aspect-ratio, 8 / 4); min-height: unset; } } .vf-card__content { grid-column: 1 / -1; padding: map-get($vf-spacing-map, vf-spacing--400); .vf-button { position: relative; z-index: 1984; } .vf-list { margin-bottom: 0; & > *:last-child { margin-bottom: 0; } } .vf-content { & > *:last-child { margin-bottom: 0; } a { text-decoration: none; &:hover { color: color(blue--dark); text-decoration: underline; text-decoration-thickness: 2px !important; } } } } .vf-card__heading__icon { fill: currentColor; padding-top: 0.1em; // to compensate for ascender, this value should be fairly consistent across most type families transform: translateX(map-get($vf-spacing-map, vf-spacing--100)); // @todo: some sort of centralised and reusable docs, tokens, guidance on animations transition-duration: 125ms; transition-property: transform; transition-timing-function: cubic-bezier(.45, .05, .55, .95); } .vf-card__title, .vf-card__heading { @include set-type(text-heading--3, $custom-margin-bottom: 0, $color: ignore); background-color: var(--card-background-color); color: text-color(primary); color: var( --card-text-color, #{text-color(primary)} ); line-height: 1.333; text-decoration: none; word-break: break-word; .vf-card__link { color: color(blue); display: grid; grid-column-gap: space(100); grid-template-columns: auto 1fr; text-decoration: none; &::after { bottom: 0; content: ''; left: 0; position: absolute; right: 0; top: 0; transition-duration: 125ms; transition-property: box-shadow; transition-timing-function: ease-in-out; z-index: 512; } &:hover { text-decoration: underline; text-decoration-thickness: 2px !important; text-underline-offset: 4px; &::after { box-shadow: 0 0 .125rem .125rem rgba(color(grey), .75); } } } .vf-card__link:hover .vf-card__heading__icon, .vf-card__link:focus .vf-card__heading__icon { transform: translateX(map-get($vf-spacing-map, vf-spacing--200)); } .vf-card__link:visited, .vf-card__link:visited:hover, .vf-card__link:hover, .vf-card__link:focus { color: var(--vf-color--blue--dark); } } .vf-card__subheading { --vf-stack-margin--custom: #{space(100)}; // fallback for vf-stack prior to version 3 --vf-stack-margin: #{space(100)}; @include set-type(text-heading--5, $custom-margin-bottom: 0, $color: ignore); word-break: break-word; } .vf-card__text { @include set-type(text-body--2, $custom-margin-bottom: 0, $color: ignore); color: ui-color(white); color: var( --card-text-color, #{ui-color(white)} ); word-break: break-word; .vf-card__link, a { color: color(blue); position: relative; text-decoration: none; z-index: 1984; &:hover { color: color(blue--dark); text-decoration: underline; text-decoration-thickness: 2px !important; } } } // -------------------------------------------------------------------------------- // Variants // -------------------------------------------------------------------------------- // Bordered // -------------------------------------------------------------------------------- .vf-card--bordered { border-bottom: 8px solid color(green); border-bottom-color: var(--vf-card-border-color, #{color(green)}); // fixes bug on hover of link and easy variant #1215 .vf-card__link { &::after { height: calc(100% + 8px); } } } // Striped // -------------------------------------------------------------------------------- .vf-card--striped { background-color: color(green--dark); background-color: var(--vf-card--striped-bg-color, #{color(green--dark)}); .vf-card__content { padding-bottom: 0; & > *:last-child:not(.vf-card__link) { padding-bottom: 1rem; } .vf-list, .vf-content * { color: ui-color(white); a { color: inherit; position: relative; text-decoration: underline; z-index: 1984; } } } .vf-card__title, .vf-card__heading { background-color: color(green); background-color: var(--vf-card-bg-color, #{color(green)}); color: ui-color(white); margin: map-get($vf-spacing-map, vf-spacing--400) * -1; margin-bottom: map-get($vf-spacing-map, vf-spacing--200) * -1; padding: map-get($vf-spacing-map, vf-spacing--400); padding-bottom: map-get($vf-spacing-map, vf-spacing--200); .vf-card__link { color: currentColor; &:hover { color: currentColor; } } } .vf-card__subheading { background-color: color(green--dark); background-color: var(--vf-card--striped-bg-color, #{color(green--dark)}); color: ui-color(white); margin: map-get($vf-spacing-map, vf-spacing--400) * -1; margin-top: 0; padding: map-get($vf-spacing-map, vf-spacing--400); padding-bottom: map-get($vf-spacing-map, vf-spacing--200); padding-top: .5rem; } .vf-card__text { color: ui-color(white); &:first-of-type { --vf-stack-margin--custom: 0; // fallback for vf-stack prior to version 3 --vf-stack-margin: 0; // padding-top: map-get($vf-spacing-map, vf-spacing--400); } .vf-card__link, a { color: inherit; text-decoration: underline; } } .vf-card__title + .vf-card__text, .vf-card__heading + .vf-card__text { --vf-stack-margin--custom: #{space(400)}; // fallback for vf-stack prior to version 3 --vf-stack-margin: #{space(400)}; } } // -------------------------------------------------------------------------------- // Theming // -------------------------------------------------------------------------------- // note: // - we are removing the `-theme-` part of the classname now. // - we are also moving towards more holistic theming with design. .vf-card--primary, .vf-card--brand { --vf-card-bg-color: #{color(green)}; --vf-card-text-color: #{ui-color(white)}; --vf-card-border-color: #{color(green)}; --vf-card--striped-bg-color: #{color(green--dark)}; --vf-card--striped-text-color: #{ui-color(white)}; } .vf-card--secondary { --vf-card-bg-color: #{color(blue)}; --vf-card-text-color: #{ui-color(white)}; --vf-card-border-color: #{color(blue)}; --vf-card--striped-bg-color: #{color(blue--dark)}; --vf-card--striped-text-color: #{ui-color(white)}; } .vf-card--tertiary { --vf-card-bg-color: #{color(grey)}; --vf-card-text-color: #{ui-color(white)}; --vf-card-border-color: #{color(grey)}; --vf-card--striped-bg-color: #{color(grey--dark)}; --vf-card--striped-text-color: #{ui-color(white)}; } // -------------------------------------------------------------------------------- // Temporary Fix // -------------------------------------------------------------------------------- // note: as we are adding `vf-stack` to the `vf-card__content` we need to override // the existing `margin-bottom` to the `__title` and __text` components. .vf-card__content.vf-stack { .vf-card__title, .vf-card__heading, .vf-card__text { margin-bottom: 0; } .vf-card__text { margin-top: #{map-get($vf-spacing-map, vf-spacing--400)}; /* IE Fallback */ margin-top: var(--vf-stack-margin, #{map-get($vf-spacing-map, vf-spacing--400)}); } } // -------------------------------------------------------------------------------- // TODO: To be deleted and removed in v3.0.0 // -------------------------------------------------------------------------------- // note: some of this CSS 'overrides' CSS in the newer cards -- but only by replacing // like for like. // vf-card levels of design html:not(.vf-disable-deprecated) { @warn 'This variant has been deprecated'; .vf-card--very-easy { border-bottom: 8px solid rgba(0, 0, 0, 0); // fixes a grid layout glitch when used with variant volume's that have a bottom border } .vf-card--easy { @warn 'This variant has been deprecated'; border-bottom: 8px solid ui-color(black); border-bottom-color: var(--vf-card-theme-color--border, #{ui-color(black)}); .vf-card__title, .vf-card__heading { --card-text-color: #{color(blue)}; } .vf-card__text { --card-text-color: #{ui-color(black)}; } } .vf-card--normal { --card-text-color: var(--vf-card-theme-color--foreground, #{ui-color(white)}); --card-background-color: var(--vf-card-theme-color--background, #{ui-color(black)}); } .vf-card--hard { --card-text-color: var(--vf-card-theme-color--foreground, #{ui-color(white)}); --card-background-color: var(--vf-card-theme-color--background, #{ui-color(black)}); .vf-card__content { grid-row: 2 / -1; } .vf-card__title, .vf-card__heading { @include set-type(text-body--5, $color: ignore); display: inline-block; margin-bottom: 0; margin-left: -24px; margin-top: 2px; padding: 16px 24px; text-transform: uppercase; } .vf-card__text { padding-top: 16px; } } // vf-card themes [class*='vf-card-theme'].vf-card--easy { --vf-card-theme-color--background: #{ui-color(white)}; } [class*='vf-card-theme'] { .vf-card__text .vf-card__link { color: inherit; text-decoration: underline; } } .vf-card-theme--primary { --vf-card-theme-color--foreground: #{ui-color(white)}; --vf-card-theme-color--border: #{color(blue)}; --vf-card-theme-color--background: #{color(blue)}; } .vf-card-theme--secondary { --vf-card-theme-color--foreground: #{ui-color(black)}; --vf-card-theme-color--border: #{color(green)}; --vf-card-theme-color--background: #{color(green)}; } .vf-card-theme--tertiary { --vf-card-theme-color--foreground: #{ui-color(white)}; --vf-card-theme-color--border: #{color(grey--dark)}; --vf-card-theme-color--background: #{color(grey--dark)}; } .vf-card-theme--quaternary { --vf-card-theme-color--foreground: #{ui-color(black)}; --vf-card-theme-color--border: #{color(yellow)}; --vf-card-theme-color--background: #{color(yellow)}; } }