Yohns PicoCSS Fork v2.2.7

I've merged some open pull requests from the original Pico repository, and then added a few more enhancements that I either needed for a project (timeline) or wanted to make the building process of websites easier (:user-valid "validation", using <label> within groups, .row & .row-fluid and the .col-* classes like Bootstrap, .align-* and more.) The demo docs here is the main enhanced that have been added to the Pico CSS 2.0.6 branch, for more docs, refer to the original Pico CSS docs.


(OPTIONAL) Some of the demos on this page do require Vanilla JavaScript Files to work the same as the preview here. I may get a build script going to compile the javascript plugins / components later. Let me know if this feature would help you.

If this fork has helped you, please Like this fork!

Tables

Striped rows require .striped class

Styles for a <caption> element have been added for tables as well.

For rows that will be hidden, make sure to add the hidden attribute like so: <tr hidden>

When rows are toggled, the hidden rows have * around the first column.

Solar System Planets
Planet Diameter (km) Dist.to Sun (AU) Orbit (days)
Mercury 4,880 0.39 88
Venus 12,104 0.72 225
Earth 12,742 1.00 365
Mars 6,779 1.52 687
Jupiter 139,820 5.20 4,333
Saturn 116,460 9.58 10,759
Neptune 49,244 30.05 60,182
Average 49,594 8.58 13,666

Responsive Tabs [role="tablist"]

Classless!
Javascirpt is required.

Accessible friendly, with left and right arrow, home and end button triggers to switch between tabs.

Make sure to Download PicoTabs.js

Ensure you have

To set up the tabs, follow these steps:

  1. HTML Structure:
    • Each tab button must have the following attributes:
      • role="tab"
      • id="unique-tab-id" - A unique ID for the tab
      • aria-selected="true/false" - Indicates if the tab is selected
      • aria-controls="panel-id" - The ID of the associated tab panel
      • tabindex="0/-1" - Indicates if the tab is focusable
    • Each tab panel must have the following attributes:
      • role="tabpanel"
      • id="panel-id" - A unique ID for the panel
      • aria-labelledby="unique-tab-id" - The ID of the associated tab
      • hidden - Indicates if the panel is hidden (use hidden attribute for non-active panels)
  2. JavaScript:

    The JavaScript file PicoTabs.js is required for the tabs to function correctly. Ensure you include it in your HTML file:

    <script src="js/PicoTabs.js"></script>

    Initialize the tabs by adding the following code:

    document.addEventListener("DOMContentLoaded", () => {
    	new PicoTabs('[role="tablist"]');
    });
  3. Keyboard Navigation:

    The following keypresses work for the tabs:

    • ArrowLeft - Move to the previous tab
    • ArrowRight - Move to the next tab
    • Home - Move to the first tab
    • End - Move to the last tab

Tab Example:

Tab One Content

Lorem ipsum dolor sit amet, consectetur adipisicing 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 adipisicing 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.


Show the code:
<div role="tablist">
	<!-- Tab One -->
	<button id="tabone" role="tab" tabindex="0" aria-selected="true" aria-controls="panel1">
		Tab One
	</button>
	<div id="panel1" role="tabpanel" aria-labelledby="tabone" tabindex="0">
		<h1>Tab One Content</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
	</div>

	<!-- Tab Two -->
	<button id="tabtwo" role="tab" aria-selected="false" aria-controls="panel2" tabindex="-1">
		Tab Two
	</button>
	<div id="panel2" role="tabpanel" aria-labelledby="tabtwo" hidden>
		<h1>Tab Two Content</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
	</div>

	<!-- Tab Three -->
	<button id="tabthree" role="tab" aria-selected="false" aria-controls="panel3" tabindex="-1">
		Tab Three
	</button>
	<div id="panel3" role="tabpanel" aria-labelledby="tabthree" hidden>
		<h1>Tab Three Content</h1>
		<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit...</p>
	</div>
</div>

Hamburger Menu nav[role="navigation"]

Classless!

Use the default <nav> component in Pico CSS docs, but add the role="navigation" attribute to the <nav>.

Positioning

