eBay's cohesive multi-screen experience starts with a shared and unified design system. As this system evolves, so too does Skin, meaning apps only need to keep their Skin package updated to ensure the latest look and feel.
Adaptive
Screens 7" and below are considered to be small screens; they are our default, baseline experience. Screens over 7" are large screens. Skin provides support for large screens in an adaptive manner.
Accessible
Skin leverages semantic HTML, SVG, ARIA roles, states and properties to apply our styles wherever possible, thus enforcing correct, accessible semantics.
Readable
Skin follows the BEM principles of Block, Element and Modifier to ensure our class name and class structure is human readable and understandable.
Decoupled
Skin is decoupled from the JavaScript layer, meaning that HTML and CSS should not need to be reimplemented every time the JS frontend framework changes.
Open
Skin operates under an open source model. GitHub allows any developer to contribute bug fixes, features, suggestions and ideas. Join the community and get involved!
Install
As of v3, Skin is distributed as the @ebay/skin package on the public NPM repository.
Users of eBay's internal NPM repository must add the following exception to their .npmrc file or .yarnrc file, respectively, in order to support the scoped package name:
If you are using the public NPM repository, then you can safely ignore this exception.
The package can be installed to the node_modules folder of your working directory by using the npm install command:
Or alternatively by adding the package as a dependency in your package.json file:
Include the @ebay/skin package in your browser.json to include the entire set of Skin modules:
Or alternatively by specifying modules on a per-need basis:
Skin provides the following modules:
@ebay/skin/actionable
@ebay/skin/button
@ebay/skin/card
@ebay/skin/checkbox
@ebay/skin/combo
@ebay/skin/core
@ebay/skin/dialog
@ebay/skin/field
@ebay/skin/form
@ebay/skin/global
@ebay/skin/grid
@ebay/skin/iconfont
@ebay/skin/icon
@ebay/skin/less*
@ebay/skin/listbox
@ebay/skin/marketsans
@ebay/skin/menu
@ebay/skin/pagination
@ebay/skin/radio
@ebay/skin/spinner
@ebay/skin/svg
@ebay/skin/switch
@ebay/skin/tab
@ebay/skin/textbox
@ebay/skin/utility
* The @ebay/skin/less module requires the additional lasso-less plugin in your app's package.json dependencies.
Bundles
Bundles are special Lasso.js modules that bundle together a collection of related Skin components.
Core
The @ebay/skin/core module bundles together Skin's core dependencies.
@ebay/skin/global
@ebay/skin/utility
Combo
The @ebay/skin/combo module bundles together Skin's most common modules, as identified across key eBay experiences.
@ebay/skin/core
@ebay/skin/dialog
@ebay/skin/form
@ebay/skin/icon
@ebay/skin/iconfont
@ebay/skin/spinner
Note: The combo bundle itself contains two other bundles. Lasso will take care of de-duping modules where necessary.
Form
The @ebay/skin/form module bundles together all form controls and field layout.
@ebay/skin/button
@ebay/skin/checkbox
@ebay/skin/field
@ebay/skin/listbox
@ebay/skin/radio
@ebay/skin/switch
@ebay/skin/textbox
Adapters
Skin takes advantage of conditional dependencies in Lasso.js, to provide adaptive CSS for every component.
NOTE: Skin itself does not do any detection of browser size or capabilities, therefore it is the responsibility of the application logic (typically via device detection service) to detect which adapters are needed.
Skin Large
Skin is built for small screens first (7" and below). Styles for larger screens (i.e. desktop) are not supplied by default.
To meet the conditional dependency for large screen styles, Lasso.js requires the skin-large flag.
Skin DS
Skin has the capability to switch between previous, current and upcoming design systems at a component level.
More information coming soon.
CDN
A CSS file containing the full collection of modules (except grid) for small screens is available via the following url:
Using this "full" file effectively means that your site is opting into a responsive approach rather than adaptive.
Fonts
Icon Font
Skin provides it's own custom icon-font via the @ebay/skin/iconfont module.
This module alone only downloads and installs the icon font-face from the eBay CDN. The individual icons within the font must be leveraged via classes provided by the icon module or via mixins provided by the less module.
NOTE: Although icon fonts are supported across all modern browsers, they sometimes experience "weird failures". Please refer to CSS tricks, which summarizes failure scenarios and other issues. It is because of such issues that Skin is currently transitioning over to an SVG based icon system.
Market Sans
Market Sans is a new and exclusive typeface developed specifically for eBay. This module downloads and installs the typeface directly from the eBay CDN servers. The typeface can then be referenced via the 'Market Sans' font-family name.
TIP: The Market Sans font-family, and all fallbacks, can also be applied using the Less variable @font-family-market-sans.
Actionable
Actionable Icon
Use the icon-btn class (for buttons) or the icon-link class (for links) and any of the available SVG icons for a borderless, actionable icon style. Font-icons are no longer supported.
Actionable Image
Use the img-btn class (for buttons) or the img-link class (for links) to create an actionable image-tile effect on hover, focus and active states.
Button
A button is typically used to trigger a JavaScript action (e.g. fetch results, open a dialog or expand a menu). In this case, the <button> tag is required.
A button may also be used to natively (i.e. no JavaScript required) submit or reset a form. In this case use the <button> tag with type=submit or type=reset respectively. Use of the <input> tag is not currently supported.
Finally, a link may be styled to look like a button. In this case the <a> tag is required with a valid HREF attribute. Please see the fake button section below for more details.
Partially disabled buttons are visually and aurally identifiable as disabled, but remain keyboard focusable.
Partially disabled buttons can vastly simplify keyboard focus management logic in situations where the button may frequently toggle back and forth between enabled and disabled (e.g. pagination or carousel 'bookend' buttons).
The aria-disabled state is required for partially disabled buttons.
Because the button cell uses flex box layout, it is fairly trivial to achieve alternate layouts, as in the example below.
TIP: Looking for borderless icon buttons? Head over to the actionable module.
Card
A card forms the content layer in the eBay Design System topography of background layer, content layer & content. This system requires that the background layer (typically the HTML body tag) have zero margin and padding. The card content layer is responsible for creating all necessary margin & padding.
All cards use a nested card__cell element to denote the inner content of the card block. Any content placed outside of this cell will be full-bleed (i.e. edge to edge). See hero card section below for more information.
NOTE: in all card examples below we use a fixed-height div to simulate Skin's default grey background layer.
Regular Card
Use the card class to create a card with vertical and horizontal margins.
This 'floating' effect helps differentiate data sets and is used to identify secondary, tertiary & extraneous content.
Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Primary Card
Use the card--primary modifier to create a primary, full-width card.
Only one primary card should be deployed per page. It is used to identify primary content and spans the entire width of the background layer.
Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Full Page Card
Applying the card class directly to the body tag creates a full page card. Full page cards span the full width and height of the page.
Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Hero Card
For cards with large hero headers, apply the card--hero modifier. The hero element must immediately precede the card__cell element.
TIP: A CSS background image can also be used as the hero image.
Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Title
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Dialog Cards
Cards can also be used inside of any dialog.
Dialog with Cards
Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus convallis molestie erat, ut adipiscing risus blandit vel. Vivamus luctus elementum lorem, eu sodales velit sagittis id. Donec a est ligula, eget volutpat augue.
To create a full content layer inside of a dialog, apply the dialog--card modifier to the dialog block.
Checkbox
A checkbox is a form control that allows the user to toggle a choice on or off.
The purpose of a checkbox is to collect form data; therefore a checkbox should always be used in conjunction with a form, label and submit button.
A checkbox requires the following SVG symbol definition:
Default Checkbox
Use the checkbox base class to create a checkbox.
The checkbox is decoupled from it's real text label to allow more flexibility in terms of layout. How and where you provide this label is up to you, but do not forget it!
The hidden attribute ensures that the SVG icon is not visible when CSS is disabled and also helps prevent a flash of unstyled content (FOUC).
Disabled Checkbox
Use the disabled attribute to disable any checkbox input.
Grouped Checkboxes
A group of checkboxes allows multi-select (unlike a group of radio buttons which enforces single-select).
A fieldset and legend are required in order to create the correct grouping semantics. Note that the Skin global module removes the default fieldset border and padding.
TIP: To stack checkboxes vertically instead of side-by-side, simply replace the span wrapper with a div wrapper.
Custom Checkbox BETA
Use the checkbox__custom-control element class to create a custom styled checkbox that can use any inline SVG for it's checked and unchecked states.
Be careful when using a custom checkbox; if a user cannot tell the icon represents an interactive control, they may skip over it entirely.
Dialog
A dialog is a child window spawned by the main web page or application.
This window forms a new background layer in our design system topography, and has zero margin and padding by default.
Content may be placed directly onto this background layer, inside of a dialog__cell element. Alternatively, a content layer can be created using the card module and/or grid module.
A dialog must remain in a hidden state for all users and devices until called upon.
All dialogs have support for optional CSS transition effects. See dialog transitions section for more details.
The lightbox will be centered vertically and it's height will grow with it's content. To instead align the lightbox to the top of the screen, use the dialog__window--top modifier.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Panel dialogs fill 80% of the available screen width.
Use the dialog__window--left or dialog__window--right modifier to create a panel on the left or right edge of the screen.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Apply the dialog__window--full modifier to create a fullscreen dialog.
The close button may have inner text (e.g. "Cancel", "Done") or an inline SVG.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
In the header, replace the close button with a back button to create a subpage dialog.
The back button may have inner text (e.g. "Back") or an inline SVG.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
In the header, use a back button and a close button to create a multi-step dialog.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
In the header, add a search form to create a search dialog.
Dialog Transitions
Skin currently supports two types of dialog transition: fade and slide.
Because CSS cannot transition an element to and from hidden (i.e. "display:none"), we require two temporary classes - dialog--transition-in and dialog--transition-out - to help prime the CSS transition in and out respectively.
The commented jQuery sample below shows the required sequence of events.
From the code sample, you should see that a CSS transition can be triggered using a combination of the hidden property, and the transient dialog--transition-in & dialog--transition-out helper modifiers.
Fade Transition
Any dialog window and mask can be faded in and out, using the dialog__window--fade and dialog__mask--fade modifiers.
The default fade duration is 16ms.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Any panel or fullscreen dialog can slide in and out, using the dialog__window--slide-left or dialog__window--slide-right modifier.
The slide transition duration is 32ms. An accompanying dialog__mask--fade-slow modifier can be applied to a dialog panel's mask. This slower fade matches the 32ms of the slide transition.
Dialog Title
Heading
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
The field module facilitates the layout of a form control and it's associated label, plus any other applicable text or sub-controls (e.g. error text or help button).
A readonly control is conveyed using the readonly attribute. The value of a readonly control is passed to the server.
Required Field
A required field is conveyed visually with an asterisk, and non-visually using the aria-required property.
Invalid Field
An invalid control is conveyed visually via a combination of red outline and some other indicator (usually either text and/or an icon). The invalid state is conveyed non-visually using the aria-invalid state.
Form control elements (such as select and input) are inline-block by default, and will only use up as much of their parent's horizontal space as they need.
For a stacked field the control must be set to 100% width (using the fluid utility class) to fill all available space.
The above example shows the fields in a flexbox layout. This layout is created using the field-group helper class. Notice that each field is also set to fluid, in order to fill all available flexbox space (flexbox layout takes care of dividing the space evenly between fluid fields).
If we set the form control width to 100% in an unstacked field, the control would flow to a new line below the label (effectively behaving like a stacked label). This behaviour can be avoided by adding an additional field__group element to create flex layout inside of the field.
TIP: You may want to experiment with sizes other than 100%, and also the flexbox justify-content property.
Field Description
A field may have nearby text to describe additional instructions, status or validation error of the control.
The field__description element defines some minimal styling, but does not dictate location or layout. This element has modifiers for confirmation, information and priority, depending on the type of descriptive text (or icon).
TIP: The description element can be designated as an ARIA live-region if client-side updates occur.
Text on Side of Field
A description can be placed adjacent to any stacked or unstacked field simply by using an inline-level tag, such as span.
Field description or error
For a fluid control and description, those elements can be wrapped in a field__group container to create flex layout.
Field description or error
Field description or error
Text Below Stacked Field
A description can be placed underneath a stacked field simply by using a block-level tag, such as div.
Field description or error
Text Above or Below Unstacked Field
A description can be added directly above and/or below the control by utlising CSS table-layout via the field--table modifier and field__row elements.
Field description or error
Global
Global creates a unique look for the eBay brand by defining the style of common elements such as headings, paragraphs, fieldsets, images and links.
The eBay grid is a flexbox first layout system, used to give to structure and form to designs. It will enable building consistent layouts across multiple pages.
For all Screens
By using our grid system pages can be made to adapt to any screen size. It uses media queries in order to change the layout. However, builds will be included for both adaptive and responsive use cases.
Consistent Design
The large and medium grid layouts are based on fractions of sixteen; the small grid is fractions of eight. Each grid cell has a percentage width with fixed "gutters". Having fixed spacing allows for consistent rhythm in our vertical and horizontal spacing.
Customizable
Currently the maximum width of a layout is 1280 pixels, but this system can easily be customized to fit all needs.
Lasso
If you are using Lasso.js, you can include the grid css by adding a flag to your lasso configuration. For this to work you must include the @ebay/skin/grid module in your browser.json as a dependency. If no flags are specified the grid-core
file will be loaded into your page.
grid-core
Adds the core grid system to your page. This includes just includes the lg, sm, and default grid sizes.
grid-large
In order to accommodate adaptive designs the large and extra-large classes were broken up into their own file. This allows for applications to only pull in the large and extra-large classes
grid-small
In order to accommodate adaptive designs the small classes were broken up into their own file. This allows for applications to only pull in the small classes
grid-full
Adds the entire grid system to your page. This includes the lg, sm and the default grid sizes. As well as the necessary classes to utilize nested grids.
The only direct children of the .grid element should be .grid__group elements.
Generally, the only direct children of the .grid__group element should be .grid__cell elements.
The only current exception is when you use the .grid__group--full modifier.
Generally, the .grid__cell element should have one block element child.
In order to simplify the grid system classes, the default classes to layout a page are .grid__cell--*of*, replacing the * with a number up to 16.
Content....
Content....
Standard Breakpoints
The standard .grid__cell modifier classes will also have modifier classes to faciliate responsive page changes for different screen sizes. These are the same as the standard .grid__cell modifier class except they have a "-lg" or "-sm" post-fix.
600
960
1280
8 columns
16 columns
Small
Medium
Large
Class
.grid__cell--*of*-sm
.grid__cell--4of8-sm
.grid__cell--*of*
.grid__cell--5of16
.grid__cell--*of*-lg
.grid__cell--8of16-lg
Media query
@media(max-width: 600px)
@media(min-width: 961px)
Viewport size
<= 600px
>= 961px
Gutter size
8px
16px
16px
16
4
4
4
4
4
8
4
8
8
Simple Fraction Grid Cell Classes
In order to make using the grid system easier, a set of commonly used fractions were identified.
These classes can be used if the percentage of the column will be staying the same regardless of the screen size.
This allows for less code to be written in the markup.
For example, instead of using .grid__cell--4of16 .grid__cell--2of8-sm
to represent one-half on both large and small screens, the class .grid__cell--one-half .
.grid__cell--one-half
.grid__cell--one-half
.grid__cell--one-fourth
.grid__cell--three-fourth
.grid__cell--one-third
.grid__cell--two-third
.grid__cell--one-fifth
.grid__cell--four-fifth
.grid__cell--two-fifth
.grid__cell--three-fifth
Nested Grid
The grid__cell element's proportions are relative to their parent container.
A few rules exist for the .grid .grid selector and the
.grid .grid > .grid__group selector. So, in order for nesting to work properly
.grid__group elements should have a direct parent that is a
.grid element. In other words, you should not place a .grid__group
directly inside a .grid__cell.
Content....
Content....
Content....
Content....
Content....
Content....
Content....
Content....
Content....
Content....
Experimental Nested Grid
Only available in grid-full.less. Contains every possible fraction, which is the reason for the significantly larger file size.
I am nested
I am nested
Content....
Grid Helper Classes
.grid__group--full
Instead of using .grid__cell--16of16, .grid__group--full can be used to achieve a full width row with the cell properties. This requires one less element, which is nice.
Example of using .grid__group--full
Content....
Content....
.grid__cell--*-hidden
In cases where you want to hide a segment of layout for a certain screen size
use the .grid__cell--sm-hidden, .grid__cell--md-hidden, or
.grid__cell--lg-hidden modifier class.
Content....
Content....
Content....
.grid__group--wrap
If there is a case where you need the content within a group to wrap, the .grid__group--wrap modifier class is used.
Without .grid__group--wrap modifier class
Content....
Content....
Content....
Content....
Content....
With .grid__group--wrap modifier class
Content....
Content....
Content....
Content....
Content....
Adapting to Screen Size With .grid__group--wrap
Wrapping can be useful when a piece of a layout needs to adapt to different screen sizes.
Content....
Content....
Content....
Content....
Content....
Content....
Content....
Content....
.grid__cell--grow
If there is a desire to have a cell fill the rest of the left-over space, use .grid__cell--grow.
This can be used to make responsive choreography between .grid__cell elements easier.
NOTE: Skin is in the midst of a transition from a font-based icon system to an SVG-based icon system. All icons listed below are being converted to SVG on a per-need basis.
Core Icons
Null Icons
Editing Icons
Selling Icons
Misc Icons
Less
The @ebay/skin/less module enables developers to access our Skin-related Less variables & mixins in their application.
Our Less module is not intended as a general-purpose library of utility mixins and variables (i.e. it is not LessHat!).
NOTE: This module requires the additional lasso-less plugin dependency in your app package.json:
Core Icons
The @ebay/skin/less module allows access to individual icons in the Skin icon font via LESS mixins.
Please refer to the icon module for the full list of icon names. When using the icons as a mixin, simply postfix any of those icon names with -mixin in your LESS file.
Core Colors
@ds4-color-core-gray-jet;
@ds4-color-core-gray-davys;
@ds4-color-core-gray-dim;
@ds4-color-core-gray-spanish;
@ds4-color-core-gray-silver;
@ds4-color-core-gray-gainsboro;
@ds4-color-core-gray-light;
@ds4-color-core-orange;
@ds4-color-core-red;
@ds4-color-core-purple;
@ds4-color-core-blue-dark;
@ds4-color-core-blue;
@ds4-color-core-violet;
@ds4-color-core-green;
@ds4-color-core-beige;
@ds4-color-core-beige-light;
Text Colors
@color-text-default;
@color-text-subheader;
@color-text-footnote;
@color-text-disabled;
@color-text-critical;
@color-text-positive;
Interface Colors
@color-interface-hot;
@color-interface-cta-dark;
@color-interface-cta;
@color-interface-cta-light;
@color-interface-positive;
@color-interface-line-separator;
@color-interface-view-background;
@color-interface-base;
@color-interface-base-light;
@color-interface-modal-shadow;
@color-interface-menu-shadow;
@color-interface-card-visited;
@color-interface-card-background;
@color-interface-card-selection;
@color-interface-card-highlight;
@color-interface-inline-text-edit;
Infographic Colors
@color-infographic-red-lightest;
@color-infographic-red-light;
@color-infographic-red;
@color-infographic-red-interaction;
@color-infographic-green-lightest;
@color-infographic-green-light;
@color-infographic-green;
@color-infographic-green-interaction;
@color-infographic-blue-lightest;
@color-infographic-blue-light;
@color-infographic-blue;
@color-infographic-blue-interaction;
@color-infographic-orange-lightest;
@color-infographic-orange-light;
@color-infographic-orange;
@color-infographic-orange-interaction;
@color-infographic-purple-lightest;
@color-infographic-purple-light;
@color-infographic-purple;
@color-infographic-purple-interaction;
@color-infographic-gray-lightest;
@color-infographic-gray-light;
@color-infographic-gray;
@color-infographic-gray-interaction;
Mobile Font Hierarchy
.font-hierarchy-mobile-jumbo;
.font-hierarchy-mobile-headline-1;
.font-hierarchy-mobile-headline-2;
.font-hierarchy-mobile-title-1;
.font-hierarchy-mobile-title-2;
.font-hierarchy-mobile-title-3;
.font-hierarchy-mobile-body-1;
.font-hierarchy-mobile-body-2;
.font-hierarchy-mobile-caption-1;
.font-hierarchy-mobile-caption-2;
Desktop Font Hierarchy
.font-hierarchy-desktop-jumbo;
.font-hierarchy-desktop-headline-1;
.font-hierarchy-desktop-headline-2;
.font-hierarchy-desktop-title-1;
.font-hierarchy-desktop-title-2;
.font-hierarchy-desktop-title-3;
.font-hierarchy-desktop-body-1;
.font-hierarchy-desktop-body-2;
.font-hierarchy-desktop-caption-1;
.font-hierarchy-desktop-caption-2;
Listbox
A listbox (also known as a select) allows the user to select one item from a list of options.
The purpose of a listbox is to collect form data; therefore a listbox should always be used in conjunction with a form, label and submit button. If you are not submitting form data, then a menu maybe a better choice.
IMPORTANT: The examples below show the listbox in isolation, without any label. Please see the field module for details on labelling controls. Remember: every listbox requires a label!
Default Listbox
The default listbox is prefilled with a selected option.
Unselected Listbox
If no suitable default value exists, the first option in the list can be used as a prompt and set to disabled & selected.
Fluid Listbox
Use the listbox__control--fluid element modifier (or fluid utility class) to fill all horizontal space of the parent element.
Borderless Listbox
For a borderless listbox, apply the listbox__control--borderless modifier.
Menu
A menu follows the principal of progressive disclosure, it keeps secondary commands hidden from view until needed. Menus are not form controls. If you wish to submit form data, please consider checkbox, listbox or radio instead.
Selecting a menu item command should update the page without a full page reload (i.e. acting similar to buttons, checkboxes or radios). If a full page load is required instead (i.e. acting like links), please see the fake menu section for more details.
NOTE: The examples below use a simple jquery-menu plugin to toggle the aria state of the menu button and menu items when clicked. The plugin also implements arrow-key navigation for keyboard accessibility.
Default Menu
For a stateless menu, use role menuitem on each menu item.
Menu item 1
Menu item 2
Menu item 3
Radio Menu
For single-select state, use role menuitemradio on each menu item.
Radio menu item 1
Radio menu item 2
Radio menu item 3
Checkbox Menu
For multi-select state, use role menuitemcheckbox on each menu item.
Checkbox menu item 1
Checkbox menu item 2
Checkbox menu item 3
Fake Menu
A fake menu looks like a normal menu widget, but it contains a list of hyperlinks (instead of a menu of menuitems) and thus behaves more like a navigational widget.
A valid HREF attribute is required for all anchor tags. A value of "javascript" (or any such variant) is not a valid URL!
Use the aria-current attribute to denote the link that matches the current page URL (if applicable).
TIP: A fake menu can contain a mix of anchor tags and button tags.
Growth Menu
Use the menu__items--grow or fake-menu__items--grow element modifier to slightly grow the width of any menu items container. This is useful in cases where the menu overlay needs to be slightly wider than the button, usually to accomodate menu items with long text.
NOTE: The growth modifier only works on menus that use a span tag.
Item 1 - Lorem ipsum dolor sit amet
Item 2
Item 3
Use the menu__items--grow-reverse or fake-menu__items--grow-reverse element modifier to grow the width of the menu overlay in reverse direction.
Item 1 - Lorem ipsum dolor sit amet
Item 2
Item 3
Tray Menu
For a menu button that expands like a tray, pushing down all content below it, use the menu__items--tray element modifier.
Menu item 1
Menu item 2
Menu item 3
Buttonless Menu BETA
Any menu can be presented as a buttonless menu, simply by omitting the button element.
TIP: Notice that the positions of the status icon and label have been flipped in this example, simply by flipping the DOM order.
Checkbox menu item 1
Checkbox menu item 2
Checkbox menu item 3
Notice
The purpose of a notice is to convey the next course of action for a task or flow. The notice must be clear and concise, with minimum cognitive load.
A notice may appear at page-level, inline-level or flyout-level, and may have a status of priority, confirmation, or information.
A page-level notice typically appears prominently at the top of the page or directly above a module. To aid discoverabilty of such important content for assistive technology, we make each page notice a landmark region with heading.
Use the page-notice--priority, page-notice--confirmation, or page-notice--information block modifiers depending on the relevant status.
By default, the text will vertically align to the top of the status icon. To vertically align text with the middle of status icon, use the .page-notice__cell--align-middle element modifier. This modifier is appropriate for short, single-line notices.
A flyout-level notice points to a specific section or element of the page. We can also says this element hosts the flyout.
The DOM order of the notice and it's host is important! To avoid keyboard and screen reader accessibility issues, the flyout element's DOM position should be adjacent to it's host.
Flyout notices are absolutely positioned by default. The flyout will be positioned relatively to the nearest ancestor with position:relative.
The flyout pointer can be positioned using any one of the following elements: flyout-notice__pointer-top-left, flyout-notice__pointer-top-center, flyout-notice__pointer-top-right, flyout-notice__pointer-bottom-right, flyout-notice__pointer-bottom-center, flyout-notice__pointer-bottom-left, flyout-notice__pointer-left or flyout-notice__pointer-right.
We had trouble connecting to PayPal. Please make your payment later.
Congrats! You are currently the high bidder, but you are close to getting outbid.
We could not find any items that match your search. Try expanding your search to find more items.
NOTE: This example uses a simple jquery-click-flyout plugin to toggle the aria-expanded state of the button when clicked.
Pagination BETA
Pagination allows a user to navigate back and forwards through a URL based dataset, or jump directly to any specific URL in that set.
Pagination links may update the results immediately on the client via AJAX, or on the server via a full page reload.
NOTE: The heading need only be wrapped in an ARIA live-region if client-side pagination is implemented (i.e. partial page updates).
Fluid Pagination
Apply the pagination__items--fluid modifier class to fill all available horizontal space. Horizontal space will be distributed around each pagination item as necessary.
Radio
A radio button is a form control thats allow a user to select a single option from a group of choices.
The purpose of a radio button is to collect form data; therefore radios should always be used in conjunction with a form, label and submit button.
A radio button requires the following SVG symbol definition:
Default Radio
Use the radio base class to create a radio.
The radio is decoupled from it's real text label to allow more flexibility in terms of layout. How and where you provide this label is up to you, but do not forget it!
The hidden attribute ensures that the SVG icon is not visible when CSS is disabled and also helps prevent a flash of unstyled content (FOUC).
Disabled Radio
Use the disabled attribute to disable any radio input.
Grouped Radio
A group of radios enforces single-select (unlike a group of checkboxes which allows multi-select).
A fieldset and legend are required in order to create the correct grouping semantics. Note that the Skin global module removes the default fieldset border and padding.
TIP: To stack radio buttons vertically instead of side-by-side, simply replace the span wrapper with a div wrapper.
Custom Radio BETA
Use the radio__custom-control element class to create a custom styled radio that can use any inline SVG for it's checked and unchecked states.
Be careful with custom radios; if a user cannot tell the icons represent an interactive control, they may skip over it entirely.
NOTE: below is just an example of how custom radios could be used; view option customizaton does not necessarly always need to be implemented with radio buttons.
Spinner
A spinner animation is used to convey a busy or loading state.
A spinner is considered a critical graphic, therefore an img role and aria-label property are required.
Large Spinner
Use the spinner--large modifier class to create a large spinner.
SVG
Skin is in the midst of a transition from a font-based icon system to an SVG-based icon system.
The source code for each SVG symbol is listed below. Each symbol must be defined inside of an <svg hidden></svg> block on the same page as where the symbol will be used. Alternatively, the symbols can be stored and referenced via an external SVG file, however a polyfill is required for legacy browsers.
Use the svg-icon class on your <svg> tag to create an icon sized version of the graphic. The height and width attributes are set to sensible defaults for a non-CSS state.
Chevrons
Light Chevrons
Status
View Options
Form Controls
Misc
Switch
A switch behaves like a checkbox - it can be on or off (i.e checked or unchecked) - and under the hood, that's exactly what it is. Whereas checkboxes are often used to allow multi-selection from a group of choices, switches are more often used in isolation or as a series of unrelated options.
IMPORTANT: The example below shows the switch in isolation, without any label. Please see the field module for details on labelling controls. Remember: every switch requires a label!
Tab
A tab is a control that allows the user to select and display a single panel of content from a group of choices. By decluttering the user-interface in this way, we say that a tab follows the principals of progressive disclosure.
Selecting a tab should update the visible panel without a full page reload. If a full page load is required instead (i.e. acting like a link), please see the fake tab section below for more details.
NOTE: The non-fake examples below use a simple jquery-tabs plugin to toggle the aria state of the tabs when clicked. The plugin also implements roving-tabindex based arrow-key navigation for keyboard accessibility.
Default Tab
When a tab is selected, the aria-selected state of all tabs in the list must be updated in order for the CSS to reflect the change. Only one tab can be selected and in the tab order at any moment in time. Likewise, only one tabpanel can be visible at any time, and it must correspond to the currently selected tab.
Tab 1
Tab 2
Tab 3
Panel 1 Content
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet assumenda culpa est nisi porro quae quidem ratione repellendus, temporibus. Assumenda atque dolor dolorem eligendi eveniet ipsam modi necessitatibus quos ut?
Panel 2 Content
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet assumenda culpa est nisi porro quae quidem ratione repellendus, temporibus. Assumenda atque dolor dolorem eligendi eveniet ipsam modi necessitatibus quos ut?
Panel 3 Content
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet assumenda culpa est nisi porro quae quidem ratione repellendus, temporibus. Assumenda atque dolor dolorem eligendi eveniet ipsam modi necessitatibus quos ut?
Fake Tab
A fake tab looks like a normal tab, but is actually a hyperlink to a new page. Therefore a set of fake tabs behaves more like a simple navigational widget, rather than a dynamic user interface control.
A valid HREF attribute is required for all anchor tags. A value of "javascript" (or any such variant) is not a valid URL!
The fake-tabs__item--current class is used to visually denote the current link. The aria-current attribute is used to programmatically denote the current page state.
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet assumenda culpa est nisi porro quae quidem ratione repellendus, temporibus. Assumenda atque dolor dolorem eligendi eveniet ipsam modi necessitatibus quos ut?
Textbox
A textbox (also known as an input) allows the user to enter data.
The purpose of a textbox is to collect form data; therefore it should always be used in conjunction with a form, label and submit button.
IMPORTANT: The examples below show the textbox in isolation, without any label. Please see the field module for details on labelling controls. Remember: every textbox requires a label!
Single-Line Textbox
Use an input tag for a single-line textbox.
Multi-line Textbox
Use the textarea tag for a multi-line textbox.
A multi-line textbox allows line breaks and has a minimum height of 200px.
Fluid Textbox
Apply the textbox__control--fluid modifier (or fluid utility class) to fill the width of the parent element.
Textbox with Icon
Single-line textboxes can be augmented with any inline SVG icon, using a textbox__icon element before the control. Font-icons are no longer supported.
NOTE: The icon is presentational, and therefore hidden from assistive technology using aria-hidden. Remember, the purpose of the field must be conveyed using a label.
Utility
Skin provides a small set of utility classes. Typically these classes will not conflict with styles set by BEM, and in some cases are applied directly by our Experience Service backend.
Our utility module is not intended as a general-purpose library of utility classes (i.e. it is not Funcssion!).