Uptown CSS

Uptown CSS

Stylesheet for Shopify App Development

Beautiful Frontend Framework for Shopify App Development

A semantic toolkit designed to help developers create responsive Shopify apps utilizing the Embedded App SDK.

View on Github

Learn more about Uptown CSS or help contribute to the cause.

View Project

Download CSS

Get just the stylesheet to quickly add within your project.

Download CSS

Download Source

Get the SASS files to customize the stylesheet.

Download Source

Overview

How to Use

Add the stylesheet to your project and begin writing the HTML for your app.

<link rel="stylesheet" href="uptown.css">


Source Dependencies

The framework is a single file that imports .scss files for each component.

SASS + Autoprefixer

Uptown CSS is built using SASS and the Autoprefixer plugin for powerful vendor prefixing.

Autoprefixer is awesome and eliminates the need for constantly checking Can I Use for cross-browser compatibility.

No JavaScript. None. Zero. Zilch.

There are no JavaScript dependencies. You're free to use any library since Uptown CSS is JS agnostic.

Developed By

Author

I'm Ryan O'Donnell, head of frontend development and design over at ShopPad. Over 50,000 Shopify stores use apps from ShopPad and each one of them is built with Uptown CSS, so this framework has been battle-tested and is production ready. Now we've open sourced it to share with the awesome developer community.

Love Uptown? Help us spread the word

Sharing is caring.

Star Fork

Examples

Below are Shopify apps that use UptownCSS. Contact me if your app uses UptownCSS too!

Getting Started

Your markup should follow this basic structure. What you put inside each section, will depend on your app.

Source

<main> <header> ... </header> <section> ... </section> <footer> ... </footer> </main>

Grid Structure

The grid is a 12-column fluid grid with a max width of 1036px, that shrinks with the browser/device at smaller sizes.

twelve

one

eleven

two

ten

three

nine

four

eight

five

seven

six

six

one-half

one-half

two-thirds

Source

<!-- This is a single, full-width element --> <article> <div class="column twelve"> <p>twelve</p> </div> </article> <!-- Just use a number and class 'column' or 'columns' --> <article> <div class="columns two"> <p>two</p> </div> <div class="columns ten"> <p>ten</p> </div> </article> <!-- There are a few shorthand classes available too --> <article> <div class="column one-half"> <p>one-half</p> </div> <div class="column one-half"> <p>one-half</p> </div> </article> <article> <div class="column two-thirds"> <p>two-thirds</p> </div> <div class="column one-third"> <p>one-third</p> </div> </article>

Cards

This element is the canvas to put your app content within.

Card

Source

<article> <div class="card"> Card </div> </article>

Cards with sections

Add the class .has-sections to the .card element then just add .card-section elements with dividing <hr> tags.

Card Section

Card Section

Card Section

Source

<article> <div class="card has-sections"> <div class="card-section"> Card Section </div> <hr/> <div class="card-section"> Card Section </div> <hr/> <div class="card-section"> Card Section </div> </div> </article>

Layouts

Below are common layouts so you can quickly develop a familiar user experience.

Section Heading

content

Source

<aside> <h2>Aside Heading</h2> <p>content</p> </aside> <article> <div class="card"> <h5>Section Heading</h5> <p>content</p> </div> </article>

Full-width layout

Add the class .full-width to any element.

Card

Source

<section class="full-width"> <article> <div class="card"> Card </div> </article> </section>

Layout with side column

A layout to show a main and side column.

Card

Card

Source

<article> <div class="card columns eight"> <p>Card</p> </div> <div class="card columns four"> <p>Card</p> </div> </article>

Layout with secondary column

The class .secondary can be added to any .card to visually dimm that element.

Card

This card is slightly dimmed to give the primary card more visual importance

Source

<article> <div class="columns eight card"> <p>Card</p> </div> <div class="columns four card secondary"> <p>This card is slightly dimmed to give the primary card more visual importance</p> </div> </article>

Typography

Type is defined with rems, so font-sizes and spacial relationships can be responsively sized based on a single font-size property. All measurements are base 10 so an H1 with 4.0rem font-size just means 40px. The typography base is device driven; "San Francisco" for Apple devices and "Roboto", "Segoe UI" for Android device. "Helvetica Neue" is the fallback. Size is set at 1.4rem (14px). Other type basics like anchors, strong, emphasis, and underline are all included.

h1 Heading

h2 Heading

h3 Heading

h4 Heading

h5 Heading
h6 Heading

Paragraph text

