Picnic CSS
Picnic CSS is a lightweight and beautiful CSS library
Buttons
They can be of different colors and types:
<button>Button</button>
<button class='success'>Success</button>
<button class='warning'>Warning</button>
<button class='error'>Error</button>
<button disabled>Disabled</button>
<button>Button</button>
<a class="button">Link</a>
<input value="Submit" type="submit">
<label>
<input type="checkbox">
<span class="toggle button">Toggle</span>
</label>
Pseudo buttons
Allows for seemingly links to behave as buttons:
<button class="pseudo">Button</button>
<a class="pseudo button">Link</a>
<input class="pseudo" value="Submit" type="submit">
<label>
<input type="checkbox">
<span class="toggle pseudo button">Toggle</span>
</label>
Hack it
You only have to define a single color base for new colors. The :hover
and :active
status are handled as overlays for consistency and simplicity
<button class="myCoolButton">My Cool Button</button>
.myCoolButton {
background: #85144b;
}
To create a larger button you only need to make the font inside it larger. The paddings are set in em so the whole button stays in great shape:
<button class="mainButton">Large button</button><br>
<button>Normal button</button><br>
<button class="shyButton">Small button</button>
.mainButton {
font-size: 1.5em;
}
.shyButton {
font-size: .75em;
}
To change the color of the pseudo-color on hover:
<button class="pseudo cool">Pseudo personal</button>
.cool:hover,
.cool:active,
.cool:focus {
background: #cff;
}
Card
A card is a self-contained, replicable type. It works great with other of its kind. It can consist of only one element or many of them:
<article class="card">
<header>
<h3>A really simple h3</h3>
</header>
</article>
<article class="card">
<header>
<button>Love</button>
<button class="dangerous">Hate</button>
</header>
</article>
<article class="card">
<header>
<h3>Forest</h3>
</header>
<footer>
<button>Like</button>
</footer>
</article>
<div class="flex two">
<div>
<article class="card">
<img src="/img/forest.jpg">
<footer>
<h3>Misty Forest</h3>
<button>Like</button>
</footer>
</article>
</div>
<div>
<article class="card">
<img src="/img/forest.jpg">
<footer>
<h3>Misty Forest</h3>
<button>Like</button>
</footer>
</article>
</div>
</div>
Checkbox
Display an inline checkbox with a nice default style
<label>
<input type="checkbox">
<span class="checkable">Check me out (;</span>
</label>
<label>
<input type="checkbox" checked>
<span class="checkable">Uncheck me</span>
</label>
Usage
This plugin, while experimental in the past, is mature now. Use a normal checkbox followed by any other element with the class checkable
. The element that follows the checkbox will receive the pseudo classes so it should be able to do so. We recommend a <span>
or <label>
. Here we use the label around them for making the <input>
change state when you click on this folowing element.
<label>
<input type="checkbox">
<span class="checkable">Checkbox text</span>
</label>
But you can also use a label and reference the original input:
<input id="checkboxdemo" type="checkbox">
<label for="checkboxdemo" class="checkable">Checkbox text</label>
JavaScript
You do not need javascript since we are using the native elements and not setting display: none
purposefully. However, you can still use javascript as normal to retrieve the checked elements.
// Pure javascript
document.querySelector('form').onsubmit = function(e){
e.preventDefault();
alert(document.querySelector('input.tos').checked);
}
// jQuery
$("form").on('submit', function(e){
e.preventDefault();
alert($('input.tos').is(':checked'));
});
Drop image
Allows you to add a file input element that can receive an image drop and clicks with native elements. However, it needs some javascript to show the dropped image:
<div style="width: 200px"> <!-- this div just for demo display -->
<label class="dropimage">
<input title="Drop image or click me" type="file">
</label>
</div>
JavaScript
This is the javascript you need for multiple elements:
document.addEventListener("DOMContentLoaded", function() {
[].forEach.call(document.querySelectorAll('.dropimage'), function(img){
img.onchange = function(e){
var inputfile = this, reader = new FileReader();
reader.onloadend = function(){
inputfile.style['background-image'] = 'url('+reader.result+')';
}
reader.readAsDataURL(e.target.files[0]);
}
});
});
Hack it
Do you want round pictures? No problem, just do this:
.profile {
border-radius: 50%; /* Make it a circle */
padding-bottom: 100%; /* 100% height (ratio 1) */
}
To get this:
<div style="width: 200px"> <!-- this div just for demo display -->
<label class="dropimage profile">
<input name="filea" title="Drop image or click me" type="file">
</label>
</div>
Make it smaller
.miniprofile {
border-radius: 50%; /* Make it a circle */
margin: 0 auto; /* Center horizontally */
width: 60%; /* 60% width */
padding-bottom: 60%; /* 60% height */
}
<div style="width: 200px"> <!-- this div just for demo display -->
<label class="dropimage miniprofile">
<input name="filea" title="Drop image or click me" type="file">
</label>
</div>
Grids
Note: the old
.row
and.grid
have been replaced by the new.flex
. You can still see the old documentation in github.
Note 2: the children
<span>
are only for display purposes; you can put anything you want instead of them
A flexbox grid implementation with breakpoints. Choose when to change your layout depending on your content instead of the device you want to show as recommended by Google's RWD, by Smashing Magazine's Logical Breakpoints and Picnic CSS.
You can create complex, flexible layouts with it. Just resize the browser to see how powerful it is:
<div class="flex two four-500 six-800 demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div class="full half-500 third-800"><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
<div><span>6</span></div>
<div><span>7</span></div>
<div><span>8</span></div>
<div><span>9</span></div>
<div class="off-half off-fourth-500 off-sixth-800"><span>10</span></div>
</div>
Equally sized columns
Let's start through the basics though. Just a container with equally sized children:
<div class="flex demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
<div><span>6</span></div>
</div>
With the class flex
, smaller children will be spaced equally to fill all of the content. However, this only works with small children. If you have children bigger than their corresponding width (1/6th in the above) they will not be restricted:
<div class="flex demo">
<div><span>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</span></div>
<div><span>2</span></div>
</div>
To fix this, manually set the number of columns as explained in the next point.
Column count
If instead you prefer certain column count, such as in a gallery where it can span several rows, use a counter besides the class flex:
<div class="flex three demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
</div>
The columns will keep being equally spaced, but this time with the width corresponding to the column counter. You can use any number as a class from one to twelve:
one
two
three
four
five
six
seven
eight
nine
ten
eleven
twelve
Most grid systems use a 12 grid system, but we wanted to use a more flexible system and allow you to choose the grid size.
Responsive column count
We follow a mobile-first design. Put the number of columns for mobile as explained in the previous point. Then, when things get too stretched, add a column counter with the number of pixels in 100 increments as follows:
<div class="flex two three-600 six-1200 demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
<div><span>6</span></div>
</div>
The number after the column count as in -600
or -1200
are the breakpoints. When the website width is over that number, that column count will be used instead of the previous. If we use two or more, the largest column count will be used.
For example, in a desktop with a screen of 1920x1080px
the previous one will display 6 columns. Any screen from 600px to 1200px will display three columns and smaller than 600px will display 2 columns.
The increment is 100px and starts in 500px up to 2000px both included. You can use any of those suffixes for the column count class:
-500
-600
-700
-800
-900
-1000
-1100
-1200
-1300
-1400
-1500
-1600
-1700
-1800
-1900
-2000
Remainders
You can also modify the remainder content as you wish with a couple of utility classes. This is the default:
<div class="flex three demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
</div>
You can grow them:
<div class="flex three grow demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
</div>
Or you can center them:
<div class="flex three center demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div><span>3</span></div>
<div><span>4</span></div>
<div><span>5</span></div>
</div>
Children sizing
Now that we know how the parent (or grid) can modify itself and the elements below them, the children can also go rebel and behave on their own. Say that a child wants to be half of the size of its parent element. Easy, just add the class half
:
<div class="flex four demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div class="half"><span>3</span></div>
</div>
We have many classes like those. They are the size relative to the parent grid:
full
half
third
two-third
fourth
three-fourth
fifth
two-fifth
three-fifth
four-fifth
sixth
none
The class none
hides the element, useful for responsive layouts
Responsive children
They can also be fine-tuned in a way similar to the above:
<div class="flex four demo">
<div class="half fourth-1000"><span>1</span></div>
<div class="half fourth-1000"><span>2</span></div>
<div class="full half-1000"><span>3</span></div>
</div>
Offsets
The children can also have one offset (empty space) before it. They are built adding the class off-SIZE, similar to the size but prefixing off-:
<div class="flex four demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div class="off-fourth"><span>3</span></div>
</div>
We have many classes like those. They are the size of the offset relative to the parent grid:
off-none
off-half
off-third
off-two-third
off-fourth
off-three-fourth
off-fifth
off-two-fifth
off-three-fifth
off-four-fifth
off-sixth
Note:
off-none
is useful for making responsive layouts as explained in the next point.
Responsive offsets
They can also have the minimum screen size when they start working:
<div class="flex three four-1000 demo">
<div><span>1</span></div>
<div><span>2</span></div>
<div class="off-fourth-800"><span>3</span></div>
</div>
The main difference with the width classes is that it includes a none in case you want to hide the offset at certain sizes and that it doesn't include a full
Input
Simple (or not) text form elements:
<fieldset class="flex two">
<label><input type="email" placeholder="Email"></label>
<label><input type="password" placeholder="Password"></label>
</fieldset>
<textarea placeholder="Textarea"></textarea>
Label
An element to display some short relevant information on the side of other element
<h1>header 1 <span class="label">Normal</span></h1>
<h2>header 2 <span class="label success">Success</span></h2>
<h3>header 3 <span class="label warning">Warning</span></h3>
<h4>header 4 <span class="label error">Error</span></h4>
<p>paragraph <span class="label">Normal</span></p>
Modal
The modal is pure CSS, which makes the HTML quite ugly actually. However it does work. To try it, press the button:
<label for="modal_1" class="button">Show modal</label>
<div class="modal">
<input id="modal_1" type="checkbox" />
<label for="modal_1" class="overlay"></label>
<article>
<header>
<h3>Great offer</h3>
<label for="modal_1" class="close">×</label>
</header>
<section class="content">
We have a special offer for you. I am sure you will love it! However this does look spammy...
</section>
<footer>
<a class="button" href="#">See offer</a>
<label for="modal_1" class="button dangerous">
Cancel
</label>
</footer>
</article>
</div>
JavaScript
As always, there is no javascript. However, a little bit of javascript could enhance the experience allowing to close the modal by pressing ESC
.
document.onkeydown = function(e){
if (e.keyCode == 27) {
var mods = document.querySelectorAll('.modal > [type=checkbox]');
[].forEach.call(mods, function(mod){ mod.checked = false; });
}
}
Toggling the modal with javascript
If you want to be able to toggle the modal with javascript, you can use the following:
document.getElementById('modal_1').checked = true; // open modal
document.getElementById('modal_1').checked = false; // close modal
Nav
A responsive, pure css navigation menu:
On these smaller versions it might have small glitches. Please see the top, page-wide nav to see the actual effect.
<div style="overflow: hidden;height: 250px;"> <!-- For Demo, Represents the body -->
<nav class="demo">
<a href="#" class="brand">
<img class="logo" src="/img/basket.png" />
<span>Picnic CSS</span>
</a>
<!-- responsive-->
<input id="bmenub" type="checkbox" class="show">
<label for="bmenub" class="burger pseudo button">menu</label>
<div class="menu">
<a href="#" class="pseudo button icon-picture">Demo</a>
<a href="#" class="button icon-puzzle">Plugins</a>
</div>
</nav>
</div>
Responsive
The nav is responsive by default. The text inside the <label>
can be changed for the following characters for a different effect (source):
- Identical to
≡
(safe on mobile): - Trigram for heaven
☰
: - Any other:
Different height and big logo
Thanks to a vertical-align trick, you can set it up to any height you want:
nav.imponent {
padding: 2em 0;
}
.imponent .logo {
height: 3em;
}
<nav class="demo imponent">
<a href="#" class="brand">
<img class="logo" src="/img/basket.png" />
<span>Picnic CSS</span>
</a>
</nav>
Form elements
Just get anything you want inside the nav, most things should work.
<div style="overflow: hidden;height: 250px;"> <!-- For Demo, Represents the body -->
<nav class="demo">
<a href="#" class="brand">Picnic CSS</a>
<!-- responsive-->
<input id="bmenug" type="checkbox" class="show">
<label for="bmenug" class="burger pseudo button">≡</label>
<div class="menu">
<input placeholder="Search plugins" />
</div>
</nav>
</div>
<div style="overflow: hidden;height: 250px;"> <!-- For Demo, Represents the body -->
<nav class="demo">
<a href="#" class="brand">Picnic CSS</a>
<!-- responsive-->
<input id="cmenug" type="checkbox" class="show">
<label for="cmenug" class="burger pseudo button">≡</label>
<div class="menu">
<select>
<option>Choose an option</option>
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</nav>
</div>
Fixed position
To set it on the top of the page instead of scrolling with the page, just do:
nav {
position: absolute;
}
Open nav menu from left
Change sass variable $picnic-nav-open-left: false !default;
to
$picnic-nav-open-left: true;
to open it from the left:
<div style="overflow: hidden;height: 250px;"> <!-- For Demo, Represents the body -->
<nav class="demo">
<a href="#" class="brand">Picnic CSS</a>
<!-- responsive-->
<input id="cmenug" type="checkbox" class="show">
<label for="cmenug" class="burger pseudo button">≡</label>
<div class="menu">
<select>
<option>Choose an option</option>
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</nav>
</div>
Radio button
A simple way of using radiobuttons
<label>
<input type='radio' name="radiodemo">
<span class="checkable">Select me</span>
</label><br><br>
<input id="radiodemo" checked type='radio' name="radiodemo">
<label for="radiodemo" class="checkable">Or me</label>
Select
<select>
<option>Select an option</option>
<option>Good option</option>
<option>Nice option</option>
<option>Cheap option</option>
</select>
Stack
A vertical group of different elements.
<span class="button stack icon-picture">Home</span>
<span class="button stack icon-puzzle">Plugins</span>
<span class="button stack icon-file-code">Documentation</span>
<span class="button stack icon-help-circled">Test</span>
They can also toggle:
<div>
<label class="stack">
<input name="stack" type="radio">
<span class="button toggle">
<span class="icon-picture"></span> Home
</span>
</label>
<label class="stack">
<input name="stack" type="radio">
<span class="button toggle">
<span class="icon-puzzle"></span> Plugins
</span>
</label>
<label class="stack">
<input name="stack" type="radio">
<span class="button toggle">
<span class="icon-file-code"></span> Documentation
</span>
</label>
<label class="stack">
<input name="stack" type="radio">
<span class="button toggle">
<span class="icon-help-circled"></span> Test
</span>
</label>
</div>
Stack different kind of elements
<div class="third">
<img class="stack" src="/img/forest.jpg">
<a class="button stack">Full size</a>
</div>
A small form
<div class="third">
<input class="stack" placeholder="Name" />
<input class="stack" placeholder="Email" />
<button class="stack icon-paper-plane">
Send
</button>
</div>
Pseudo buttons:
<a class="stack pseudo button">First</a>
<a class="stack pseudo button">Second</a>
<a class="stack pseudo button">Third</a>
Forms
Create nice and packed forms. jsfiddle
<div class="third">
<input class="stack" placeholder="First name" />
<input class="stack" placeholder="Last name" />
<input class="stack" placeholder="Email" />
</div><br>
<div class="third">
<input class="stack" placeholder="Password" />
<input class="stack" placeholder="Repeat password" />
<textarea class="stack" placeholder="Biography"></textarea>
<button class="stack icon-paper-plane">Send</button>
</div>
Table
<table class="primary">
<thead>
<tr>
<th>Name</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr>
<td>Francisco</td>
<td>Valencia, Spain</td>
</tr>
<tr>
<td>Eve</td>
<td>San Francisco, USA</td>
</tr>
<tr>
<td>Martin</td>
<td>New York, USA</td>
</tr>
<tr>
<td>Sarah</td>
<td>London, UK</td>
</tr>
</tbody>
</table>
Tabs
Original: http://jsfiddle.net/franciscop/wwfby2y8/
A simple tab system inspired by Components CSS Tabs.
<div class="tabs three">
<input id='tab-1' type='radio' name='tabgroupB' checked />
<label class="pseudo button toggle" for="tab-1">Forest</label>
<input id='tab-2' type='radio' name='tabgroupB'>
<label class="pseudo button toggle" for="tab-2">Lake</label>
<input id='tab-3' type='radio' name='tabgroupB'>
<label class="pseudo button toggle" for="tab-3">Balloon</label>
<div class="row">
<div>
<img src="img/forest.jpg">
</div>
<div>
<img src="img/lake.jpg">
</div>
<div>
<img src="img/balloon.jpg">
</div>
</div>
</div>
Gallery example
Create a gallery super-easy with thumbnails as tabs:
<div class="tabs four">
<input id="tabC-1" type='radio' name='tabGroupC' checked >
<input id="tabC-2" type='radio' name='tabGroupC'>
<input id="tabC-3" type='radio' name='tabGroupC'>
<input id="tabC-4" type='radio' name='tabGroupC'>
<div class='row'>
<div>
<img src="img/forest.jpg">
</div>
<div>
<img src="img/lake.jpg">
</div>
<div>
<img src="img/halong.jpg">
</div>
<div>
<img src="img/balloon.jpg">
</div>
</div>
<label for="tabC-1"><img src="img/forest.jpg"></label>
<label for="tabC-2"><img src="img/lake.jpg"></label>
<label for="tabC-3"><img src="img/halong.jpg"></label>
<label for="tabC-4"><img src="img/balloon.jpg"></label>
</div>
Tooltip
Hover this element to show the tooltip:
<button data-tooltip="This is a great tooltip" class="tooltip-top">
Hover for tooltip
</button>
Positions
<button data-tooltip="This is a great tooltip" class="tooltip-top">
Top
</button>
<button data-tooltip="This is a great tooltip">
Bottom (default)
</button>
<button data-tooltip="This is a great tooltip" class="tooltip-left">
Left
</button>
<button data-tooltip="This is a great tooltip" class="tooltip-right">
Right
</button>