1
0
mirror of https://github.com/cjcenizal/flexbox-patterns.git synced 2025-08-06 16:16:33 +02:00

Initial commit: a bunch of patterns and a build command.

This commit is contained in:
CJ Cenizal (MacBook Air)
2016-01-02 21:27:50 -08:00
commit 6f5b31c4dc
18 changed files with 1415 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
node_modules
.DS_Store
.sass-cache
*.log

23
README.md Normal file
View File

@@ -0,0 +1,23 @@
# Flexbox Patterns
This repository contains the original SCSS used for the
components at [www.flexboxpatterns.com](http://www.flexboxpatterns.com).
Feel free to use these styles however you like!
## Getting started
Assuming you have Node installed, you can install the project dependencies with
`npm install`. This will install PostCSS and Autoprefixer; two critical tools
for making your CSS cross-browser compatible.
This project also requires you have [SASS](http://sass-lang.com/) installed
(`sudo gem install sass`).
## Commands
`npm run build`
I've chosen to write the styles with SCSS since it's widely adopted and I've
found that it makes me more productive. This command will compile the SCSS into
CSS and add various vendor-prefixed properties. Open up `dist/index.html`
to see a demo page of the various flexbox patterns in the browser.

176
dist/index.html vendored Normal file
View File

@@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Flexbox Patterns Demo Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="http://fonts.googleapis.com/css?family=Lato:300,400,700|Ubuntu+Mono" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link href="styles.css" rel="stylesheet" type="text/css">
<style>
body {
padding: 40px;
font-family: "Lato", "Helvetica", sans-serif;
font-size: 14px;
line-height: 1.5;
}
.demo {
max-width: 500px;
margin-bottom: 40px;
}
</style>
</head>
<body>
<!-- Card group -->
<div class="demo">
<div class="cardGroup">
<div class="card cardGroup__card">
<div class="card__description cardGroup__cardDescription">
<div class="icon fa fa-thumbs-o-up card__descriptionIcon"></div>
<div class="card__descriptionText">Trial</div>
</div>
<div class="card__price">Free!</div>
</div>
<div class="card cardGroup__card">
<div class="card__description cardGroup__cardDescription">
<div class="icon fa fa-trophy card__descriptionIcon"></div>
<div class="card__descriptionText">Basic tier<br/>(most popular)</div>
</div>
<div class="card__price">$10.00</div>
</div>
<div class="card cardGroup__card">
<div class="card__description cardGroup__cardDescription">
<div class="icon fa fa-bolt card__descriptionIcon"></div>
<div class="card__descriptionText">Advanced tier<br/>(only for enterprise-level professionals)</div>
</div>
<div class="card__price">$6,000.00</div>
</div>
</div>
</div>
<!-- Card -->
<div class="demo">
<div class="card card--fixedWidth">
<div class="card__description">
<div class="icon fa fa-flask card__descriptionIcon"></div>
<div class="card__descriptionText">Science potion</div>
</div>
<div class="card__price">Costs $5</div>
</div>
</div>
<!-- Centered icon -->
<div class="demo">
<div class="centeredIcon">
<div class="icon fa fa-phone"></div>
</div>
</div>
<!-- Centered prompt -->
<div class="demo">
<div class="centeredPrompt">
<div class="centeredPrompt__item centeredPromptIcon">
<div class="icon fa fa-smile-o"></div>
</div>
<div class="centeredPrompt__item centeredPromptLabel">Welcome to the app!</div>
<div class="centeredPrompt__item centeredPromptDetails">Thanks for signing up. Let&rsquo;s take a look around.</div>
<div class="centeredPrompt__item button">Begin tour</div>
</div>
</div>
<!-- Feature list -->
<div class="demo">
<div class="featureListItem">
<div class="featureListItem__icon">
<div class="icon fa fa-calendar"></div>
</div>
<div class="featureListItem__description">The calendar feature makes scheduling a snap.</div>
</div>
<div class="featureListItem featureListItem--reverse">
<div class="featureListItem__icon">
<div class="icon fa fa-dashboard"></div>
</div>
<div class="featureListItem__description">Our dashboard gives you a bird&rsquo;s-eye-view-at-a-glance-on-the-go.</div>
</div>
<div class="featureListItem">
<div class="featureListItem__icon">
<div class="icon fa fa-envelope"></div>
</div>
<div class="featureListItem__description">You can get notified by email or SMS.</div>
</div>
</div>
<!-- Form footer -->
<div class="demo">
<div class="formFooter">
<!-- This section gets pushed to the left side-->
<div class="formFooter__section">
<div class="formFooter__item formFooterFeedback">
<div class="fa fa-spinner formFooterSpinner"></div>&nbsp;Saving...
</div>
</div>
<!-- This section gets pushed to the right side-->
<div class="formFooter__section">
<div class="formFooter__item button button--clear">Reset</div>
<div class="formFooter__item button">Save</div>
</div>
</div>
</div>
<!-- Side bar -->
<div class="demo">
<div class="sideBar">
<!-- This section gets pushed to the top-->
<div class="sideBar__section">
<div class="sideBar__item is-side-bar-item-selected">Inbox</div>
<div class="sideBar__item">Contacts</div>
<div class="sideBar__item">Account</div>
</div>
<!-- This section gets pushed to the bottom-->
<div class="sideBar__section">
<div class="sideBar__item">Legal</div>
</div>
</div>
</div>
<!-- Site header -->
<div class="demo">
<div class="siteHeader">
<!-- This section gets pushed to the left side-->
<div class="siteHeader__section">
<div class="siteHeader__item siteHeaderLogo">
<div class="fa fa-inbox"></div>
</div>
<div class="siteHeader__item siteHeaderButton is-site-header-item-selected">Inbox</div>
<div class="siteHeader__item siteHeaderButton">Sent</div>
<div class="siteHeader__item siteHeaderButton">Trash</div>
</div>
<!-- This section gets pushed to the right side-->
<div class="siteHeader__section">
<div class="siteHeader__item siteHeaderButton">Settings</div>
</div>
</div>
</div>
<!-- Stepper input -->
<div class="demo">
<div class="stepperInput">
<button class="button button--addOnLeft">-</button>
<input type="text" placeholder="Age" value="32" class="input stepperInput__input"/>
<button class="button button--addOnRight">+</button>
</div>
</div>
<!-- Tabs -->
<div class="demo">
<div class="tabs">
<div class="tab is-tab-selected">Tab 1</div>
<div class="tab">Tab 2</div>
<div class="tab">Tab 3</div>
<div class="tab">Tab 4</div>
</div>
</div>
</body>
</html>

500
dist/styles.css vendored Normal file
View File

@@ -0,0 +1,500 @@
.stepperInput {
/**
* Setting display to flex makes this container lay
* out its children using flexbox. By default, it
* orders items horizontally, top-aligned.
* This has a similar effect to setting the children
* to have display: inline-block.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex; }
.stepperInput__input {
border-left: 0;
border-right: 0;
width: 60px;
text-align: center; }
.button {
cursor: pointer;
padding: 5px 15px;
color: #FFFFFF;
background-color: #4EBBE4;
font-size: 12px;
border: 1px solid #16A2D7;
border-radius: 4px; }
.button--addOnLeft {
border-top-right-radius: 0;
border-bottom-right-radius: 0; }
.button--addOnRight {
border-top-left-radius: 0;
border-bottom-left-radius: 0; }
.input {
border: 1px solid #D7DBDD;
padding: 0 10px;
border-radius: 0;
box-shadow: none; }
.tabs {
/**
* Setting display to flex makes this container lay
* out its children using flexbox, the exact same
* as in the above "Stepper input" example.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
border-bottom: 1px solid #D7DBDD; }
.tab {
cursor: pointer;
padding: 5px 30px;
color: #16A2D7;
font-size: 12px;
border-bottom: 2px solid transparent; }
.tab.is-tab-selected {
border-bottom-color: #4EBBE4; }
.siteHeader {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* Make the container put as much space as possible
* between its children, with the children at either
* end laying flush against the container's edges.
*/
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
padding: 10px;
background-color: #56727C; }
.siteHeader__section {
/**
* Lay out the children of this container with
* flexbox.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* Align the children in the center, along
* the main axis. By default the children will
* align along their top edges.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center; }
.siteHeader__item {
padding: 5px 15px;
font-size: 12px; }
.siteHeader__item + .siteHeader__item {
margin-left: 5px; }
.siteHeader__item.is-site-header-item-selected {
color: #FFFFFF;
background-color: #415F69;
border-radius: 4px; }
.siteHeaderLogo {
font-size: 20px;
line-height: 0;
color: white; }
.siteHeaderButton {
cursor: pointer;
color: #D9E9EF; }
.formFooter {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* Align the children in the center, along
* the main axis, which is horizontal in this case.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
/**
* Make the container put as much space as possible
* between its children, with the children at either
* end laying flush against the container's edges.
*/
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
border-top: 1px solid #D7DBDD;
padding: 10px; }
.formFooter__section {
/**
* This container orders items horizontally.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* It aligns them vertically in the center.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center; }
.formFooter__item + .formFooter__item {
margin-left: 5px; }
.formFooterFeedback {
color: #86969C;
font-size: 12px;
line-height: 0; }
.formFooterSpinner {
-webkit-animation: formFooterSpinner 1s infinite steps(8, end);
animation: formFooterSpinner 1s infinite steps(8, end); }
@-webkit-keyframes formFooterSpinner {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
@keyframes formFooterSpinner {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg); }
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg); } }
.button--clear {
color: #16A2D7;
background-color: #FFFFFF;
border: 1px solid #FFFFFF; }
.sideBar {
/**
* This container orders items according to flexbox
* rules. By default, this would arrange its children
* horizontally. However, the next property...
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* ...sets the main axis to be vertical instead of
* horizontal, so now the children are laid out
* vertically, from top to bottom.
*/
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
/**
* It will also put as much space as possible
* between its children, with the children at either end
* laying flush against the container's edges.
*/
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
height: 300px;
width: 150px;
border-right: 1px solid #D7DBDD;
background-color: #FCFDFD;
padding: 10px; }
.sideBar__item {
cursor: pointer;
padding: 5px 10px;
color: #16A2D7;
font-size: 12px; }
.sideBar__item.is-side-bar-item-selected {
background-color: #EEF3F5;
border-radius: 4px; }
.centeredPrompt {
/**
* Lay out the children of this container with
* flexbox.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* Rotate the main axis so that the children
* are laid out vertically, the same as in the
* above "Side bar" example.
*/
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
/**
* Align the children in the center, along
* the main axis. Because the direction is
* "column" this has a similar effect as setting
* text-align: center.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
/**
* Instead of pushing the children apart, as in
* previous examples, we will group them together
* in the center of their container.
*/
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
min-height: 300px;
padding: 10px; }
.centeredPrompt__item + .centeredPrompt__item {
margin-top: 5px; }
.centeredPromptIcon {
font-size: 60px;
line-height: 0; }
.centeredPromptLabel {
color: #86969C;
font-size: 30px;
font-weight: 700;
text-align: center; }
.centeredPromptDetails {
color: #86969C;
font-size: 16px;
margin-bottom: 10px;
text-align: center; }
.icon {
color: #BCD2DA; }
.centeredIcon {
/**
* Lay out the children of this container with
* flexbox.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* As in the above "Centered prmopt" example,
* we'll rotate the main axis so that the children
* are ordered vertically.
*/
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
/**
* And just like in that example, align the children
* in the center, along the main axis.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
/**
* Same thing here as before: group the children
* together in the center of their container.
*/
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
border: 1px solid #D7DBDD;
font-size: 40px;
width: 90px;
height: 90px;
border-radius: 100%;
box-shadow: 0 2px 1px rgba(0, 0, 0, 0.05), 0 2px 3px rgba(0, 0, 0, 0.05), 0 4px 8px rgba(0, 0, 0, 0.05); }
.featureListItem {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* Align the children in the center, along
* the main axis, which is horizontal in this case.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
max-width: 400px;
padding: 10px; }
.featureListItem + .featureListItem {
border-top: 1px solid #D7DBDD; }
.featureListItem--reverse {
/**
* We can specify the flex-direction so that
* the children elements are displayed in the
* reverse order of how they appear in the
* markup.
*/
-webkit-flex-direction: row-reverse;
-ms-flex-direction: row-reverse;
flex-direction: row-reverse; }
.featureListItem__icon,
.featureListItem__description {
padding: 5px 15px; }
.featureListItem__icon {
font-size: 50px;
line-height: 0; }
.featureListItem__description {
color: #86969C;
font-size: 12px; }
.card {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* Rotate the main axis so that the children
* are laid out vertically.
*/
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
border: 1px solid #CAD0D2;
border-radius: 4px;
overflow: hidden; }
.card__description {
/**
* Lay out the children of this container with
* flexbox.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
/**
* We're going to lay out this element's children
* just like in the "Centered prompt" example.
* First we'll rotate the main axis so that the
* children are laid out vertically.
*/
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
/**
* Just like in the "Centered prompt" example,
* we'll align the children in the center, along
* the main axis.
*/
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
/**
* And just like in the "Centered prompt", we'll
* group the children in the center of their
* container.
*/
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
padding: 15px; }
.card__descriptionIcon {
font-size: 32px;
margin-bottom: 10px; }
.card__descriptionText {
color: #57727C;
font-size: 12px;
text-align: center; }
.card__price {
text-align: center;
color: #57727C;
font-size: 12px;
font-weight: 700;
padding: 5px 15px;
border-top: 1px solid #D7DBDD;
background-color: #EEF3F5; }
.card--fixedWidth {
max-width: 120px; }
.cardGroup {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
border: 1px solid #CAD0D2;
border-radius: 4px;
overflow: hidden; }
.cardGroup__card {
/**
* The flex property is a short-hand for setting
* the flex-shrink, flex-grow, and flex-basis
* properties. These properties control how the
* element resizes to fill its container.
*
* We'll also set flex-grow to 1 so that it
* will expand to fill its container. (The
* default value is 1.)
*
* We'll set flex-shrink to 1 so that the element
* will shrink as its container gets smaller.
* (The default value is 0.)
*
* Last, we set flex-basis to 0 so that its
* size is solely determined by the size of
* the container. (The default value
* is auto, which would cause the content's
* size to also be a factor in this calculation.)
*
* The net result of these properties is that the
* element is a fluid size, and will expand and
* shrink with its container and siblings, but
* they will all have the same size, even if they
* have different amounts of content.
*/
-webkit-flex: 1 1 0;
-ms-flex: 1 1 0;
flex: 1 1 0;
border: none;
border-radius: 0; }
.cardGroup__card + .cardGroup__card {
border-left: 1px solid #D7DBDD; }
.cardGroup__cardDescription {
/**
* We're doing almost the exact same thing here as
* we did above. The difference is that its
* flex-basis is auto, so now the size of its content
* will affect how large it is.
*/
-webkit-flex: 1 1 auto;
-ms-flex: 1 1 auto;
flex: 1 1 auto; }
/*# sourceMappingURL=styles.css.map */

7
dist/styles.css.map vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"version": 3,
"mappings": "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",
"sources": ["../src/styles/stepper-input.scss","../src/styles/tabs.scss","../src/styles/site-header.scss","../src/styles/form-footer.scss","../src/styles/side-bar.scss","../src/styles/centered-prompt.scss","../src/styles/centered-icon.scss","../src/styles/feature-list.scss","../src/styles/card.scss","../src/styles/card-group.scss"],
"names": [],
"file": "styles.css"
}

18
package.json Normal file
View File

@@ -0,0 +1,18 @@
{
"name": "flexbox-patterns",
"version": "0.0.1",
"description": "Patterns for using flexbox CSS to build awesome UI components",
"repository": "cjcenizal/flexbox-patterns",
"author": {
"name": "CJ Cenizal",
"email": "cj@cenizal.com",
"url": "http://www.cenizal.com/"
},
"devDependencies": {
"autoprefixer": "6.2.3",
"postcss-cli": "2.3.3"
},
"scripts": {
"build": "sass src/index.scss dist/styles.css && node_modules/.bin/postcss --local-plugins --use autoprefixer --autoprefixer.browsers 'last 2 versions' -o dist/styles.css dist/styles.css && cp src/index.html dist/index.html"
}
}

176
src/index.html Normal file
View File

@@ -0,0 +1,176 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Flexbox Patterns Demo Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="http://fonts.googleapis.com/css?family=Lato:300,400,700|Ubuntu+Mono" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link href="styles.css" rel="stylesheet" type="text/css">
<style>
body {
padding: 40px;
font-family: "Lato", "Helvetica", sans-serif;
font-size: 14px;
line-height: 1.5;
}
.demo {
max-width: 500px;
margin-bottom: 40px;
}
</style>
</head>
<body>
<!-- Card group -->
<div class="demo">
<div class="cardGroup">
<div class="card cardGroup__card">
<div class="card__description cardGroup__cardDescription">
<div class="icon fa fa-thumbs-o-up card__descriptionIcon"></div>
<div class="card__descriptionText">Trial</div>
</div>
<div class="card__price">Free!</div>
</div>
<div class="card cardGroup__card">
<div class="card__description cardGroup__cardDescription">
<div class="icon fa fa-trophy card__descriptionIcon"></div>
<div class="card__descriptionText">Basic tier<br/>(most popular)</div>
</div>
<div class="card__price">$10.00</div>
</div>
<div class="card cardGroup__card">
<div class="card__description cardGroup__cardDescription">
<div class="icon fa fa-bolt card__descriptionIcon"></div>
<div class="card__descriptionText">Advanced tier<br/>(only for enterprise-level professionals)</div>
</div>
<div class="card__price">$6,000.00</div>
</div>
</div>
</div>
<!-- Card -->
<div class="demo">
<div class="card card--fixedWidth">
<div class="card__description">
<div class="icon fa fa-flask card__descriptionIcon"></div>
<div class="card__descriptionText">Science potion</div>
</div>
<div class="card__price">Costs $5</div>
</div>
</div>
<!-- Centered icon -->
<div class="demo">
<div class="centeredIcon">
<div class="icon fa fa-phone"></div>
</div>
</div>
<!-- Centered prompt -->
<div class="demo">
<div class="centeredPrompt">
<div class="centeredPrompt__item centeredPromptIcon">
<div class="icon fa fa-smile-o"></div>
</div>
<div class="centeredPrompt__item centeredPromptLabel">Welcome to the app!</div>
<div class="centeredPrompt__item centeredPromptDetails">Thanks for signing up. Let&rsquo;s take a look around.</div>
<div class="centeredPrompt__item button">Begin tour</div>
</div>
</div>
<!-- Feature list -->
<div class="demo">
<div class="featureListItem">
<div class="featureListItem__icon">
<div class="icon fa fa-calendar"></div>
</div>
<div class="featureListItem__description">The calendar feature makes scheduling a snap.</div>
</div>
<div class="featureListItem featureListItem--reverse">
<div class="featureListItem__icon">
<div class="icon fa fa-dashboard"></div>
</div>
<div class="featureListItem__description">Our dashboard gives you a bird&rsquo;s-eye-view-at-a-glance-on-the-go.</div>
</div>
<div class="featureListItem">
<div class="featureListItem__icon">
<div class="icon fa fa-envelope"></div>
</div>
<div class="featureListItem__description">You can get notified by email or SMS.</div>
</div>
</div>
<!-- Form footer -->
<div class="demo">
<div class="formFooter">
<!-- This section gets pushed to the left side-->
<div class="formFooter__section">
<div class="formFooter__item formFooterFeedback">
<div class="fa fa-spinner formFooterSpinner"></div>&nbsp;Saving...
</div>
</div>
<!-- This section gets pushed to the right side-->
<div class="formFooter__section">
<div class="formFooter__item button button--clear">Reset</div>
<div class="formFooter__item button">Save</div>
</div>
</div>
</div>
<!-- Side bar -->
<div class="demo">
<div class="sideBar">
<!-- This section gets pushed to the top-->
<div class="sideBar__section">
<div class="sideBar__item is-side-bar-item-selected">Inbox</div>
<div class="sideBar__item">Contacts</div>
<div class="sideBar__item">Account</div>
</div>
<!-- This section gets pushed to the bottom-->
<div class="sideBar__section">
<div class="sideBar__item">Legal</div>
</div>
</div>
</div>
<!-- Site header -->
<div class="demo">
<div class="siteHeader">
<!-- This section gets pushed to the left side-->
<div class="siteHeader__section">
<div class="siteHeader__item siteHeaderLogo">
<div class="fa fa-inbox"></div>
</div>
<div class="siteHeader__item siteHeaderButton is-site-header-item-selected">Inbox</div>
<div class="siteHeader__item siteHeaderButton">Sent</div>
<div class="siteHeader__item siteHeaderButton">Trash</div>
</div>
<!-- This section gets pushed to the right side-->
<div class="siteHeader__section">
<div class="siteHeader__item siteHeaderButton">Settings</div>
</div>
</div>
</div>
<!-- Stepper input -->
<div class="demo">
<div class="stepperInput">
<button class="button button--addOnLeft">-</button>
<input type="text" placeholder="Age" value="32" class="input stepperInput__input"/>
<button class="button button--addOnRight">+</button>
</div>
</div>
<!-- Tabs -->
<div class="demo">
<div class="tabs">
<div class="tab is-tab-selected">Tab 1</div>
<div class="tab">Tab 2</div>
<div class="tab">Tab 3</div>
<div class="tab">Tab 4</div>
</div>
</div>
</body>
</html>

11
src/index.scss Normal file
View File

@@ -0,0 +1,11 @@
@import "styles/stepper-input";
@import "styles/tabs";
@import "styles/site-header";
@import "styles/form-footer";
@import "styles/side-bar";
@import "styles/centered-prompt";
@import "styles/centered-icon";
@import "styles/feature-list";
@import "styles/card";
@import "styles/card-group";

View File

@@ -0,0 +1,58 @@
.cardGroup {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: flex;
border: 1px solid #CAD0D2;
border-radius: 4px;
overflow: hidden;
}
.cardGroup__card {
/**
* The flex property is a short-hand for setting
* the flex-shrink, flex-grow, and flex-basis
* properties. These properties control how the
* element resizes to fill its container.
*
* We'll also set flex-grow to 1 so that it
* will expand to fill its container. (The
* default value is 1.)
*
* We'll set flex-shrink to 1 so that the element
* will shrink as its container gets smaller.
* (The default value is 0.)
*
* Last, we set flex-basis to 0 so that its
* size is solely determined by the size of
* the container. (The default value
* is auto, which would cause the content's
* size to also be a factor in this calculation.)
*
* The net result of these properties is that the
* element is a fluid size, and will expand and
* shrink with its container and siblings, but
* they will all have the same size, even if they
* have different amounts of content.
*/
flex: 1 1 0;
border: none;
border-radius: 0;
& + & {
border-left: 1px solid #D7DBDD;
}
}
.cardGroup__cardDescription {
/**
* We're doing almost the exact same thing here as
* we did above. The difference is that its
* flex-basis is auto, so now the size of its content
* will affect how large it is.
*/
flex: 1 1 auto;
}

74
src/styles/card.scss Normal file
View File

@@ -0,0 +1,74 @@
.card {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: flex;
/**
* Rotate the main axis so that the children
* are laid out vertically.
*/
flex-direction: column;
border: 1px solid #CAD0D2;
border-radius: 4px;
overflow: hidden;
}
.card__description {
/**
* Lay out the children of this container with
* flexbox.
*/
display: flex;
/**
* We're going to lay out this element's children
* just like in the "Centered prompt" example.
* First we'll rotate the main axis so that the
* children are laid out vertically.
*/
flex-direction: column;
/**
* Just like in the "Centered prompt" example,
* we'll align the children in the center, along
* the main axis.
*/
align-items: center;
/**
* And just like in the "Centered prompt", we'll
* group the children in the center of their
* container.
*/
justify-content: center;
padding: 15px;
}
.card__descriptionIcon {
font-size: 32px;
margin-bottom: 10px;
}
.card__descriptionText {
color: #57727C;
font-size: 12px;
text-align: center;
}
.card__price {
text-align: center;
color: #57727C;
font-size: 12px;
font-weight: 700;
padding: 5px 15px;
border-top: 1px solid #D7DBDD;
background-color: #EEF3F5;
}
.card--fixedWidth {
max-width: 120px;
}

View File

@@ -0,0 +1,36 @@
.centeredIcon {
/**
* Lay out the children of this container with
* flexbox.
*/
display: flex;
/**
* As in the above "Centered prmopt" example,
* we'll rotate the main axis so that the children
* are ordered vertically.
*/
flex-direction: column;
/**
* And just like in that example, align the children
* in the center, along the main axis.
*/
align-items: center;
/**
* Same thing here as before: group the children
* together in the center of their container.
*/
justify-content: center;
border: 1px solid #D7DBDD;
font-size: 40px;
width: 90px;
height: 90px;
border-radius: 100%;
box-shadow:
0 2px 1px rgba(#000000, 0.05),
0 2px 3px rgba(#000000, 0.05),
0 4px 8px rgba(#000000, 0.05);
}

View File

@@ -0,0 +1,61 @@
.centeredPrompt {
/**
* Lay out the children of this container with
* flexbox.
*/
display: flex;
/**
* Rotate the main axis so that the children
* are laid out vertically, the same as in the
* above "Side bar" example.
*/
flex-direction: column;
/**
* Align the children in the center, along
* the main axis. Because the direction is
* "column" this has a similar effect as setting
* text-align: center.
*/
align-items: center;
/**
* Instead of pushing the children apart, as in
* previous examples, we will group them together
* in the center of their container.
*/
justify-content: center;
min-height: 300px;
padding: 10px;
}
.centeredPrompt__item {
& + & {
margin-top: 5px;
}
}
.centeredPromptIcon {
font-size: 60px;
line-height: 0;
}
.centeredPromptLabel {
color: #86969C;
font-size: 30px;
font-weight: 700;
text-align: center;
}
.centeredPromptDetails {
color: #86969C;
font-size: 16px;
margin-bottom: 10px;
text-align: center;
}
.icon {
color: #BCD2DA;
}

View File

@@ -0,0 +1,45 @@
.featureListItem {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: flex;
/**
* Align the children in the center, along
* the main axis, which is horizontal in this case.
*/
align-items: center;
max-width: 400px;
padding: 10px;
& + & {
border-top: 1px solid #D7DBDD;
}
}
.featureListItem--reverse {
/**
* We can specify the flex-direction so that
* the children elements are displayed in the
* reverse order of how they appear in the
* markup.
*/
flex-direction: row-reverse;
}
.featureListItem__icon,
.featureListItem__description {
padding: 5px 15px;
}
.featureListItem__icon {
font-size: 50px;
line-height: 0;
}
.featureListItem__description {
color: #86969C;
font-size: 12px;
}

View File

@@ -0,0 +1,62 @@
.formFooter {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: flex;
/**
* Align the children in the center, along
* the main axis, which is horizontal in this case.
*/
align-items: center;
/**
* Make the container put as much space as possible
* between its children, with the children at either
* end laying flush against the container's edges.
*/
justify-content: space-between;
border-top: 1px solid #D7DBDD;
padding: 10px;
}
.formFooter__section {
/**
* This container orders items horizontally.
*/
display: flex;
/**
* It aligns them vertically in the center.
*/
align-items: center;
}
.formFooter__item {
& + & {
margin-left: 5px;
}
}
.formFooterFeedback {
color: #86969C;
font-size: 12px;
line-height: 0;
}
.formFooterSpinner {
animation: formFooterSpinner 1s infinite steps(8, end);
}
@keyframes formFooterSpinner {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.button--clear {
color: #16A2D7;
background-color: #FFFFFF;
border: 1px solid #FFFFFF;
}

40
src/styles/side-bar.scss Normal file
View File

@@ -0,0 +1,40 @@
.sideBar {
/**
* This container orders items according to flexbox
* rules. By default, this would arrange its children
* horizontally. However, the next property...
*/
display: flex;
/**
* ...sets the main axis to be vertical instead of
* horizontal, so now the children are laid out
* vertically, from top to bottom.
*/
flex-direction: column;
/**
* It will also put as much space as possible
* between its children, with the children at either end
* laying flush against the container's edges.
*/
justify-content: space-between;
height: 300px;
width: 150px;
border-right: 1px solid #D7DBDD;
background-color: #FCFDFD;
padding: 10px;
}
.sideBar__item {
cursor: pointer;
padding: 5px 10px;
color: #16A2D7;
font-size: 12px;
&.is-side-bar-item-selected {
background-color: #EEF3F5;
border-radius: 4px;
}
}

View File

@@ -0,0 +1,58 @@
.siteHeader {
/**
* Lay out the children of this container with
* flexbox, which is horizontal by default.
*/
display: flex;
/**
* Make the container put as much space as possible
* between its children, with the children at either
* end laying flush against the container's edges.
*/
justify-content: space-between;
padding: 10px;
background-color: #56727C;
}
.siteHeader__section {
/**
* Lay out the children of this container with
* flexbox.
*/
display: flex;
/**
* Align the children in the center, along
* the main axis. By default the children will
* align along their top edges.
*/
align-items: center;
}
.siteHeader__item {
padding: 5px 15px;
font-size: 12px;
& + & {
margin-left: 5px;
}
&.is-site-header-item-selected {
color: #FFFFFF;
background-color: #415F69;
border-radius: 4px;
}
}
.siteHeaderLogo {
font-size: 20px;
line-height: 0;
color: white;
}
.siteHeaderButton {
cursor: pointer;
color: #D9E9EF;
}

View File

@@ -0,0 +1,44 @@
.stepperInput {
/**
* Setting display to flex makes this container lay
* out its children using flexbox. By default, it
* orders items horizontally, top-aligned.
* This has a similar effect to setting the children
* to have display: inline-block.
*/
display: flex;
}
.stepperInput__input {
border-left: 0;
border-right: 0;
width: 60px;
text-align: center;
}
.button {
cursor: pointer;
padding: 5px 15px;
color: #FFFFFF;
background-color: #4EBBE4;
font-size: 12px;
border: 1px solid #16A2D7;
border-radius: 4px;
}
.button--addOnLeft {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.button--addOnRight {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.input {
border: 1px solid #D7DBDD;
padding: 0 10px;
border-radius: 0;
box-shadow: none;
}

22
src/styles/tabs.scss Normal file
View File

@@ -0,0 +1,22 @@
.tabs {
/**
* Setting display to flex makes this container lay
* out its children using flexbox, the exact same
* as in the above "Stepper input" example.
*/
display: flex;
border-bottom: 1px solid #D7DBDD;
}
.tab {
cursor: pointer;
padding: 5px 30px;
color: #16A2D7;
font-size: 12px;
border-bottom: 2px solid transparent;
&.is-tab-selected {
border-bottom-color: #4EBBE4;
}
}