Anchor Bold Underline
Preformatted text
Code
  • Unordered list item
  • Unordered list item
    • Unordered list item
    • Unordered list item
    • Unordered list item
  • Unordered list item
  1. Ordered list item
  2. Ordered list item
    1. Ordered list item
    2. Ordered list item
    3. Ordered list item
  3. Ordered list item
<h1>h1 Heading</h1> <h2>h2 Heading</h2> <h3>h3 Heading</h3> <h4>h4 Heading</h4> <h5>h5 Heading</h5> <h6>h6 Heading</h6> <p>Paragraph text</p> <a>Anchor</a> <strong>Bold</strong> <u>Underline</u> <pre>Preformatted text</pre> <code>Code</code> <ul> <li>Unordered list item</li> <li>Unordered list item <ul> <li>Unordered list item</li> <li>Unordered list item</li> <li>Unordered list item</li> </ul> </li> <li>Unordered list item</li> </ul> <ol> <li>Ordered list item</li> <li>Unordered list item <ol> <li>Unordered list item</li> <li>Unordered list item</li> <li>Unordered list item</li> </ol> </li> <li>Ordered list item</li> </ol>

Icons

Familiar icons are available and can be used on their own or within other elements.

Prev
Next
Trash
Clock
Close
Checkmark
Search
Flag
Bell
Exclamation
Question
Prohibit
Product
Collection
Preview
Edit
Addition
Subtraction
Calendar
Add Circle
Orders
Globe
Funnel
Percent
Payment
Discount
Report
Customer
Gear
Apps
Themes
Post
Pages
Navigation
Account
Folder
Gift Cards
Cart
Inventory
Home
Image
<i class="icon-prev"></i> <i class="icon-next"></i> <i class="icon-trash"></i> <i class="icon-clock"></i> <i class="icon-close"></i> <i class="icon-checkmark"></i> <i class="icon-search"></i> <i class="icon-flag"></i> <i class="icon-bell"></i> <i class="icon-exclamation"></i> <i class="icon-question"></i> <i class="icon-prohibit"></i> <i class="icon-product"></i> <i class="icon-collection"></i> <i class="icon-preview"></i> <i class="icon-edit"></i> <i class="icon-addition"></i> <i class="icon-subtraction"></i> <i class="icon-calendar"></i> <i class="icon-addcircle"></i> <i class="icon-orders"></i> <i class="icon-globe"></i> <i class="icon-funnel"></i> <i class="icon-percent"></i> <i class="icon-payment"></i> <i class="icon-discount"></i> <i class="icon-report"></i> <i class="icon-customers"></i> <i class="icon-gear"></i> <i class="icon-apps"></i> <i class="icon-themes"></i> <i class="icon-post"></i> <i class="icon-pages"></i> <i class="icon-navigation"></i> <i class="icon-account"></i> <i class="icon-folder"></i> <i class="icon-giftcards"></i> <i class="icon-cart"></i> <i class="icon-inventory"></i> <i class="icon-home"></i> <i class="icon-image"></i>

Placeholder Icons

Familiar placeholder images available.

<i class="image icon-photos"></i> <i class="image icon-profile"></i>

Buttons

Buttons support both the <button> and the <a> element. Only the <a> element requires a .button class to be appended. The button type is not a factor.

Default Secondary Warning Disabled
<button>Default</button> <button class="secondary">Secondary</button> <button class="warning">Warning</button> <button disabled="disabled">Disabled</button> <button class="link">Link</button> <a href="#" class="button">Default</a> <a href="#" class="button secondary">Secondary</a> <a href="#" class="button warning">Warning</a> <a href="#" class="button disabled">Disabled</a>

Button Groups

Wrap any set of buttons within an element having a class of .button-group.

<span class="button-group"> <button class="secondary">Left</button> <button class="secondary">Middle</button> <button class="secondary">Right</button> </span>

Icon Buttons

Add any supported icon without text. Disabled state is also supported to dim the icon color.

<button class="secondary icon-prev"></button> <button class="secondary icon-next"></button> <button class="secondary icon-trash"></button> <button class="secondary icon-calendar"></button> <!-- Icon button can also be disabled --> <button class="secondary icon-prev" disabled="disabled"></button> <button class="secondary icon-next" disabled="disabled"></button> <button class="secondary icon-trash" disabled="disabled"></button> <button class="secondary icon-calendar" disabled="disabled"></button>

Form Fields

Standard form fields. Wrap radio and checkbox elements with a label element.