The default position puts your nav links and burger menu at the end of the line, but data-position="start" will put them at the start of the line.

Breakpoints

Use the data-breakpoint="**" to change when the burger menu appears. The different values are md, lg, xl and xxl. These are the same breakpoints the .row uses.

Hamburger Icon

Before the list of elements you want to be within the burger menu, add the following:

<input type="checkbox" id="YOUR-ID" />
<label for="YOUR-ID" style="font-size: calc(var(--pico-font-size) * 1.5);">&#x2261;</label>

Change YOUR-ID to whatever id you want to use, but ensure the id for the checkbox, is the same as the id for the label.

DO NOT put the input[type="checkbox"] within the <label> element, it will not work correctly if you do that.
Custom Hamburger Icon?

Replace the &#x2261; with your own icon, svg element, or image.

Collapsed List

Add role="list" attribute to the <ul> or <ol> element for the hamburger menu, and then add role="listitem" attribute to each <li> element.


Example Hamburger Menu

(resize width of screen if you don't see it)

Hamburger Menu Under Nav Example


Show the code:
<nav role="navigation" data-position="end" data-breakpoint="lg">
	<ul>
		<li><a href="https://github.com/Yohn/PicoCSS" target="_blank">Yohns Fork</a></li>
	</ul>
	<ul>
		<li><strong>Like Us on GitHub!</strong></li>
	</ul>
	<input type="checkbox" id="menu-btn2">
	<label for="menu-btn2" style="font-size: calc(var(--pico-font-size) * 1.3);" aria-label="Menu"
		aria-controls="nav-example2">
		&equiv;
	</label>
	<ol id="nav-example2" role="list">
		<li role="listitem"><a href="#">Home</a></li>
		<li role="listitem"><a href="#">About</a></li>
		<li role="listitem"><a href="#">Services</a></li>
		<li role="listitem"><a href="#">Login</a></li>
		<li role="listitem"><a href="#">Sign Up</a></li>
	</ol>
</nav>

Tooltip

Tooltips are now dark background be default for light and dark theme.

I also wanted to remove the dotted line on input fileds when they are contained within the tooltip element, so that is why this example has the input field with the tooltip on the <label> wrapper.

We also want the tooltip width to not be huge when the tooltip is short.


Ghost Buttons

Ghost buttons are buttons that have a transparent background and border. They are often used as secondary buttons to indicate a less important action.

Ghost buttons are created by adding the .ghost class to a button

.ghost will work on all <button>, [type="button"], [type="submit"], [type="reset"], and [role="button"] elements.


Show the code:
<button type="button" class="ghost">Ghost Button</button>
<button type="button" class="ghost secondary">Secondary Ghost Button</button>
<button type="button" class="ghost contrast">Contrast Ghost Button</button>

Floating Labels

Classless!

For floating labels to work, you need to add the role="form" attribute to a <section> tag, ensure you have a placeholder="example" attribute on your input or textarea tags, and that placeholder value needs to be the same value that is used within the label tag, which would go after your form element..



Show The Code
<section role="form">
	<input type="email" id="fl-email-ele" placeholder="Email" aria-required="true"
		aria-labelledby="fl-email">
	<label for="fl-email-ele" id="fl-email">Email</label>
</section>
<section role="form">
	<select id="fl-topic-ele" required aria-required="true" aria-labelledby="fl-topic">
		<option selected disabled value="">Topic</option>
		<option>General</option>
		<option>Support</option>
		<option>Feedback</option>
	</select>
	<label for="fl-topic-ele" id="fl-topic">Topic</label>
</section>
<section role="form">
	<textarea id="fl-message-ele" placeholder="Message" aria-required="true"
		aria-labelledby="fl-message"></textarea>
	<label for="fl-message-ele" id="fl-message">Message</label>
</section>

Validation

Classless!

Using form :user-valid and :user-invalid.

You can disable the validation by adding the attribute novalidate to the form tag.

Classless except for the file input button previews.

Check JS for FileValidator class


Group

Classless and no JavaScript!
  1. <label> has been added.
  2. <legend> has been added. (To be used with <fieldset role="group">
  3. <details class="dropdown"> has been added.

Click on the Getting Started to see the sub-dropdown menu under About.


[role=group] > .dropdown


form > [role=group]


form > [role=group] > select


form > [role=group] > label + input + select


Rows

Similar to Bootstrap 5.3.3, with the responsive .col-*COL#*, .col-*BREAKPOINT*-*COL#*, .offset-*COL#*, .offset-*BREAKPOINT*-*COL#*.

.row has a max width set to the viewport of your xl viewport (1300px by default)

.row-fluid max width is 100%.
col-3
col-6
col-3
col-3 offset-1
col-2
col-2
col-3
col-3
col-3
col-3
col-3
col-2
col-8
col-2
col-5
col-7
col-9
col-3

Columns with offsets defined by breakpoints

When defining multiple .col-*-* on the same element, the order your put the classes on the element matter.

col-2, col-md-4
col-4, offset-8, col-md-6, offset-md-6
col-5, offset-1, col-md-11
col-2, col-md-6
col-3, offset-9, col-md-6, offset-md-6
col-3 col-md-12 col-lg-6
col-3 col-md-12 col-lg-6
col-4 col-md-6 col-lg-3
col-6 offset-6 col-md-3 offset-md-9 col-lg-2 offset-lg-10

Alignment

You can add .align-start (default), .align-center or .align-end to your .row or .row-fluid element to align the containing elements to the top, middle, or bottom.

col-4
col-4

-md- Breakpoints

col-12, col-md-4
col-12, col-md-4
col-12, col-md-4


Popovers

Popovers will replace the notifications below.

Popover

Click/Tap everywhere else to close
Footer
Some Feedback Message With Close Button

Accordions

Accordion 1

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque urna diam, tincidunt nec porta sed, auctor id velit. Etiam venenatis nisl ut orci consequat, vitae tempus quam commodo. Nulla non mauris ipsum. Aliquam eu posuere orci. Nulla convallis lectus rutrum quam hendrerit, in facilisis elit sollicitudin. Mauris pulvinar pulvinar mi, dictum tristique elit auctor quis. Maecenas ac ipsum ultrices, porta turpis sit amet, congue turpis.

Accordion 2
  • Vestibulum id elit quis massa interdum sodales.
  • Nunc quis eros vel odio pretium tincidunt nec quis neque.
  • Quisque sed eros non eros ornare elementum.
  • Cras sed libero aliquet, porta dolor quis, dapibus ipsum.

Timeline


View Custom CSS
--pico-timeline-line-color: var(--pico-primary-background);
--pico-timeline-dot-background-color: var(--pico-primary-inverse);
--pico-timeline-dot-border-color: var(--pico-primary-background);
--pico-timeline-arrow-color: var(--pico-card-sectioning-background-color);

2017

Lorem ipsum dolor sit amet, quo ei simul congue exerci, ad nec admodum perfecto mnesarchum, vim ea mazim fierent detracto. Ea quis iuvaret expetendis his, te elit voluptua dignissim per, habeo iusto primis ea eam.

2016

Lorem ipsum dolor sit amet, quo ei simul congue exerci, ad nec admodum perfecto mnesarchum, vim ea mazim fierent detracto. Ea quis iuvaret expetendis his, te elit voluptua dignissim per, habeo iusto primis ea eam.

2015

Lorem ipsum dolor sit amet, quo ei simul congue exerci, ad nec admodum perfecto mnesarchum, vim ea mazim fierent detracto. Ea quis iuvaret expetendis his, te elit voluptua dignissim per, habeo iusto primis ea eam.

2012

Lorem ipsum dolor sit amet, quo ei simul congue exerci, ad nec admodum perfecto mnesarchum, vim ea mazim fierent detracto. Ea quis iuvaret expetendis his, te elit voluptua dignissim per, habeo iusto primis ea eam.


DO NOT USE THE FOLLOWING

All CSS and JavaScript have been removed for the following examples, so you will only be seeing the raw examples, without styling

Show Old Tabs

The tabs below will be removed in a future version.

Tabs section[role="region"]

DOES NOT WORK IN CHROME

Information

  • I wanted this to work without javascript
  • I wanted to use the <details> and <summary> tags.

Grips

  1. I would have liked to use the role attribute values tablist, tab, and tabpanel but the w3 specs says we cant use roles on <details> and <summary> tags.
  2. <section> in theory has a default role attribute value of region, though not confirmed, or applied when we are using it for our CSS. So I went with the role="region" attribute to help with selecting the correct element with CSS, classless and no JavaScript!

Example Tabs with no JavaScript:

Tab 1

Content for Tab 1

Content for Tab 1

Tab 2

Just a random table

row 1 col 1 row 1 col 2 row 1 col 3
row 2 col 1 row 2 col 2 row 2 col 3
row 3 col 1 row 3 col 2 row 3 col 3
Tab 3
Tab 4

Content for Tab 4

Tab 5

Content for Tab 5


Show the code:
<section role="region">
	<details name="lets-go" open>
		<summary>Tab 1</summary>
		<div>
			<p>Content for Tab 1</p>
			<p>Content for Tab 1</p>
		</div>
	</details>
	<details name="lets-go">
		<summary>Tab 2</summary>
		<div>
			<p>Just a random table</p>
			<table>
				<tr>
					<td>row 1 col 1</td>
					<td>row 1 col 2</td>
					<td>row 1 col 3</td>
				</tr>
				<tr>
					<td>row 2 col 1</td>
					<td>row 2 col 2</td>
					<td>row 2 col 3</td>
				</tr>
				<tr>
					<td>row 3 col 1</td>
					<td>row 3 col 2</td>
					<td>row 3 col 3</td>
				</tr>
			</table>
		</div>
	</details>
	<details name="lets-go">
		<summary>Tab 3</summary>
		<div>
			<form action="javascript:void(0);">
				<section role="form">
					<input type="text" id="name" name="name" placeholder="Name:" required>
					<label for="name">Name:</label>
				</section>
				<section role="form">
					<input type="email" id="email" name="email" placeholder="Email:" required>
					<label for="email">Email:</label>
				</section>
				<input type="submit" value="Submit">
			</form>
		</div>
	</details>
	<details name="lets-go">
		<summary>Tab 4</summary>
		<div>
			<p>Content for Tab 4</p>
		</div>
	</details>
	<details name="lets-go">
		<summary>Tab 5</summary>
		<div>
			<p>Content for Tab 5</p>
		</div>
	</details>
</section>

Show Old Notifications

The Notifications below will be removed in a future version.

Notificaton

DEPRECATED

Confirm your action!

Cras sit amet maximus risus. Pellentesque sodales odio sit amet augue finibus pellentesque. Nullam finibus risus non semper euismod.

Modal with a Form!

The <form> tag is the first element within the <article> tag.

<dialog id="modal-form-example">
	<article>
		<form action="javascript:void(0);" method="POST">
			<header>
				<button aria-label="Close" rel="prev" data-target="modal-form-example" onclick="toggleModal(event)"></button>
				<h3>Modal with a Form!</h3>
			</header>
			<section role="form">
				<input autofocus type="text" name="mf-name" id="mf-name" placeholder="Name">
				<label for="mf-name">Name</label>
			</section>
			<section role="form">
				<input type="password" name="mf-pass" id="mf-pass" placeholder="Password">
				<label for="mf-pass">Password</label>
			</section>
			<footer>
				<div class="grid">
					<button role="button" class="secondary" data-target="modal-form-example" onclick="toggleModal(event)">&cross; Cancel</button>
					<div></div>
					<button data-target="modal-form-example" onclick="toggleModal(event)">&check; Confirm</button>
				</div>
			</footer>
		</form>
	</article>
</dialog>
Small Modal

This is a small modal with max-width of 400px.

Medium Modal

This is a medium modal with max-width of 600px.

Large Modal

This is a large modal with max-width of 800px.

Extra Large Modal

This is an extra large modal with max-width of 1000px.

Fullscreen Modal

This is a fullscreen modal that takes up the entire viewport.