Yohns PicoCSS Fork v2.2.1

Not in npm yet, but will be soon.

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!

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.


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!

I wanted to add the label tah to have an input group kind of thing going on.


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>