<div class="row"> <label>Label</label> <input type="text" /> </div> <div class="row"> <label><input type="radio" name="option1a" checked="checked">Option</label> <label><input type="radio" name="option1a">Option</label> </div> <div class="row"> <select><option>Select</option></select> </div> <div class="row"> <label><input type="checkbox" name="option2a" checked="checked">Option</label> <label><input type="checkbox" name="option2a">Option</label> </div> <div class="row"> <textarea></textarea> </div>

Form Fields: Disabled

Disabled form field states are supported too. Add a disabled="disabled" attribute to any form field.

<div class="row"> <label>Label</label> <input type="text" disabled="disabled" /> </div> <div class="row"> <label><input type="radio" name="option3a" checked="checked" disabled="disabled">Option</label> <label><input type="radio" name="option3a" disabled="disabled">Option</label> </div> <div class="row"> <select disabled="disabled"><option>Select</option></select> </div> <div class="row"> <label><input type="checkbox" name="option4a" checked="checked" disabled="disabled">Option</label> <label><input type="checkbox" name="option4a" disabled="disabled">Option</label> </div> <div class="row"> <textarea disabled="disabled"></textarea> </div>

Form Fields: Errors

Add .error class to the parent .row or to the <label> for checkboxes and radio elements.

<div class="row error"> <label>Label</label> <input type="text" /> </div> <div class="row"> <label><input type="radio" name="option5a" checked="checked">Option</label> <label class="error"><input type="radio" name="option5a">Option</label> </div> <div class="row error"> <select><option>Select</option></select> </div> <div class="row"> <label><input type="checkbox" name="option6a" checked="checked">Option</label> <label class="error"><input type="checkbox" name="option6a">Option</label> </div> <div class="row error"> <textarea></textarea> </div>

Search

Use the input type search. No extra classes required.

<input type="search" />

Side Elements

Add .side-elements to the parent .row element. All elements within will stretch automatically to be on a single line.

<div class="row side-elements"> <label>Label</label> <input type="text" /> <button>Action</button> </div>

Advanced Form Element

The .label-cta class will pull any element to the right.

Context help text
<label>Label <a href="#" class="label-cta">Link</a></label> <input type="text" /> <em>Context help text</em>

Append Field Elements

Use an element with a class .input-group. Add elements with .append class. Place them before or after the form field.

Prefix
Suffix
$ .00
<div class="input-group"> <span class="append">Prefix</span> <input type="text" /> </div> <div class="input-group"> <input type="text" /> <span class="append">Suffix</span> </div> <div class="input-group"> <span class="append">$</span> <input type="text" /> <span class="append">.00</span> </div>

Append Field Buttons

Use an element with a class .input-group. Add <button> or .button elements. Place them before or after the form field.

<div class="input-group"> <input type="text" /> <button class="secondary">Button</button> </div> <div class="input-group"> <button class="secondary">Filter</button> <input type="text" /> <button class="secondary">Save</button> <button class="secondary icon-trash"></button> </div>

Hover Tips

Add a class .tip to any element. Add the tip's text as a data-hover attribute. The hover event will automatically pull the text without any JavaScript needed.

Paragraph Text

Lorem ipsum dolor consectetur adipiscing elit.

Links

Hover for a tip

Buttons

<a class="tip" href="#" data-hover="You found me!"> <button class="tip" data-hover="You rebel">Hover Me</button>

Alerts

The container element needs a class .alert. Add .notice, .success, .warning, .notification or .error for the desired icon and color. The <dl> element is for the title and description text. Adding a .close element or <button> elements are optional.

General Alert
General Alert with Close
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis leo purus, rhoncus id ultrices vitae, feugiat non neque.
General Alert with Button
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis leo purus, rhoncus id ultrices vitae. Learn More
Notice Alert
Lorem ipsum dolor sit amet, consectetur adipiscing elit leo purus, rhoncus id ultrices vitae.
Success Alert
Lorem ipsum dolor sit amet, consectetur adipiscing elit leo purus, rhoncus id ultrices vitae.
Warning Alert
Lorem ipsum dolor sit amet, consectetur adipiscing elit leo purus, rhoncus id ultrices vitae.
Notification Alert
Lorem ipsum dolor sit amet, consectetur adipiscing elit leo purus, rhoncus id ultrices vitae.
Error Alert
Lorem ipsum dolor sit amet, consectetur adipiscing elit leo purus, rhoncus id ultrices vitae.
<div class="alert"> <dl> <dt>General Alert</dt> </dl> </div> <div class="alert"> <a class="close" href="#"></a> <dl> <dt>General Alert with Close</dt> <dd>...</dd> </dl> </div> <div class="alert"> <dl> <dt>General Alert with Button</dt> <dd>... <a href="#">Learn More</a></dd> </dl> <button>Change</button> </div> <div class="alert notice"> <dl> <dt>Notice Alert</dt> <dd>...</dd> </dl> </div> <div class="alert success"> <dl> <dt>Success Alert</dt> <dd>...</dd> </dl> </div> <div class="alert warning"> <dl> <dt>Warning Alert</dt> <dd>...</dd> </dl> </div> <div class="alert notification"> <dl> <dt>Notification Alert</dt> <dd>...</dd> </dl> </div> <div class="alert error"> <dl> <dt>Error Alert</dt> <dd>...</dd> </dl> </div>

Tables

Default <table> containing various types of content. Add a container wrapper with a class .overflow-container if the table needs to be scrollable on smaller screens.

Source

<table> <thead> <tr> <th colspan="2">Product</th> <th>Status</th> <th>Action</th> </tr> </thead> <tbody> <tr> <td><a href="#"><img width="35" height="35" alt="" src="images/image-none.svg"></a></td> <td><a href="#">Some Product</a></td> <td></td> <td><button class="secondary icon-trash"></button></td> </tr> <tr> <td><a href="#"><img width="35" height="35" alt="" src="images/image-none.svg"></a></td> <td><a href="#">Another Product</a></td> <td><ul> <li>This product has no images.</li> <li>This product has no description.</li> <li>This product must be at least $0.01.</li> </ul></td> <td></td> </tr> <tr> <td><a href="#"><img width="35" height="35" alt="" src="images/image-none.svg"></a></td> <td><a href="#">One More Product</a></td> <td><ul> <li>This product must be at least $0.01.</li> </ul></td> <td></td> </tr> </tbody> </table>

Table with tags & buttons

Default <table> element showing buttons and tags elements.

Source

<table> <thead> <tr> <th></th> <th>Product</th> <th>Status</th> <th>Action</th> </tr> </thead> <tbody> <tr> <td>Text</td> <td><a href="#">Some Product</a></td> <td><span class="tag yellow">Approved</span></td> <td><button class="secondary">Button</button></td> </tr> <tr> <td>Text</td> <td><a href="#">Some Product</a></td> <td><span class="tag orange">Pending</span></td> <td><button class="secondary">Button</button></td> </tr> <tr> <td>Text</td> <td><a href="#">Some Product</a></td> <td><span class="tag grey">Paid</span></td> <td><button class="secondary">Button</button></td> </tr> </tbody> </table>

Results Table

A <table> showing a list of results. Use the .pagination container around the .button-group.

Name Location Orders Last Order Total Spent
John Doe Oakland, CA 1 #1001 $125.00
Jane Doe Oakland, CA 0 $0.00
Mike Smith San Francisco, CA 1 #1002 $100.00

Source

<table class="results"> <thead> <tr> <th>Name</th> <th>Location</th> <th>Orders</th> <th>Last Order</th> <th class="align-right">Total Spent</th> </tr> </thead> <tbody> <tr> <td>John Doe</td> <td>Oakland, CA</td> <td>1</td> <td><a href="#">#1001</a></td> <td class="align-right">$125.00</td> </tr> <tr> <td>Jane Doe</td> <td>Oakland, CA</td> <td>0</td> <td>&mdash;</td> <td class="align-right">$0.00</td> </tr> <tr> <td>Mike Smith</td> <td>San Francisco, CA</td> <td>1</td> <td><a href="#">#1002</a></td> <td class="align-right">$100.00</td> </tr> </tbody> </table> <div class="pagination"> <span class="button-group"> <button class="secondary icon-prev"></button> <button class="secondary icon-next"></button> </span> </div>

Text Highlight

Use .highlight-warning to highlight any text.

Product Inventory Type
Adidas Running Show 5 in stock Shoe
New Balance Running Show 12 in stock Shoe
New Balance Running Show 60 in stock for 5 variants Shoe

Source

<table class="results"> <thead> <tr> <th>Product</th> <th>Inventory</th> <th>Type</th> </tr> </thead> <tbody> <tr> <td>Adidas Running Show</td> <td><span class="highlight-warning">5</span> in stock</td> <td>Shoe</td> </tr> <tr> <td>New Balance Running Show</td> <td><span class="highlight-warning">12</span> in stock</td> <td>Shoe</td> </tr> <tr> <td>New Balance Running Show</td> <td>60 in stock for 5 variants</td> <td>Shoe</td> </tr> </tbody> </table>

Summary Report

Add .summary to a <table> element for this specific layout.

Heading Last 7 Days
Direct 67% 2
Search 33% 1
<table class="summary"> <thead> <th colspan="3">Heading <span>Last 7 Days</span></th> </thead> <tbody> <tr> <td>Direct</td> <td>67%</td> <td>2</td> </tr> <tr> <td>Search</td> <td>33%</td> <td>1</td> </tr> </tbody> </table>

Tags

Any element with .tag and any supporting color.

green yellow red grey lightblue orange blue
<span class="tag green">green</span> <span class="tag yellow">yellow</span> <span class="tag red">red</span> <span class="tag grey">grey</span> <span class="tag lightblue">lightblue</span> <span class="tag orange">orange</span> <span class="tag blue">blue</span>

Pending Tags

Add the class .pending to display a clock icon to represent a "pending" state.

green yellow red grey lightblue orange blue
<span class="tag green pending">green</span> <span class="tag yellow pending">yellow</span> <span class="tag red pending">red</span> <span class="tag grey pending">grey</span> <span class="tag lightblue pending">lightblue</span> <span class="tag orange pending">orange</span> <span class="tag blue pending">blue</span>

Removable Tags

Primarily used with content not associated with forms.

green yellow red grey lightblue orange blue
<span class="tag green remove">green <a href="#"></a></span> <span class="tag yellow remove">yellow <a href="#"></a></span> <span class="tag red remove">red <a href="#"></a></span> <span class="tag grey remove">grey <a href="#"></a></span> <span class="tag lightblue remove">lightblue <a href="#"></a></span> <span class="tag orange remove">orange <a href="#"></a></span> <span class="tag blue remove">blue <a href="#"></a></span>

Collapsable Tags

Primarily used in conjunction with form fields.

green yellow red grey lightblue orange blue
<span class="tag green collapsable">green <a href="#"></a></span> <span class="tag yellow collapsable">yellow <a href="#"></a></span> <span class="tag red collapsable">red <a href="#"></a></span> <span class="tag grey collapsable">grey <a href="#"></a></span> <span class="tag lightblue collapsable">lightblue <a href="#"></a></span> <span class="tag orange collapsable">orange <a href="#"></a></span> <span class="tag blue collapsable">blue <a href="#"></a></span>

Tabs

Use a <ul> with the class .tabs directly after an element with the .has-sections class.

Content

<div class="columns has-sections card"> <ul class="tabs"> <li class="active"><a href="#">Tab 1</a></li> <li><a href="#">Tab 2</a></li> <li><a href="#">Tab 3</a></li> </ul> <div class="card-section"> <p>Content</p> </div> </div>

Utilities

Sometimes it's better to use a utility class than create a whole new class just to do something simple.

.full-width { width: 100%; max-width: 100%; box-sizing: border-box; } .max-full-width { max-width: 100%; box-sizing: border-box; } .align-right { text-align: right; } .highlight-warning { background: #fffbe9; color: #e85b0f; } .blue { color: #3e89b5; } .green { color: #4d684b; } .yellow { color: #6f4f26; } .red { color: #8c2929; } .grey { color: #798c9c; } .lightblue { color: #647f9e; } .orange { color: #7f3a07; } .emphasis { font-weight: 600; color: hsl(0,0%,10%); } .subdued { font-weight: normal; color: hsl(0,0%,44%); } .hide-scrollbars { ::-webkit-scrollbar { display: none !important; width: 10px !important; height: 0 !important; } ::-webkit-scrollbar-thumb { background-color: rgba(0,0,0,0); } } .overflow-container { overflow: scroll; -webkit-overflow-scrolling: touch; -ms-overflow-style: -ms-autohiding-scrollbar; }

Header

Using the <header> is great opportunity to showcase the app's branding.

App Name

Headline text over your own background

A simple <header> element with an h1 and/or h2 element. The <article> directly after will automatically be pulled up

Source

<header> <h1>App Name</h1> <h2>Headline text over your own background</h2> </header> <article> ... </article>

Zero-state

Preferred layout option when you have nothing to show.

Heading

Some explanatory text

Source

<section class="zero-state full-width"> <article> <h1>Heading</h1> <h3>Some explanatory text</h3> <button>Action</button> </article> </section>

Footer

Standard elements for help links to app-related questions.

Source

<footer> <article class="help"> <span></span> <p>Learn more about <a href="#">%screen%</a> at the <a href="#">%company%</a> Help Center.</p> </article> </footer>