Repository: phuocng/csslayout Branch: master Commit: ecf92df03a34 Files: 120 Total size: 424.4 KB Directory structure: gitextract_eojep_s2/ ├── .gitignore ├── LICENSE ├── README.md └── contents/ ├── accordion.mdx ├── arrow-buttons.mdx ├── avatar-list.mdx ├── avatar.mdx ├── badge.mdx ├── box-selector.mdx ├── breadcrumb.mdx ├── button-with-icon.mdx ├── calendar.mdx ├── card-layout.mdx ├── card.mdx ├── carousel-slider.mdx ├── center-align-one-and-left-align-the-other.mdx ├── centering.mdx ├── chip.mdx ├── circular-navigation.mdx ├── close-button.mdx ├── color-swatch.mdx ├── concave-corners.mdx ├── cookie-banner.mdx ├── corner-ribbon.mdx ├── curved-background.mdx ├── custom-checkbox-button.mdx ├── custom-radio-button.mdx ├── diagonal-section.mdx ├── docked-at-corner.mdx ├── dot-leader.mdx ├── dot-navigation.mdx ├── drawer.mdx ├── drop-area.mdx ├── drop-cap.mdx ├── dropdown.mdx ├── fading-long-section.mdx ├── feature-comparison.mdx ├── feature-list.mdx ├── fixed-at-corner.mdx ├── fixed-at-side.mdx ├── flipping-number.mdx ├── floating-label.mdx ├── folded-corner.mdx ├── folder-structure.mdx ├── frame-corners.mdx ├── full-background.mdx ├── full-screen-menu.mdx ├── grid-lines-background.mdx ├── grid-without-double-borders.mdx ├── holy-grail.mdx ├── indeterminate-progress-bar.mdx ├── initial-avatar.mdx ├── input-addon.mdx ├── inverted-corners.mdx ├── keyboard-shortcut.mdx ├── layered-card.mdx ├── linear-gauge.mdx ├── lined-paper.mdx ├── masonry-grid.mdx ├── media-object.mdx ├── mega-menu.mdx ├── menu.mdx ├── modal.mdx ├── nested-dropdowns.mdx ├── notification.mdx ├── overlay-play-button.mdx ├── pagination.mdx ├── pie-chart.mdx ├── popover-arrow.mdx ├── presence-indicator.mdx ├── previous-next-buttons.mdx ├── price-tag.mdx ├── pricing-table.mdx ├── progress-bar.mdx ├── property-list.mdx ├── questions-and-answers.mdx ├── radial-progress-bar.mdx ├── radio-button-group.mdx ├── radio-switch.mdx ├── rating.mdx ├── resizable-element.mdx ├── ribbon.mdx ├── same-height-columns.mdx ├── search-box.mdx ├── separator.mdx ├── sidebar.mdx ├── simple-grid.mdx ├── slider.mdx ├── speech-bubble.mdx ├── spin-button.mdx ├── spinner.mdx ├── split-navigation.mdx ├── split-screen.mdx ├── stacked-cards.mdx ├── stamp-border.mdx ├── statistic.mdx ├── status-light.mdx ├── stepper-input.mdx ├── sticky-footer.mdx ├── sticky-header.mdx ├── sticky-sections.mdx ├── sticky-table-column.mdx ├── sticky-table-headers.mdx ├── switch.mdx ├── tab.mdx ├── teardrop.mdx ├── three-dimensions-card.mdx ├── timeline.mdx ├── toggle-password-visibility.mdx ├── tooltip.mdx ├── tree-diagram.mdx ├── triangle-buttons.mdx ├── upload-button.mdx ├── validation-icon.mdx ├── video-background.mdx ├── voting.mdx ├── watermark.mdx ├── wizard.mdx ├── zebra-like-background.mdx └── zigzag-timeline.mdx ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2019 phuocng Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # CSS Layout As a front-end engineer, I deal with a lot of layouts and components. While there are plenty of CSS frameworks out there that provide these, I don't always want to include them all in my project. That's why I've put together a collection of the most popular layouts and components that can be built with pure CSS. These layouts and components are powered by modern CSS features like flexbox and grid, and can be easily customized to fit your specific needs. By combining them, you can create any possible layout you need. The best part? This collection has zero dependencies, no frameworks, and no CSS hacks. These are real use cases that can save you time and effort in your projects. ## About This project is developed by _Nguyen Huu Phuoc_. I love building products and sharing knowledge. Be my friend on - [Twitter](https://twitter.com/nghuuphuoc) - [Github](https://github.com/phuocng) ================================================ FILE: contents/accordion.mdx ================================================ --- category: Display created: '2019-12-04' description: Create an accordion with CSS flexbox keywords: css accordion, css flexbox thumbnail: /assets/css-layout/thumbnails/accordion.png title: Accordion --- ## HTML ```html index.html
...
...
...
...
...
``` ## CSS ```css styles.css .accordion { /* Border */ border: 1px solid #d1d5db; border-bottom-color: transparent; border-radius: 4px; } .accordion__item { border-bottom: 1px solid #d1d5db; } .accordion__header { /* Center the content horizontally */ align-items: center; display: flex; cursor: pointer; padding: 16px; } .accordion__toggle { margin-right: 12px; } .accordion__title { /* Take remaining width */ flex: 1; } .accordion__content { border-top: 1px solid #d1d5db; padding: 16px; } .accordion__item--collapsed .accordion__content { display: none; } .accordion__item--expanded .accordion__content { display: block; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden .accordion { border: 1px solid #d1d5db; border-radius: 4px; height: 100%; width: 100%; } .accordion__item:not(:last-child) { border-bottom: 1px solid #d1d5db; } .accordion__header { align-items: center; display: flex; justify-content: center; cursor: pointer; padding: 0.5rem; } .accordion__toggle { margin-right: 0.25rem; } .accordion__title { flex: 1; } .accordion__content { padding: 0.5rem; } .accordion__item--collapsed .accordion__content { display: none; } .accordion__item--expanded .accordion__content { display: block; } ``` ```html index.html hidden
```
================================================ FILE: contents/arrow-buttons.mdx ================================================ --- category: Display created: '2020-01-21' description: Create arrow buttons with CSS keywords: css arrow buttons thumbnail: /assets/css-layout/thumbnails/arrow-buttons.png title: Arrow buttons updated: '2021-04-01' --- ## HTML ```html index.html ``` ## CSS ```css styles.css .arrow-button { /* Transparent background */ background-color: transparent; /* Size */ height: 12px; width: 12px; } .arrow-button--t { /* Edges */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translateY(25%) rotate(45deg); } .arrow-button--r { /* Edges */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translateX(-25%) rotate(45deg); } .arrow-button--b { /* Edges */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translateY(-25%) rotate(45deg); } .arrow-button--l { /* Edges */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translateX(25%) rotate(45deg); } ``` ```css styles.css hidden .arrow-buttons { position: relative; height: 100%; width: 100%; } .arrow-button { /* Transparent background */ background-color: transparent; /* Size */ height: 12px; width: 12px; } .arrow-button--t { /* Edges */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translateY(25%) rotate(45deg); } .arrow-button--r { /* Edges */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translateX(-25%) rotate(45deg); } .arrow-button--b { /* Edges */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translateY(-25%) rotate(45deg); } .arrow-button--l { /* Edges */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translateX(25%) rotate(45deg); } /* Demo */ .arrow-buttons__corner { position: absolute; } .arrow-buttons__corner--t { left: 50%; top: 0; transform: translate(-50%, 0%); } .arrow-buttons__corner--r { right: 0; top: 50%; transform: translate(0%, -50%); } .arrow-buttons__corner--b { bottom: 0; left: 50%; transform: translate(-50%, 0%); } .arrow-buttons__corner--l { left: 0; top: 50%; transform: translate(0%, -50%); } ``` ```html index.html hidden
```
================================================ FILE: contents/avatar-list.mdx ================================================ --- category: Display created: '2019-11-29' description: Create an avatar list with CSS flexbox keywords: css avatar, css flexbox thumbnail: /assets/css-layout/thumbnails/avatar-list.png title: Avatar list --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .avatars { display: flex; } .avatars__item { /* Nagative margin make avatar overlap to previous one */ margin-left: -0.25rem; } .avatars__image { /* Add a white curve between avatars */ box-shadow: 0 0 0 0.25rem #fff; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Rounded border */ border-radius: 9999px; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .avatars { display: flex; justify-content: center; height: 2rem; width: 100%; } .avatars__item { margin-left: -0.25rem; } .avatars__image { background-color: #d1d5db; box-shadow: 0 0 0 0.25rem #fff; color: #fff; font-size: 0.75rem; /* Rounded border */ border-radius: 50%; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 2rem; width: 2rem; } ``` ```html index.html hidden
A
B
C
```
================================================ FILE: contents/avatar.mdx ================================================ --- category: Display created: '2019-12-04' description: Create an avatar component with CSS flexbox keywords: css avatar, css flexbox thumbnail: /assets/css-layout/thumbnails/avatar.png title: Avatar --- ## HTML ```html index.html
``` ## CSS ```css styles.css .avatar { /* Rounded border */ border-radius: 50%; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 4rem; width: 4rem; } .avatar__image { /* Size */ height: 50%; width: 50%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .avatar { height: 4rem; width: 4rem; background-color: #d1d5db; /* Rounded border */ border-radius: 50%; /* Center the content */ align-items: center; display: flex; justify-content: center; } .avatar__image { height: 50%; width: 50%; } ``` ```html index.html hidden
```
================================================ FILE: contents/badge.mdx ================================================ --- category: Display created: '2019-11-16' description: Create a badge component with CSS flexbox keywords: css badge, css flexbox thumbnail: /assets/css-layout/thumbnails/badge.png title: Badge --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .badge { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Colors */ background-color: #d1d5db; color: #fff; /* Rounded border */ border-radius: 9999px; height: 3rem; width: 3rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .badge { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Colors */ background-color: #d1d5db; color: #fff; /* Rounded border */ border-radius: 9999px; height: 3rem; width: 3rem; } ``` ```html index.html hidden
9+
```
================================================ FILE: contents/box-selector.mdx ================================================ --- category: Input created: '2022-09-24' description: Create a box selector with CSS keywords: css box selector thumbnail: /assets/css-layout/thumbnails/box-selector.png title: Box selector --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .box-selector { border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.5rem; } .box-selector--selected { /* Change the border color */ border: 2px solid #3b82f6; /* Used to position the tick */ position: relative; } /* The tick */ .box-selector--selected:before { /* Absolute position */ content: ''; left: 0.25rem; position: absolute; top: 0.25rem; /* Size */ height: 1rem; width: 1rem; /* Background */ background-image: url("data:image/svg+xml,%3Csvg fill='%233b82f6' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'%3E%3C/path%3E%3C/svg%3E"); background-position: center center; background-repeat: no-repeat; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .box-selector-container { display: grid; grid-template-columns: repeat(2, 1fr); column-gap: 1rem; row-gap: 1rem; width: 16rem; } .box-selector { border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.5rem; } .box-selector--selected { border: 2px solid #3b82f6; position: relative; &:before { content: ''; left: 0.25rem; position: absolute; top: 0.25rem; height: 1rem; width: 1rem; background-image: url("data:image/svg+xml,%3Csvg fill='%233b82f6' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z'%3E%3C/path%3E%3C/svg%3E"); background-position: center center; background-repeat: no-repeat; } } ``` ```html index.html hidden
```
## See also - [Custom checkbox button](https://phuoc.ng/collection/css-layout/custom-checkbox-button/) - [Custom radio button](https://phuoc.ng/collection/css-layout/custom-radio-button/) ================================================ FILE: contents/breadcrumb.mdx ================================================ --- category: Navigation created: '2019-11-17' description: Create a breadcrumb with CSS flexbox keywords: css breadcrumb, css flexbox thumbnail: /assets/css-layout/thumbnails/breadcrumb.png title: Breadcrumb --- ## HTML ```html index.html ``` ## CSS ```css styles.css .breadcrumb { /* Content is centered vertically */ align-items: center; display: flex; } .breadcrumb__item { margin: 0 0.5rem; /* Used to position the separator between items */ position: relative; } .breadcrumb__item:not(:last-child)::after { /* Absolute position */ position: absolute; right: 0; top: 0; transform: translate(0.5rem, 0px); content: '/'; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .breadcrumb { /* Content is centered vertically */ align-items: center; display: flex; } .breadcrumb__item { margin: 0 0.5rem; position: relative; } .breadcrumb__item:not(:last-child)::after { /* Absolute position */ position: absolute; right: 0; top: 0; transform: translate(0.5rem, 0px); content: '/'; } ``` ```html index.html hidden ``` ================================================ FILE: contents/button-with-icon.mdx ================================================ --- category: Input created: '2019-11-17' description: Create an icon button with CSS flexbox keywords: css flexbox, css icon button thumbnail: /assets/css-layout/thumbnails/button-with-icon.png title: Button with icon --- ## HTML ```html index.html ``` ## CSS ```css styles.css .button-with-icon { /* Center the content */ align-items: center; display: flex; flex-direction: row; justify-content: center; } .button-with-icon__label { margin-left: 0.5rem; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .button-with-icon { /* Center the content */ align-items: center; display: flex; flex-direction: row; justify-content: center; /* Demo */ background: #fff; border: 1px solid #d1d5db; border-radius: 0.25rem; width: 8rem; } .button-with-icon__label { flex: 1; margin-left: 0.5rem; } ``` ```html index.html hidden ``` ================================================ FILE: contents/calendar.mdx ================================================ --- category: Display created: '2022-09-24' description: Create a calendar with CSS grid keywords: css calendar, css grid thumbnail: /assets/css-layout/thumbnails/calendar.png title: Calendar --- ## HTML ```html index.html
Mon
Tue
Wed
Thu
Fri
Sat
Sun
30
31
1
2
...
1
2
``` ## CSS ```css styles.css .calendar { display: grid; grid-template-columns: repeat(7, 1fr); } .calendar__weekday { border-bottom: 1px solid #d1d5db; padding: 0.125rem; } .calendar__day { border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; padding: 0.25rem; text-align: center; } .calendar__day--current { background-color: #3b82f6; color: #fff; } .calendar__day:nth-child(7n + 1) { border-left: 1px solid #d1d5db; } .calendar__day--disabled { color: #d1d5db; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .calendar { display: grid; grid-template-columns: repeat(7, 1fr); width: 16rem; } .calendar__weekday { border-bottom: 1px solid #d1d5db; padding: 0.5rem; text-align: center; } .calendar__day { border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; padding: 0.5rem; text-align: center; } .calendar__day--current { background-color: #3b82f6; color: #fff; } .calendar__day:nth-child(7n + 1) { border-left: 1px solid #d1d5db; } .calendar__day--disabled { color: #e5e7eb; } ``` ```html index.html hidden
Mon
Tue
Wed
Thu
Fri
Sat
Sun
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
```
================================================ FILE: contents/card-layout.mdx ================================================ --- category: Layout created: '2019-12-25' description: Create a card layout with CSS flexbox keywords: css card layout, css flexbox, css layout thumbnail: /assets/css-layout/thumbnails/card-layout.png title: Card layout --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .card-layout { display: flex; /* Put a card in the next row when previous cards take all width */ flex-wrap: wrap; margin-left: -0.25rem; margin-right: -0.25rem; } .card-layout__item { /* There will be 3 cards per row */ flex-basis: 33.33333%; padding-left: 0.25rem; padding-right: 0.25rem; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .card-layout { display: flex; /* Put a card in the next row when previous cards take all width */ flex-wrap: wrap; margin-left: -0.25rem; margin-right: -0.25rem; } .card-layout__item { /* There will be 3 cards per row */ flex-basis: 33.33333%; padding-left: 0.25rem; padding-right: 0.25rem; /* Demo */ margin: 0.25rem 0; } ``` ```html index.html hidden
```
================================================ FILE: contents/card.mdx ================================================ --- category: Display created: '2019-11-17' description: Create a card with CSS flexbox keywords: css card, css flexbox thumbnail: /assets/css-layout/thumbnails/card.png title: Card --- ## HTML ```html index.html
...
...
...
``` ## CSS ```css styles.css .card { display: flex; flex-direction: column; } .card__cover { height: 20rem; width: 100%; } .card__content { /* Take available height */ flex: 1; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .card { display: flex; flex-direction: column; width: 16rem; height: 100%; border: 1px solid #d1d5db; border-radius: 0.25rem; } .card__cover { background: #d1d5db; border-radius: 0.25rem; height: 40%; width: 100%; } .card__content { /* Take available height */ flex: 1; padding: 0.5rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/carousel-slider.mdx ================================================ --- category: Navigation created: '2023-10-14' description: Create a carousel slider with CSS openGraphCover: /og/css-layout/carousel-slider.png thumbnail: /assets/css-layout/thumbnails/carousel-slider.png title: Carousel slider --- A carousel slider is a component that lets users browse a collection of items, usually images or cards, by sliding them horizontally or vertically. It's commonly used in websites and mobile apps to showcase products, features, or news articles. You can find carousel sliders in all kinds of websites and apps, like e-commerce platforms, news portals, and social media sites. They offer an interactive and engaging way for users to navigate content without taking up too much screen space. On top of that, carousel sliders can be customized with different transition effects, autoplay options, and navigation controls. This makes for an even better user experience. In this post, we'll show you how to create a carousel slider with CSS. ## HTML markup Let's talk about organizing the markup for a slider with five items. The slider consists of a `div` element with the class `slider__inner` that displays the list of items, each with a `slider__item` class. ```html
``` For simplicity, let's assume all slider items have the same dimensions as the slider container. The `.slider` class sets the dimensions of the slider container to a `width` and `height` of 100%, taking up all available space in its parent element. The `overflow` property is set to `hidden` to ensure that any content that overflows the slider container is not visible. ```css .slider { overflow: hidden; position: relative; width: 100%; height: 20rem; } ``` Meanwhile, the `.slider__inner` class positions the list of items inside the slider container. It has an absolute position with `top` and `left` properties set to 0, placing it at the top left corner of its parent element (the slider container). The `width` and `height` are also set to 100%, filling up all available space inside its parent element. ```css .slide__inner { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } ``` To position the items inside the slider container, we use absolute positioning with `top`, `left`, `width`, and `height` properties set to 0 and 100% respectively, ensuring that each item takes up all available space inside the slider container. ```css .slider__item { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } ``` Now, to achieve the sliding effect, we use the `translateX()` function of CSS `transform` property. This function moves an element horizontally by a given percentage or pixel value. In our case, we want to move each item to the right so that only one item is visible at a time. ```html
1
2
3
4
5
``` To activate a specific item in the carousel slider, we shift the whole inner container to the left by a value that moves the target item into view. One way to achieve this is by setting the `transform` property of the `.slider__inner` element to `translateX(-300%)`. This will move the inner container three times its width to the left, which positions the fourth item at the beginning of the slider. ```html
1
2
3
4
5
``` By adjusting this value, we can easily activate any other item in our carousel slider. This technique allows us to create an interactive and engaging carousel slider that users can navigate through with ease. ## Adding navigation Now that we have placed the slider items in the right spot, it's time to add navigation so users can easily move between them. To do this, we'll create an additional element with the `slider__navigation` CSS class. This element contains multiple dots that users can click to jump to the corresponding item. Here is the updated markup: ```html
``` The `slider__navigation` element has a position of `absolute`, which means it's positioned relative to the nearest positioned ancestor (in this case, the `.slider` element). We set `bottom: 1rem` to position it at the bottom of the slider container, and `left: 50%` is used to center it horizontally. To center its content horizontally, we use `transform: translateX(-50%)`, which moves it left by half of its own width. ```css .slider__navigation { position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%); } ``` The navigation dots inside the `slider__navigation` are created using individual elements with a class of `slider__dot`. To space them out evenly, we use the CSS property `gap: 0.5rem`, which adds a gap between each item. The items are aligned along the horizontal axis using flexbox properties such as `display: flex`, `align-items: center`, and `justify-content: center`. ```css .slider__navigation { display: flex; align-items: center; justify-content: center; gap: 0.5rem; } ``` The `slider__dot` class is used to style the navigation dots inside the `slider__navigation` element. It has a background color of `rgb(203 213 225)` and a border radius of `50%`, which gives it a circular shape. It also has a `cursor` property set to `pointer`, which changes the mouse cursor when hovering over the element, indicating that it can be clicked. Finally, its dimensions are set to `height: 0.5rem` and `width: 0.5rem`, making it small enough to fit inside the navigation container but large enough to be clickable. ```css .slider__dot { background-color: rgb(203 213 225); border-radius: 50%; cursor: pointer; height: 0.5rem; width: 0.5rem; } ``` To indicate the currently active dot, we can add a separate class named `slider__dot--active` and apply it to the corresponding dot element. This class will have a different background color than the inactive dots, making it clear which item is currently active. ```css .slider__dot--active { background-color: rgb(100 116 139); } ``` When an item is activated in the slider, we can remove the `slider__dot--active` class from all dots and then add it only to the dot that corresponds to the currently active item. This ensures that only one dot is highlighted at any given time. ## Adding arrows for easy navigation In addition to the navigation we created earlier, we can further enhance the user experience by adding two buttons that allow users to quickly move to the previous and next items. Here's the updated markup: ```html
...
``` To create these buttons, we use the `.slider__prev` and `.slider__next` classes. We set their position to absolute so that they're positioned relative to the slider container. We also set the top position to `50%` and use `transform: translateY(-50%)` to center them vertically inside the slider container. Here's how they are positioned: ```css .slider__prev, .slider__next { position: absolute; top: 50%; transform: translateY(-50%); height: 1rem; width: 0.5rem; } ``` To add arrow navigation to the carousel slider, we can use CSS pseudo-elements `::before` and `::after`. These elements allow us to add content before or after an element's content, which in our case will be arrows. If you're not familiar with how to create arrows using CSS, you can check out this [post](https://phuoc.ng/collection/css-layout/triangle-buttons/) for guidance. With these CSS rules in place, you should now have fully functional arrow navigation for your carousel slider. ## Demo Let's take a look at the final result. Check out the code to see how we shifted the whole inner element to activate the fourth item. It's important to note that this is purely for layout purposes only. Clicking on the dots or arrows won't navigate to the corresponding item. Check out this [post](https://phuoc.ng/collection/css-animation/navigate-to-a-specific-item-in-a-carousel-slider/) to learn how we can make it happen. ```css styles.css .slider { overflow: hidden; position: relative; width: 100%; height: 20rem; } .slider__inner { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } .slider__item { position: absolute; top: 0; left: 0; width: 100%; height: 100%; /* Demo purpose */ background: rgb(241 245 249); align-items: center; display: flex; justify-content: center; font-size: 2.5rem; font-weight: 500; } .slider__navigation { position: absolute; bottom: 1rem; left: 50%; transform: translateX(-50%); align-items: center; display: flex; justify-content: center; gap: 0.5rem; } .slider__dot { background: rgb(203 213 225); border-radius: 50%; cursor: pointer; height: 0.5rem; width: 0.5rem; } .slider__dot--active { background: rgb(100 116 139); } .slider__prev, .slider__next { position: absolute; top: 50%; transform: translateY(-50%); height: 1rem; width: 0.5rem; } .slider__prev::before, .slider__next::before { cursor: pointer; content: ''; position: absolute; border-style: solid; height: 0; width: 0; } .slider__prev::before { border-color: transparent rgb(148 163 184) transparent transparent; border-width: 0.5rem 0.5rem 0.5rem 0; } .slider__next::before { border-color: transparent transparent transparent rgb(148 163 184); border-width: 0.5rem 0 0.5rem 0.5rem; } .slider__prev { left: 0.5rem; } .slider__next { right: 0.5rem; } ``` ```html index.html
1
2
3
4
5
```
## See also - [Dot navigation](https://phuoc.ng/collection/css-layout/dot-navigation/) - [Fixed at side](https://phuoc.ng/collection/css-layout/fixed-at-side/) - [Navigate to a specific item in a carousel slider](https://phuoc.ng/collection/css-animation/navigate-to-a-specific-item-in-a-carousel-slider/) - [Triangle buttons](https://phuoc.ng/collection/css-layout/triangle-buttons/) ================================================ FILE: contents/center-align-one-and-left-align-the-other.mdx ================================================ --- category: Display created: '2023-08-27' description: How to center align one element and left align the other keywords: css flexbox, css grid openGraphCover: /og/css-layout/center-align-one-left-align-other.png thumbnail: /assets/css-layout/thumbnails/center-align-one-left-align-other.png title: Center align one and left align the other --- Using a single row to display all elements is a common pattern in web design. These elements can be divided into different groups and arranged on the left, center, or right side of the row. You've probably seen this pattern before, like in a toolbar where the main actions are grouped and displayed at the center. Meanwhile, less important buttons are located on the left side, like a button to toggle the sidebar. Another example is the header of a web application, where the main title is displayed at the center, and a button to go back to the previous page is on the left side. In this post, we'll learn how to create this kind of layout. To keep it simple, let's assume that the layout consists of only two elements. ```html
``` ## Using CSS flexbox Initially, our first idea might be to use flexbox to arrange the layout. ```css .container { display: flex; justify-content: center; } ``` To align the first element to the left and center the remaining items, we can use the margin property. Here's an example: ```css .container__left { margin-right: auto; } .container__center { margin-right: auto; } ``` Let's take a look at what it looks like: ```css demo.css hidden :root { --placeholder-size: 1rem; } body { align-items: center; display: flex; justify-content: center; } .circle { background-color: rgb(203 213 225); border-radius: 9999px; height: var(--placeholder-size); width: var(--placeholder-size); margin-right: 0.125rem; } .square { background-color: rgb(203 213 225); border-radius: 0.25rem; height: var(--placeholder-size); width: var(--placeholder-size); margin: 0 0.125rem; } .container { border: 1px solid rgb(203 213 225); border-radius: 0.25rem; padding: 0.5rem; width: 16rem; } .container__left, .container__center { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .container { display: flex; } .container__left { margin-right: auto; } .container__center { margin-right: auto; } ``` ```html index.html
```
Unfortunately, our expectation doesn't match reality. The main element is centered only within the available space, not the entire container. Let's move on to the next section to find a solution to this issue. ## Using CSS grid In addition to CSS flexbox, CSS offers another powerful tool for creating layouts: CSS grid. We can use this technique to solve the issue we talked about earlier. Let's say we now have three elements in our layout instead of two, and we need to add an empty element on the right-hand side. ```css .container { display: grid; grid-template-columns: 1fr repeat(1, auto) 1fr; } ``` Let's dive into some CSS talk. The first CSS declaration is simple: it replaces the `flex` value with `grid`, which tells the browser to create a grid layout. Now, the second CSS declaration might seem confusing, but it's actually quite easy to understand. The `1fr` means that the first and last columns should take up an equal amount of space. The `repeat(1, auto)` declaration means that there should be one column with a width of `auto`. So, in simpler terms, this CSS declaration creates a layout with three columns. The first and last columns will have equal width, while the middle column will adjust its width to fit its content. Lastly, we want the main element to start at the second column. So, we can set the `grid-column-start` property to 2. ```css .container__center { grid-column-start: 2; } ``` Now, it's a breeze to move the first column to the left. ```css .container__left { margin-right: auto; } ``` Finally, let's check out the demonstration to see the progress we've made so far! ```css demo.css hidden :root { --placeholder-size: 1rem; } body { align-items: center; display: flex; justify-content: center; } .circle { background-color: rgb(203 213 225); border-radius: 9999px; height: var(--placeholder-size); width: var(--placeholder-size); margin-right: 0.125rem; } .square { background-color: rgb(203 213 225); border-radius: 0.25rem; height: var(--placeholder-size); width: var(--placeholder-size); margin: 0 0.125rem; } .container { border: 1px solid rgb(203 213 225); border-radius: 0.25rem; padding: 0.5rem; width: 16rem; } .container__left, .container__center { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .container { display: grid; grid-template-columns: 1fr repeat(1, auto) 1fr; } .container__left { margin-right: auto; } .container__center { grid-column-start: 2; } ``` ```html index.html
```
Replacing the non-existing third column with the real one is a piece of cake. All you need to do is push it to the right using a single CSS declaration. ```css .container__right { margin-left: auto; } ``` ```css demo.css hidden :root { --placeholder-size: 1rem; } body { align-items: center; display: flex; justify-content: center; } .circle { background-color: rgb(203 213 225); border-radius: 9999px; height: var(--placeholder-size); width: var(--placeholder-size); margin-right: 0.125rem; } .square { background-color: rgb(203 213 225); border-radius: 0.25rem; height: var(--placeholder-size); width: var(--placeholder-size); margin: 0 0.125rem; } .container { border: 1px solid rgb(203 213 225); border-radius: 0.25rem; padding: 0.5rem; width: 16rem; } .container__left, .container__center, .container__right { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css hidden .container { display: grid; grid-template-columns: 1fr repeat(1, auto) 1fr; } .container__left { margin-right: auto; } .container__center { grid-column-start: 2; } .container__right { margin-left: auto; } ``` ```html index.html hidden
```
## Usages In addition to the sample usages mentioned earlier, I've been using this technique to create a layout that centers the main content of the page while aligning the sidebar to the right side of the screen. Here's an example of what the layout looks like: ```css demo.css hidden .container { border: 1px solid rgb(203 213 225); width: 100%; height: 16rem; } .container__main { align-items: center; display: flex; justify-content: center; background: rgb(203 213 225); width: 9rem; } .container__sidebar { align-items: center; display: flex; justify-content: center; background: rgb(226 232 240); width: 4rem; } @media (min-width: 600px) { .container__main { width: 15rem; } .container__sidebar { width: 8rem; } } ``` ```css styles.css .container { display: grid; grid-template-columns: 1fr repeat(1, auto) 1fr; } .container__main { grid-column-start: 2; } .container__sidebar { margin-left: auto; } ``` ```html index.html
Main
Sidebar
```
================================================ FILE: contents/centering.mdx ================================================ --- category: Display created: '2019-11-15' description: Center an element with CSS flexbox keywords: css centering, css flexbox thumbnail: /assets/css-layout/thumbnails/centering.png title: Centering --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .centering { align-items: center; display: flex; justify-content: center; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .centering { align-items: center; display: flex; justify-content: center; /* Demo */ flex-direction: column; width: 16rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/chip.mdx ================================================ --- category: Input created: '2019-12-21' description: Create a chip component with CSS flexbox keywords: css chip, css flexbox, css tag thumbnail: /assets/css-layout/thumbnails/chip.png title: Chip --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .chip { /* Center the content */ align-items: center; display: inline-flex; justify-content: center; /* Background color */ background-color: #d1d5db; /* Rounded border */ border-radius: 9999px; /* Spacing */ padding: 0.25rem 0.5rem; } .chip__content { margin-right: 0.25rem; } ``` The [close button](https://phuoc.ng/collection/css-layout/close-button/) is used to create a button for removing the chip: ```css .chip__button { /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 1rem; width: 1rem; /* Used to position the inner */ position: relative; } .chip__button-line { /* Background color */ background-color: #9ca3af; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .chip__button-line--first { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .chip__button-line--second { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .chip { /* Center the content */ align-items: center; display: inline-flex; justify-content: center; /* Background color */ background-color: #d1d5db; /* Rounded border */ border-radius: 9999px; /* Spacing */ padding: 0.25rem 0.5rem; } .chip__content { margin-right: 0.25rem; } .chip__button { /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 1rem; width: 1rem; /* Used to position the inner */ position: relative; } .chip__button-line { /* Background color */ background-color: #9ca3af; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .chip__button-line--first { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .chip__button-line--second { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```html index.html hidden
CSS
```
================================================ FILE: contents/circular-navigation.mdx ================================================ --- category: Navigation created: '2019-11-30' description: Create a circular navigation with CSS flexbox keywords: css circular navigation, css flexbox thumbnail: /assets/css-layout/thumbnails/circular-navigation.png title: Circular navigation --- ## HTML ```html index.html
...
...
...
``` ## CSS ```css styles.css .circular-navigation { position: relative; } .circular-navigation__circle { /* Position */ position: absolute; top: 0; /* 3rem is the distance from the item to the trigger element. Replace 0deg with 60deg, 180deg, 240deg, 300deg for another item in case you want to have a total of 6 menu items. The formulation is 360 / numberOfItems * indexOfItem */ transform: rotate(0deg) translateX(-3rem); /* Must have the same size as the trigger element */ height: 2rem; width: 2rem; } .circular-navigation__content { /* Rotate it to make it displayed vertically Replace -0deg with -60deg, -180deg, -240deg, -300deg for another item in case you want to have a total of 6 menu items. The formulation is -(360 / numberOfItems * indexOfItem) */ transform: rotate(-0deg); /* Center the content */ align-items: center; display: flex; justify-content: center; /* Take full size */ height: 100%; width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .circular-navigation-container { /* Demo */ align-items: center; display: flex; justify-content: center; height: 8rem; width: 8rem; } .circular-navigation { position: relative; height: 2rem; width: 2rem; } .circular-navigation__circle { /* Position */ position: absolute; top: 0; /* 3rem is the distance from the item to the trigger element. Replace 0deg with 60deg, 180deg, 240deg, 300deg for another item in case you want to have a total of 6 menu items. The formulation is 360 / numberOfItems * indexOfItem */ transform: rotate(var(--circular-navigation__circle-degree)) translateX(-3rem); /* Must have the same size as the trigger element */ height: 2rem; width: 2rem; /* Demo */ background-color: #d1d5db; border-radius: 9999px; } .circular-navigation__content { /* Rotate it to make it displayed vertically Replace -0deg with -60deg, -180deg, -240deg, -300deg for another item in case you want to have a total of 6 menu items. The formulation is -(360 / numberOfItems * indexOfItem) */ transform: rotate(var(--circular-navigation__content-degree)); /* Center the content */ align-items: center; display: flex; justify-content: center; /* Take full size */ height: 100%; width: 100%; } .circular-navigation__circle--1 { --circular-navigation__circle-degree: 0deg; --circular-navigation__content-degree: -0deg; } .circular-navigation__circle--2 { --circular-navigation__circle-degree: 60deg; --circular-navigation__content-degree: -60deg; } .circular-navigation__circle--3 { --circular-navigation__circle-degree: 120deg; --circular-navigation__content-degree: -120deg; } .circular-navigation__circle--4 { --circular-navigation__circle-degree: 180deg; --circular-navigation__content-degree: -180deg; } .circular-navigation__circle--5 { --circular-navigation__circle-degree: 240deg; --circular-navigation__content-degree: -240deg; } .circular-navigation__circle--6 { --circular-navigation__circle-degree: 300deg; --circular-navigation__content-degree: -300deg; } ``` ```html index.html hidden
1
2
3
4
5
6
```
================================================ FILE: contents/close-button.mdx ================================================ --- category: Display created: '2019-12-11' description: Create a close button with CSS flexbox keywords: css close button, css flexbox thumbnail: /assets/css-layout/thumbnails/close-button.png title: Close button --- ## HTML ```html index.html ``` ## CSS ```css styles.css .close-button { /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 3rem; width: 3rem; /* Used to position the inner */ position: relative; } .close-button__line { /* Background color */ background-color: #d1d5db; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .close-button__line--first { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .close-button__line--second { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .close-button { /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 3rem; width: 3rem; /* Used to position the inner */ position: relative; } .close-button__line { /* Background color */ background-color: #d1d5db; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .close-button__line--first { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .close-button__line--second { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```html index.html hidden ``` ================================================ FILE: contents/color-swatch.mdx ================================================ --- category: Display created: '2021-05-08' description: Create a color swatch with CSS flexbox keywords: css color swatch, css flexbox thumbnail: /assets/css-layout/thumbnails/color-swatch.png title: Color swatch --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .swatch { /* Wrap the items */ display: flex; flex-wrap: wrap; } .swatch__item { /* Rounded border */ border-radius: 9999px; height: 1.5rem; width: 1.5rem; /* Space between items */ margin: 0.5rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .swatch { /* Wrap the items */ align-items: center; display: flex; justify-content: center; flex-wrap: wrap; } .swatch__item { /* Rounded border */ border-radius: 9999px; height: 1.5rem; width: 1.5rem; /* Space between items */ margin: 0.5rem; } .swatch__item--1st { background-color: rgba(0, 0, 0, 0.1); } .swatch__item--2nd { background-color: rgba(0, 0, 0, 0.2); } .swatch__item--3rd { background-color: #d1d5db; } .swatch__item--4th { background-color: rgba(0, 0, 0, 0.4); } .swatch__item--5th { background-color: rgba(0, 0, 0, 0.5); } .swatch__item--6th { background-color: rgba(0, 0, 0, 0.6); } ``` ```html index.html hidden
```
================================================ FILE: contents/concave-corners.mdx ================================================ --- category: Display created: '2021-05-09' description: Create concave corners with CSS keywords: css border radius, css concave border radius, css concave corners thumbnail: /assets/css-layout/thumbnails/concave-corners.png title: Concave corners --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .concave-corners { background-color: #d1d5db; /* Used to position the corners */ position: relative; } .concave-corners__corner { /* Absolute position */ position: absolute; /* Size */ height: 1rem; width: 1rem; background: #fff; } .concave-corners__corner--tl { /* Position */ left: 0; top: 0; /* Border radius */ border-radius: 0 0 1rem 0; } .concave-corners__corner--tr { /* Position */ right: 0; top: 0; /* Border radius */ border-radius: 0 0 0 1rem; } .concave-corners__corner--bl { /* Position */ bottom: 0; left: 0; /* Border radius */ border-radius: 0 1rem 0 0; } .concave-corners__corner--br { /* Position */ bottom: 0; right: 0; /* Border radius */ border-radius: 1rem 0 0 0; } ``` ```css styles.css hidden body { height: 24rem; } .concave-corners { background-color: #d1d5db; /* Used to position the corners */ position: relative; /* Misc */ height: 100%; width: 100%; } .concave-corners__corner { /* Absolute position */ position: absolute; /* Size */ height: 1rem; width: 1rem; background: #fff; } .concave-corners__corner--tl { /* Position */ left: 0; top: 0; /* Border radius */ border-radius: 0 0 1rem 0; } .concave-corners__corner--tr { /* Position */ right: 0; top: 0; /* Border radius */ border-radius: 0 0 0 1rem; } .concave-corners__corner--bl { /* Position */ bottom: 0; left: 0; /* Border radius */ border-radius: 0 1rem 0 0; } .concave-corners__corner--br { /* Position */ bottom: 0; right: 0; /* Border radius */ border-radius: 1rem 0 0 0; } ``` ```html index.html hidden
```
================================================ FILE: contents/cookie-banner.mdx ================================================ --- category: Display created: '2019-11-30' description: Create a cookie banner with CSS flexbox keywords: css cookie banner, css flexbox thumbnail: /assets/css-layout/thumbnails/cookie-banner.png title: Cookie banner --- ## HTML ```html index.html ``` ## CSS ```css styles.css .cookie-banner { /* Banner is displayed at the bottom */ bottom: 0; left: 0; position: fixed; width: 100%; /* Center the content */ align-items: center; display: flex; justify-content: center; } .cookie-banner__content { /* Take available width */ flex: 1; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .cookie-banner { border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; align-items: end; display: flex; } .cookie-banner__content { border-top: 1px solid #d1d5db; /* Take available width */ flex: 1; padding: 0 0.5rem; } ``` ```html index.html hidden ``` ================================================ FILE: contents/corner-ribbon.mdx ================================================ --- category: Display created: '2019-12-01' description: Create a corner ribbon with CSS flexbox keywords: css flexbox, css ribbon thumbnail: /assets/css-layout/thumbnails/corner-ribbon.png title: Corner ribbon --- ## HTML ```html index.html
``` ## CSS ```css styles.css .corner-ribbon { position: relative; } .corner-ribbon__inner { /* Displayed at the top left corner */ left: 0px; position: absolute; top: 0px; /* Size */ height: 4rem; width: 4rem; /* Hide the part of its children which is displayed outside */ overflow: hidden; } .corner-ribbon__ribbon { /* Position */ left: 1rem; position: absolute; top: 1rem; /* Size */ height: 1.5rem; width: 5.656rem; /* Displayed diagonally */ transform: translate(-38px, -8px) rotate(-45deg); /* Background color */ background-color: #d1d5db; /* Centerize the text content */ text-align: center; } ``` ```css styles.css hidden body { height: 24rem; } .corner-ribbon { position: relative; border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; } .corner-ribbon__inner { /* Displayed at the top left corner */ left: 0px; position: absolute; top: 0px; /* Size */ height: 4rem; width: 4rem; /* Hide the part of its children which is displayed outside */ overflow: hidden; } .corner-ribbon__ribbon { /* Position */ left: 1rem; position: absolute; top: 1rem; /* Size */ height: 1.5rem; width: 5.656rem; /* Displayed diagonally */ transform: translate(-38px, -8px) rotate(-45deg); /* Background color */ background-color: #d1d5db; /* Centerize the text content */ text-align: center; } ``` ```html index.html hidden
```
================================================ FILE: contents/curved-background.mdx ================================================ --- category: Display created: '2020-01-17' description: Create an element with curved background keywords: css border radius, css curved background thumbnail: /assets/css-layout/thumbnails/curved-background.png title: Curved background --- ## HTML ```html index.html
``` ## CSS ```css styles.css .curved-background__curved { /* Background color */ background-color: #d1d5db; /* You can use gradient background color such as */ /* background: linear-gradient(rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.1) 100%); */ /* Curved corners */ border-bottom-left-radius: 50% 40%; border-bottom-right-radius: 50% 40%; /* Size */ height: 50%; width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .curved-background { border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; } .curved-background__curved { background-color: #d1d5db; border-bottom-left-radius: 50% 40%; border-bottom-right-radius: 50% 40%; height: 8rem; width: 100%; } ``` ```html index.html hidden
```
================================================ FILE: contents/custom-checkbox-button.mdx ================================================ --- category: Input created: '2019-12-01' description: Create a custom checkbox button with CSS flexbox keywords: css checkbox, css flexbox thumbnail: /assets/css-layout/thumbnails/custom-checkbox-button.png title: Custom checkbox button --- ## HTML ```html index.html ``` ## CSS ```css styles.css .custom-checkbox-button { /* Center the content horizontally */ align-items: center; display: inline-flex; /* Cursor */ cursor: pointer; } .custom-checkbox-button__input { /* Hide it */ display: none; } .custom-checkbox-button__square { border: 1px solid #d1d5db; border-radius: 0.25rem; /* Spacing */ margin-right: 0.5rem; padding: 0.25rem; } .custom-checkbox-button__checkbox { background-color: transparent; border-radius: 0.25rem; height: 1rem; width: 1rem; } .custom-checkbox-button__checkbox--selected { /* For selected checkbox */ background-color: #3b82f6; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .custom-checkbox-button { /* Center the content horizontally */ align-items: center; display: flex; /* Cursor */ cursor: pointer; /* Demo */ margin: 0.25rem 0; width: 16rem; } .custom-checkbox-button__input { /* Hide it */ display: none; } .custom-checkbox-button__square { border: 1px solid #d1d5db; border-radius: 0.25rem; /* Spacing */ margin-right: 0.5rem; padding: 0.25rem; } .custom-checkbox-button__checkbox { background-color: transparent; border-radius: 0.25rem; height: 1rem; width: 1rem; } .custom-checkbox-button__checkbox--selected { /* For selected checkbox */ background-color: #3b82f6; } ``` ```html index.html hidden ``` ## See also - [Box selector](https://phuoc.ng/collection/css-layout/box-selector/) - [Custom radio button](https://phuoc.ng/collection/css-layout/custom-radio-button/) ================================================ FILE: contents/custom-radio-button.mdx ================================================ --- category: Input created: '2019-12-01' description: Create a custom radio button with CSS flexbox keywords: css flexbox, css radio thumbnail: /assets/css-layout/thumbnails/custom-radio-button.png title: Custom radio button --- ## HTML ```html index.html ``` ## CSS ```css styles.css .custom-radio-button { /* Center the content horizontally */ align-items: center; display: inline-flex; /* Cursor */ cursor: pointer; } .custom-radio-button__input { /* Hide it */ display: none; } .custom-radio-button__circle { /* Rounded border */ border: 1px solid #d1d5db; border-radius: 9999px; /* Spacing */ margin-right: 0.5rem; padding: 0.25rem; } .custom-radio-button__radio { /* Rounded border */ border-radius: 9999px; height: 1rem; width: 1rem; /* For not selected radio */ background-color: transparent; } .custom-radio-button__radio--selected { /* For selected radio */ background-color: #3b82f6; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .custom-radio-button { /* Center the content horizontally */ align-items: center; display: flex; /* Cursor */ cursor: pointer; /* Demo */ margin: 0.25rem 0; width: 16rem; } .custom-radio-button__input { /* Hide it */ display: none; } .custom-radio-button__circle { /* Rounded border */ border: 1px solid #d1d5db; border-radius: 9999px; /* Spacing */ margin-right: 0.5rem; padding: 0.25rem; } .custom-radio-button__radio { /* Rounded border */ border-radius: 9999px; height: 1rem; width: 1rem; /* For not selected radio */ background-color: transparent; } .custom-radio-button__radio--selected { /* For selected radio */ background-color: #3b82f6; } ``` ```html index.html hidden ``` ## See also - [Box selector](https://phuoc.ng/collection/css-layout/box-selector/) - [Custom checkbox button](https://phuoc.ng/collection/css-layout/custom-checkbox-button/) ================================================ FILE: contents/diagonal-section.mdx ================================================ --- category: Display created: '2019-12-25' description: Create a diagonal section with CSS keywords: css diagonal section, css transform skew thumbnail: /assets/css-layout/thumbnails/diagonal-section.png title: Diagonal section --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .diagonal-section { /* Used to position the diagonal area */ position: relative; } .diagonal-section__diagonal { /* Absolute position */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Create diagonal sides */ transform: skewY(-5deg); /* Background color */ background-color: #d1d5db; /* Displayed under the main content */ z-index: -1; } ``` ```css styles.css hidden body { height: 24rem; } .diagonal-section { /* Used to position the diagonal area */ position: relative; height: 100%; width: 100%; } .diagonal-section__diagonal { /* Absolute position */ left: 0px; position: absolute; top: 50%; /* Take full size */ height: 2rem; width: 100%; /* Create diagonal sides */ transform: translate(0, -50%) skewY(-15deg); /* Background color */ background-color: #d1d5db; } ``` ```html index.html hidden
```
================================================ FILE: contents/docked-at-corner.mdx ================================================ --- category: Display created: '2019-11-23' description: Dock an element at corner with CSS keywords: css docked, css flexbox thumbnail: /assets/css-layout/thumbnails/docked-at-corner.png title: Docked at corner --- ## HTML ```html index.html
``` ## CSS ```css styles.css .docked-at-corner { position: relative; } .docked-at-corner__docker { position: absolute; right: 0; top: 0; transform: translate(50%, -50%); /* Center the content */ align-items: center; display: flex; justify-content: center; } ``` ```css styles.css hidden body { align-items: center; display: flex; height: 24rem; justify-content: center; } .docked-at-corner { position: relative; height: 16rem; width: 20rem; border: 1px solid #d1d5db; border-radius: 0.25rem; } .docked-at-corner__docker { background-color: #22c55e; border-radius: 9999px; position: absolute; right: 0; top: 0; transform: translate(50%, -50%); /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 1rem; width: 1rem; } ``` ```html index.html hidden
```
## See also - Discover how to animate a docked element using the [pulse animation](https://phuoc.ng/collection/css-animation/pulse-animation/) ================================================ FILE: contents/dot-leader.mdx ================================================ --- category: Display created: '2019-11-27' description: Create dot leaders with CSS flexbox keywords: css dot leader, css flexbox thumbnail: /assets/css-layout/thumbnails/dot-leader.png title: Dot leader --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .dot-leader { /* Center the content */ align-items: center; display: flex; justify-content: center; } .dot-leader__dots { /* Bottom border */ border-bottom: 1px dotted #d1d5db; /* Take remaining width */ flex: 1; /* Spacing */ margin: 0 0.25rem; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .dot-leader { width: 16rem; /* Center the content */ align-items: center; display: flex; justify-content: center; margin: 1rem 0; } .dot-leader__dots { /* Bottom border */ border-bottom: 1px dotted #d1d5db; /* Take remaining width */ flex: 1; /* Spacing */ margin: 0 0.25rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/dot-navigation.mdx ================================================ --- category: Navigation created: '2019-11-22' description: Create dot navigation with CSS flexbox keywords: css dot navigation, css flexbox thumbnail: /assets/css-layout/thumbnails/dot-navigation.png title: Dot navigation --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .dot-navigation { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Reset styles */ list-style-type: none; margin: 0; padding: 0; } .dot-navigation__item { /* Rounded border */ border-radius: 9999px; height: 0.75rem; width: 0.75rem; /* Inactive dot */ background-color: transparent; border: 1px solid #d1d5db; /* OPTIONAL: Spacing between dots */ margin: 0 0.25rem; } /* Active dot */ .dot-navigation__item--active { background-color: #d1d5db; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .dot-navigation { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Reset styles */ list-style-type: none; margin: 0; padding: 0; } .dot-navigation__item { /* Rounded border */ border-radius: 9999px; height: 0.75rem; width: 0.75rem; /* Inactive dot */ background-color: transparent; border: 1px solid #d1d5db; /* OPTIONAL: Spacing between dots */ margin: 0 0.25rem; } .dot-navigation__item--active { background-color: #d1d5db; } ``` ```html index.html hidden
```
## See also - [Carousel slider](https://phuoc.ng/collection/css-layout/carousel-slider/) ================================================ FILE: contents/drawer.mdx ================================================ --- category: Navigation created: '2019-12-13' description: Create a drawer navigation with CSS keywords: css drawer, css off-canvas thumbnail: /assets/css-layout/thumbnails/drawer.png title: Drawer --- This pattern is also known as off-canvas. ## HTML ```html index.html
...
``` ## CSS ```css styles.css .drawer { /* Take full size */ height: 100%; left: 0; position: fixed; top: 0; width: 100%; z-index: 9999; } .drawer__overlay { /* Take full size */ height: 100%; left: 0; position: fixed; top: 0; width: 100%; /* User still can see the content of main page */ background-color: rgba(0, 0, 0, 0.5); z-index: -1; } .drawer__sidebar { /* Take full height */ height: 100%; left: 0; position: fixed; top: 0; width: 200px; /* Background */ background-color: #fff; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .drawer { /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; display: flex; } .drawer__sidebar { /* Demo */ border-right: 1px solid #d1d5db; width: 25%; } .drawer__overlay { /* Demo */ background: #4b5563; flex: 1; } ``` ```html index.html hidden
```
================================================ FILE: contents/drop-area.mdx ================================================ --- category: Display created: '2019-11-27' description: Create a dropping area with CSS flexbox keywords: css dropping area, css flexbox thumbnail: /assets/css-layout/thumbnails/drop-area.png title: Drop area --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .drop-area { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Border */ border: 0.25rem dashed #d1d5db; border-radius: 0.25rem; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .drop-area { padding: 0.5rem; height: 100%; width: 100%; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Border */ border: 0.25rem dashed #d1d5db; border-radius: 0.25rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/drop-cap.mdx ================================================ --- category: Display created: '2019-11-29' description: Create a drop cap with CSS keywords: css drop cap, css :first-letter thumbnail: /assets/css-layout/thumbnails/drop-cap.png title: Drop cap --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .drop-cap:first-letter { /* Display at the left */ float: left; line-height: 1; /* Spacing */ margin: 0 0.5rem 0 0; padding: 0 0.5rem; /* Optional */ border: 2px solid #d1d5db; font-size: 2rem; font-weight: 700; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .drop-cap { overflow: hidden; } .drop-cap:first-letter { border: 2px solid #d1d5db; /* Display at the left */ float: left; line-height: 1; /* Spacing */ margin: 0 0.5rem 0 0; padding: 0 0.5rem; /* Optional */ font-size: 2rem; font-weight: 700; } ``` ```html index.html hidden
CSS is a style sheet language used for describing the presentation of a document written in a markup language like HTML. CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript.
```
================================================ FILE: contents/dropdown.mdx ================================================ --- category: Navigation created: '2019-11-29' description: Create a dropdown with CSS keywords: css dropdown, css menu thumbnail: /assets/css-layout/thumbnails/dropdown.png title: Dropdown --- ## HTML ```html index.html ``` ## CSS ```css styles.css .dropdown { position: relative; } .dropdown__trigger { cursor: pointer; } /* Hide the dropdown's content by default */ .dropdown__content { display: none; /* Position it right below the trigger element */ left: 0; padding-top: 0.25rem; position: absolute; top: 100%; /* It should be on the top of other elements */ background-color: #fff; z-index: 9999; } /* Show the content when hover on the container */ .dropdown:hover .dropdown__content { display: block; } ``` You can use a [triangle button](https://phuoc.ng/collection/css-layout/triangle-buttons/) to indicate that there is content under it. Move the mouse over the button to see the dropdown. ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; height: 24rem; } .dropdown { position: relative; /* Demo */ width: 6rem; align-items: flex-start; display: flex; justify-content: center; } .dropdown__trigger { cursor: pointer; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 2rem; width: 6rem; padding: 0.25rem 0.5rem; align-items: center; display: flex; justify-content: center; } /* Hide the dropdown's content by default */ .dropdown__content { display: none; /* Position it right below the trigger element */ left: 0; padding-top: 0.25rem; position: absolute; top: 100%; /* It should be on the top of other elements */ background-color: #fff; z-index: 9999; } .dropdown__body { /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 6rem; width: 8rem; } /* Show the content when hover on the container */ .dropdown:hover .dropdown__content { display: block; } ``` ```html index.html hidden ``` ================================================ FILE: contents/fading-long-section.mdx ================================================ --- category: Display created: '2020-01-10' description: Fading long section to indicate there is more content keywords: css fading overflow, css linear gradient thumbnail: /assets/css-layout/thumbnails/fading-long-section.png title: Fading long section --- The pattern is often used to indicate there is more content. ## HTML ```html index.html
...
``` ## CSS ```css styles.css .fading-long-section { /* Used to position the faded element */ position: relative; } .fading-long-section__content { /* Height */ height: 100%; overflow-y: hidden; } .fading-long-section__fading { /* Displayed at the bottom */ bottom: 0; left: 0; position: absolute; /* Size */ height: 2rem; width: 100%; /* Gradient background */ background: linear-gradient(rgba(255, 255, 255, 0.01), #fff); } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; margin: 0.5rem 0; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden .fading-long-section { /* Used to position the faded element */ position: relative; height: 24rem; } .fading-long-section__content { /* Height */ height: 100%; overflow-y: hidden; } .fading-long-section__fading { /* Displayed at the bottom */ bottom: 0; left: 0; position: absolute; /* Size */ height: 2rem; width: 100%; /* Gradient background */ background: linear-gradient(rgba(255, 255, 255, 0.01), #fff); } ``` ```html index.html hidden
```
## See also - [Create a reference using React.createRef()](https://phuoc.ng/collection/react-ref/create-a-reference-using-react-create-ref/) - [Customer logos marquee](https://phuoc.ng/collection/css-animation/customer-logos-marquee/) ================================================ FILE: contents/feature-comparison.mdx ================================================ --- category: Display created: '2019-12-11' description: Create a feature comparison list with CSS flexbox keywords: css feature comparison, css flexbox thumbnail: /assets/css-layout/thumbnails/feature-comparison.png title: Feature comparison --- ## HTML ```html index.html
...
...
...
... ``` ## CSS ```css styles.css .feature-comparison { align-items: center; display: flex; /* Bottom border */ border-bottom: 1px solid #d1d5db; /* Spacing */ padding: 0.25rem 0; } .feature-comparison__feature { /* Take available width */ flex: 1; } .feature-comparison__model { /* Center the content */ display: flex; justify-content: center; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden .feature-comparison { align-items: center; display: flex; /* Bottom border */ border-bottom: 1px solid #d1d5db; /* Spacing */ padding: 0.25rem 0; width: 100%; } .feature-comparison__feature { /* Take available width */ flex: 1; } .feature-comparison__model { /* Center the content */ display: flex; justify-content: center; /* Demo */ width: 1.5rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/feature-list.mdx ================================================ --- category: Display created: '2019-11-21' description: Create a feature list with CSS flexbox keywords: css feature list, css flexbox thumbnail: /assets/css-layout/thumbnails/feature-list.png title: Feature list --- ## HTML ```html index.html
...
...
... ``` ## CSS ```css styles.css .feature-list { display: flex; /* OPTIONAL: Spacing between items */ margin: 0.5rem 0; } /* Reverse the order of image and content */ .feature-list--reverse { flex-direction: row-reverse; } .feature-list__image { width: 2rem; } .feature-list__desc { /* Take the remaining width */ flex: 1; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .feature-list { display: flex; /* OPTIONAL: Spacing between items */ margin: 0.5rem 0; width: 16rem; } .feature-list--reverse { flex-direction: row-reverse; } .feature-list__image { width: 2rem; } .feature-list__desc { /* Take the remaining width */ flex: 1; } ``` ```html index.html hidden
```
================================================ FILE: contents/fixed-at-corner.mdx ================================================ --- category: Display created: '2019-11-17' description: Fix an element at corner with CSS keywords: css fixed thumbnail: /assets/css-layout/thumbnails/fixed-at-corner.png title: Fixed at corner --- ## HTML ```html index.html
...
...
...
...
``` ## CSS ```css styles.css .fixed-at-corner { position: relative; } .fixed-at-corner__corner { position: absolute; } .fixed-at-corner__corner--tl { left: 0; top: 0; } .fixed-at-corner__corner--tr { top: 0; right: 0; } .fixed-at-corner__corner--br { bottom: 0; right: 0; } .fixed-at-corner__corner--bl { bottom: 0; left: 0; } ``` ```css placeholders.css hidden .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .fixed-at-corner { width: 100%; height: 100%; border: 1px solid #d1d5db; border-radius: 0.25rem; position: relative; } .fixed-at-corner__corner { position: absolute; } .fixed-at-corner__corner--tl { left: 0; top: 0; } .fixed-at-corner__corner--tr { top: 0; right: 0; } .fixed-at-corner__corner--br { bottom: 0; right: 0; } .fixed-at-corner__corner--bl { bottom: 0; left: 0; } ``` ```html index.html hidden
```
================================================ FILE: contents/fixed-at-side.mdx ================================================ --- category: Display created: '2019-12-21' description: Fix an element at the middle of side with CSS keywords: css fixed thumbnail: /assets/css-layout/thumbnails/fixed-at-side.png title: Fixed at side --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .fixed-at-side { position: fixed; top: 50%; transform: translate(0px, -50%); } .fixed-at-side--l { left: 0; } .fixed-at-side--r { right: 0; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .fixed-at-side { width: 100%; height: 100%; border: 1px solid #d1d5db; border-radius: 0.25rem; position: relative; } .fixed-at-side__side { height: 40%; position: absolute; top: 50%; transform: translate(0px, -50%); } .fixed-at-side__side--l { left: 0; } .fixed-at-side__side--r { right: 0; } ``` ```html index.html hidden
```
## See also - [Carousel slider](https://phuoc.ng/collection/css-layout/carousel-slider/) ================================================ FILE: contents/flipping-number.mdx ================================================ --- category: Display created: '2023-09-07' description: Create a flipping number in CSS keywords: css flipping number, css flipping clock, css flipping counter openGraphCover: /og/css-layout/flipping-number.png thumbnail: /assets/css-layout/thumbnails/flipping-number.png title: Flipping number --- Flipping number layout is a popular display format used in digital clocks, countdown timers, and scoreboards. It uses multiple panels to show each digit of a number, and each panel can flip over to reveal the next number, giving the impression of an analog clock face. In web design, flip numbers are a great way to create unique and eye-catching interfaces. They're perfect for displaying all kinds of information, such as scores, prices, or countdowns. In this post, we'll learn how to create a flipping number using CSS. Get ready to impress your users with a stunning display! ## Markup First things first, let's prepare the layout for our flipping number. It's a simple layout that involves two elements. The container element creates the top and bottom flipping effects, while the inner element is used to display the number. ```html
42
``` ## Adding effects Instead of creating separate elements for the top and bottom backgrounds, we can simplify things by using pseudo-elements. The `::before` element can handle the top background, while the `::after` element can generate the bottom background. To make this work, we need to position the pseudo-element absolutely within the container. We can do this by using the `position` property with different values: ```css .flip { overflow: hidden; } .flip::before { content: ''; position: absolute; } ``` It's important to remember that the pseudo-element won't be visible without the `content` property. In our case, the `::before` element doesn't have any content, so we can simply set the `content` property to empty. Now, let's focus on the `::before` element, which will cover the first half of the container. We can use a combination of `top`, `left`, `height`, and `width` properties to indicate its position and dimensions: ```css .flip::before { top: 0; left: 0; height: 50%; width: 100%; } ``` Lastly, let's create a gradient for the top half using the `linear-gradient` function. This will allow us to set the `background` property in the following way: ```css .flip::before { background: linear-gradient(to right bottom, rgb(71 85 105), rgb(15 23 42)); } ``` In the code above, we're passing several parameters to the `linear-gradient` function. The first parameter, `to right bottom`, sets the direction of the gradient. In this case, it means the gradient will start at the top left and end at the bottom right. The second and third parameters are colors that determine the start and end points of the gradient. The first color, `rgb(71 85 105)`, is a darker shade representing the starting point. The second color, `rgb(15 23 42)`, is an even darker shade representing the ending point. ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css hidden .flip { display: inline-flex; padding: 1rem; position: relative; border-radius: 0.5rem; overflow: hidden; } .flip::before { content: ''; position: absolute; top: 0; left: 0; height: 50%; width: 100%; background: linear-gradient(to right bottom, rgb(71 85 105), rgb(15 23 42)); } .flip__number { color: #fff; font-size: 4rem; font-weight: 600; z-index: 1; } ``` ```html index.html hidden
42
```
We can use the same steps for the bottom half, with only one difference: the position and background color. Since the bottom half is positioned at the bottom, it will reset the `bottom` and `left` properties to zero. Here's how the bottom half can be created using the `::after` pseudo-element. ```css .flip::after { content: ''; position: absolute; bottom: 0; left: 0; height: 50%; width: 100%; background: linear-gradient(to right bottom, rgb(100 116 139), rgb(15 23 42)); } ``` Finally, to ensure that content is displayed on top of pseudo-elements, we need to set the `z-index` property. ```css .flip__number { z-index: 1; } ``` Check out the result below. ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css hidden .flip { display: inline-flex; padding: 1rem; position: relative; border-radius: 0.5rem; overflow: hidden; } .flip::before { content: ''; position: absolute; top: 0; left: 0; height: 50%; width: 100%; background: linear-gradient(to right bottom, rgb(71 85 105), rgb(15 23 42)); } .flip::after { content: ''; position: absolute; bottom: 0; left: 0; height: 50%; width: 100%; background: linear-gradient(to right bottom, rgb(100 116 139), rgb(15 23 42)); } .flip__number { color: #fff; font-size: 4rem; font-weight: 600; z-index: 1; } ``` ```html index.html hidden
42
```
## Adding a divider To enhance the layout's visual appeal, we can insert a thin divider between the top and bottom halves. We can achieve this by adding a border at the bottom of the first half. ```css .flip::before { border-bottom: 1px solid rgb(148 163 184); } ``` As the border will occupy space, we need to slightly push up the first half to ensure both halves have the same height. We can use a negative value with the `translateY()` function to accomplish this. ```css .flip::before { transform: translateY(-1px); } ``` It's important to note that the value passed must match the border's thickness. Therefore, it's better to use a CSS variable to represent the number. This way, the code will still work even if you increase the border's thickness. Plus, it'll be easier for other engineers on your team to understand, making the code easier to maintain. ```css :root { --divider-height: 1px; } .flip::before { border-bottom: var(--divider-height) solid rgb(148 163 184); transform: translateY(calc(-1 * var(--divider-height))); } ``` Let's take a look at the final result we've achieved so far. ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css :root { --divider-height: 1px; } .flip { display: inline-flex; padding: 1rem; position: relative; border-radius: 0.5rem; overflow: hidden; } .flip::before { content: ''; position: absolute; top: 0; left: 0; height: 50%; width: 100%; background: linear-gradient(to right bottom, rgb(71 85 105), rgb(15 23 42)); border-bottom: var(--divider-height) solid rgb(148 163 184); transform: translateY(calc(-1 * var(--divider-height))); } .flip::after { content: ''; position: absolute; bottom: 0; left: 0; height: 50%; width: 100%; background: linear-gradient(to right bottom, rgb(100 116 139), rgb(15 23 42)); } .flip__number { color: #fff; font-size: 4rem; font-weight: 600; z-index: 1; } ``` ```html index.html
42
```
================================================ FILE: contents/floating-label.mdx ================================================ --- category: Input created: '2019-11-28' description: Create a floating label with CSS keywords: css floating label, placeholder shown thumbnail: /assets/css-layout/thumbnails/floating-label.png title: Floating label --- ## HTML ```html index.html
``` ## CSS ```css styles.css .floating-label { border: 1px solid #d1d5db; border-radius: 0.25rem; position: relative; } .floating-label__input { border: none; padding: 0.5rem; height: 100%; } /* Show the label at desired position when the placeholder of input isn't shown */ .floating-label__input:not(:placeholder-shown) + .floating-label__label { background: #fff; transform: translate(0, -200%); opacity: 1; } .floating-label__label { /* Position the label */ left: 1rem; position: absolute; top: 100%; /* Hide it by default */ opacity: 0; transition: all 200ms; padding: 0 0.5rem; } ``` Type something in the input to see how the label is shown up. ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .floating-label { border: 1px solid #d1d5db; border-radius: 0.25rem; position: relative; /* Demo */ padding: 0px 1px; height: 2.5rem; } .floating-label__input { border: none; padding: 0.5rem; height: 100%; } /* Show the label at desired position when the placeholder of input isn't shown */ .floating-label__input:not(:placeholder-shown) + .floating-label__label { background: #fff; transform: translate(0, -200%); opacity: 1; } .floating-label__label { /* Position the label */ left: 1rem; position: absolute; top: 100%; /* Hide it by default */ opacity: 0; transition: all 200ms; padding: 0 0.5rem; } ``` ```html index.html hidden
```
## See also - Explore some ways to [animate a floating label](https://phuoc.ng/collection/css-animation/floating-label/). ================================================ FILE: contents/folded-corner.mdx ================================================ --- category: Display created: '2023-09-06' description: Create a folded corner in CSS keywords: css folded corner openGraphCover: /og/css-layout/folded-corner.png thumbnail: /assets/css-layout/thumbnails/folded-corner.png title: Folded corner --- The folded corner layout is a popular design element in web design that adds creativity and uniqueness to a website. It creates the illusion of a folded corner on a webpage, giving it a tangible feel. Using this technique can help highlight important information or sections on a page, making it easier for users to navigate a content-heavy website. It can also be used simply for aesthetic purposes, adding an interesting visual element to the page. In this post, we will explore various ways to create a folded corner effect. So, get ready to learn some cool techniques! ## Markup To begin, let's create the markup for our layout. It's as simple as adding an HTML element. ```html
``` ## Using multiple backgrounds Let's take a moment to imagine an element with a folded corner. This element is made up of two layers: a rectangle with a curved corner and a triangle placed on top of it. To create the first layer, we can use the `linear-gradient` function to define the background of the element. ```css background: linear-gradient(-135deg, transparent 1.7677rem, rgb(226 232 240) 0) ``` If you're not familiar with the `linear-gradient` function or the number `1.7677rem` in the sample code, don't worry. Here's what's going on: - The `linear-gradient` function creates a gradient background for an element. The `-135deg` specifies the direction of the gradient, which in this case is from the top-right corner to the bottom-left corner. - The first color stop in the gradient is `transparent`, which means there's no color at that point. The second color stop is `rgb(226 232 240)`, which is an RGB color value for that point in the gradient. - The `1.7677rem` and `0` values determine where these colors are positioned within the gradient. `transparent` will be visible for the first `1.7677rem` of the gradient, followed by `rgb(226 232 240)` for the rest. Wondering how we calculated the `1.7677rem` value? It's actually pretty simple. Just imagine that the folded corner is a square with sides of 2.5rem. But because we rotate the first stop by 135 degrees, the side of the square becomes the diagonal. Now, a square whose diagonal is 2.5rem has a size of `2.5rem / Math.sqrt(2)`, which is `1.7677rem`. Easy, right? Let's take a look at how it creates a curved corner: ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css .box { height: 12rem; width: 16rem; background: linear-gradient(-135deg, transparent 1.7677rem, rgb(226 232 240) 0); } ``` ```html index.html
```
### Creating the triangle There are several ways to create a triangle, such as using different border colors. However, in this section, we will stick to using the `linear-gradient` function. ```css .triangle { background: linear-gradient(to left bottom, transparent 50%, rgb(100 116 139) 0); } ``` In this example, we use the `to left bottom` value to specify the direction of the gradient. It starts from the top-right corner and goes to the bottom-left corner. The first color stop is `transparent`, which means that there is no color at that point. The second color stop is `rgb(100 116 139)`, which specifies an RGB color value for that point in the gradient. To create a diagonal line across the box from the top-right to the bottom-left corner, we start with transparency at 50% of this line and then transition into our dark color for the remaining area. Let's take a look at how it generates a triangle shape: ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css .triangle { height: 2.5rem; width: 2.5rem; background: linear-gradient(to left bottom, transparent 50%, rgb(100 116 139) 0); } ``` ```html index.html
```
Next, let's move the triangle to the top-right corner of the box element. To do this, we can simply adjust the position of the background. ```css .box { background: linear-gradient(...) no-repeat 100% 0 / 2.5rem 2.5rem; } ``` Let's break down the declaration into its individual parts: - `no-repeat` is a keyword that tells the background image not to repeat. - `100% 0` sets the position of the background image to the top-right corner of the element. - `/ 2.5rem 2.5rem` specifies the size of the background image. The first value represents the width, and the second value represents the height. In this case, both values are set to `2.5rem`, which matches the size of our folded corner square. Check out the box element with a triangle attached to the top-right corner. I added a simple dashed border so you can see the bounding of the box. ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css .box { height: 12rem; width: 16rem; border: 2px dashed rgb(226 232 240); background: linear-gradient(to left bottom, transparent 50%, rgb(100 116 139) 0) no-repeat 100% 0 / 2.5rem 2.5rem; } ``` ```html index.html
```
### Combining backgrounds Now that you know how to use the linear gradient to create both layers, it's time to merge them and generate the folded corner. CSS allows us to use multiple declarations for the `background` properties by separating them with commas. Keep in mind that the order of these declarations is important and can affect the final result. ```css .box { background: linear-gradient(to left bottom, transparent 50%, rgb(100 116 139) 0) no-repeat 100% 0 / 2.5rem 2.5rem, linear-gradient(-135deg, transparent 1.7677rem, rgb(226 232 240) 0); } ``` Without further ado, let's take a look at the final result of the steps we've taken so far: ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css .box { height: 12rem; width: 16rem; background: linear-gradient(to left bottom, transparent 50%, rgb(100 116 139) 0) no-repeat 100% 0 / 2.5rem 2.5rem, linear-gradient(-135deg, transparent 1.7677rem, rgb(226 232 240) 0); } ``` ```html index.html
```
## Using a pseudo-element In the previous section, we used a cool approach to generate a folded corner using multiple backgrounds in a single `div` element. However, this approach has some downsides. For example, it's not easy to add more styles to the triangle, like a shadow. To add more customization to the triangle, we can use the `:after` pseudo-element to represent it. Here are some basic styles to position the triangle: ```css .box { position: relative; } .box::after { content: ''; position: absolute; top: 0; right: 0; width: 2.5rem; height: 2.5rem; } ``` The `position` property values of `absolute` and `relative` are applied to the box and the triangle, respectively. This ensures that the triangle is positioned absolutely within the box. Although the triangle doesn't contain any information, we still need to set the content property to an empty `''` for it to appear. The `top` and `right` properties position the triangle in the top-right corner, while the `width` and `height` properties determine its size. We're using a separate element to represent the triangle. This makes it easy to style it however you want. Want to add a box shadow? No problem! ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css .box { height: 12rem; width: 16rem; background: linear-gradient(-135deg, transparent 1.7677rem, rgb(226 232 240) 0); position: relative; } .box::after { content: ''; position: absolute; top: 0; right: 0; width: 2.5rem; height: 2.5rem; background: linear-gradient(to left bottom, transparent 50%, rgb(100 116 139) 0) no-repeat 100% 0; box-shadow: -0.4rem 0.4rem 0.4rem -0.2rem rgba(0 0 0 / 50); } ``` ```html index.html
```
================================================ FILE: contents/folder-structure.mdx ================================================ --- category: Display created: '2021-04-03' description: Create a folder structure with CSS keywords: css folder structure, css folder tree thumbnail: /assets/css-layout/thumbnails/folder-structure.png title: Folder structure --- ## HTML ```html index.html
``` ## CSS ```css styles.css :root { --folder-structure-item-height: 0.5rem; --folder-structure-item-margin-left: 2.25rem; --folder-structure-item-padding-top: 0.5rem; } .folder-structure ul { /* Reset */ list-style-type: none; margin: 0; } .folder-structure li { padding: var(--folder-structure-item-padding-top) 0rem 0rem 0rem; position: relative; } .folder-structure li::before { border-left: 1px solid #d1d5db; content: ''; /* Position */ left: 0; position: absolute; top: 0; transform: translate(calc(-1 * var(--folder-structure-item-margin-left)), 0); /* Size */ height: 100%; } .folder-structure li::after { border-bottom: 1px solid #d1d5db; content: ''; /* Position */ left: 0; position: absolute; top: calc(var(--folder-structure-item-padding-top) + var(--folder-structure-item-height) / 2); transform: translate(-100%, 0); /* Size */ width: var(--folder-structure-item-margin-left); } /* Remove the border from the last item */ .folder-structure li:last-child::before { height: calc(var(--folder-structure-item-padding-top) + var(--folder-structure-item-height) / 2); } ``` ```css placeholders.css hidden .square { background: #d1d5db; height: var(--square-size); width: var(--square-size); } .square--sm { --square-size: 0.5rem; } .square--md { --square-size: 2rem; } .square--lg { --square-size: 4rem; } ``` ```css styles.css hidden :root { --folder-structure-item-height: 0.5rem; --folder-structure-item-margin-left: 2.25rem; --folder-structure-item-padding-top: 0.5rem; } body { align-items: center; display: flex; justify-content: center; } .folder-structure ul { /* Reset */ list-style-type: none; margin: 0; } .folder-structure li { padding: var(--folder-structure-item-padding-top) 0rem 0rem 0rem; position: relative; } .folder-structure li::before { border-left: 1px solid #d1d5db; content: ''; /* Position */ left: 0; position: absolute; top: 0; transform: translate(calc(-1 * var(--folder-structure-item-margin-left)), 0); /* Size */ height: 100%; } .folder-structure li::after { border-bottom: 1px solid #d1d5db; content: ''; /* Position */ left: 0; position: absolute; top: calc(var(--folder-structure-item-padding-top) + var(--folder-structure-item-height) / 2); transform: translate(-100%, 0); /* Size */ width: var(--folder-structure-item-margin-left); } /* Remove the border from the last item */ .folder-structure li:last-child::before { height: calc(var(--folder-structure-item-padding-top) + var(--folder-structure-item-height) / 2); } ``` ```html index.html hidden
```
================================================ FILE: contents/frame-corners.mdx ================================================ --- category: Display created: '2023-09-06' description: Create frame corners in CSS keywords: css folded corner openGraphCover: /og/css-layout/frame-corners.png thumbnail: /assets/css-layout/thumbnails/frame-corners.png title: Frame corners --- The frame corner layout pattern is a popular and effective technique in web design. It uses corner elements to frame content on a web page, adding depth and structure. This technique is often used with images and shapes. In this post, we'll teach you how to create frame corners with CSS. Are you ready to dive in and learn? ## Markup The first step in preparing the layout is to structure it properly. This usually involves two elements: an inner element for displaying the content and an outer element that will display four frames at its corners. Here's an example of what the layout could look like: ```html
``` ## Adding overlays Creating a frame at the corners is a simple idea. We can use CSS to add overlay elements around the content area and position them using absolute positioning. Here's how to get started: define some CSS variables that can be reused later. ```css :root { --frame-border-size: 0.25rem; --frame-height: 1rem; --frame-width: 1rem; } ``` The `--frame-border-size` variable controls the thickness of the frame, while `--frame-height` and `--frame-width` determine its dimensions. To create a single frame for the outer element, we can use a solid border and adjust the `padding` property to set the space between the border and the box content. ```css .box { border: var(--frame-border-size) solid rgb(30 41 59); padding: var(--frame-height) var(--frame-width); } ``` ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css hidden :root { --frame-border-size: 0.25rem; --frame-height: 1rem; --frame-width: 1rem; } .box { border: var(--frame-border-size) solid rgb(30 41 59); padding: var(--frame-height) var(--frame-width); height: 12rem; width: 16rem; } .box__inner { width: 100%; height: 100%; background: rgb(226 232 240); } ``` ```html index.html hidden
```
In order to hide the top and bottom borders of the box, there's a nifty trick we can use called the pseudo-element. Here's how it works: We'll use the `::before` pseudo-element to create a vertical overlay that sits outside the box. To achieve this, we position the element absolutely within the box. We set the `position` property to both elements to make sure it stays in place. ```css .box { position: relative; } .box::before { content: ''; position: absolute; } ``` To create the overlay effect, we need to set the `left` and `right` properties to be the same as the frame's width, and the `top` and `bottom` properties to be the same the thickness of the frame border. By using negative numbers for these properties, we push the overlay to the outside of the box, causing the top and bottom borders to overlap. ```css .box::before { left: var(--frame-width); right: var(--frame-width); top: calc(-1 * var(--frame-border-size)); bottom: calc(-1 * var(--frame-border-size)); } ``` ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css hidden :root { --frame-border-size: 0.25rem; --frame-height: 1rem; --frame-width: 1rem; } .box { border: var(--frame-border-size) solid rgb(30 41 59); padding: var(--frame-height) var(--frame-width); height: 12rem; width: 16rem; position: relative; } .box::before { content: ''; position: absolute; left: var(--frame-width); right: var(--frame-width); top: calc(-1 * var(--frame-border-size)); bottom: calc(-1 * var(--frame-border-size)); background: rgb(226 232 240); } ``` ```html index.html hidden
```
Finally, to create the blank areas at the top and bottom, we make the top and bottom borders the same height as the frame. And voila! The top and bottom borders are hidden, and our box looks sleek and polished. ```css .box::before { border-top: var(--frame-height) solid #fff; border-bottom: var(--frame-height) solid #fff; } ``` ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css hidden :root { --frame-border-size: 0.25rem; --frame-height: 1rem; --frame-width: 1rem; } .box { border: var(--frame-border-size) solid rgb(30 41 59); padding: var(--frame-height) var(--frame-width); height: 12rem; width: 16rem; position: relative; } .box::before { content: ''; position: absolute; left: var(--frame-width); right: var(--frame-width); top: calc(-1 * var(--frame-border-size)); bottom: calc(-1 * var(--frame-border-size)); background: rgb(226 232 240); border-top: var(--frame-height) solid #fff; border-bottom: var(--frame-height) solid #fff; } ``` ```html index.html hidden
```
We can use the same approach and create the horizontal overlay element with the `::after` pesudo-element. Now, let's check out the final result of the steps we've followed together so far. ```css demo.css hidden body { display: flex; align-items: center; justify-content: center; } ``` ```css styles.css :root { --frame-border-size: 0.25rem; --frame-height: 1rem; --frame-width: 1rem; } .box { border: var(--frame-border-size) solid rgb(30 41 59); padding: var(--frame-height) var(--frame-width); height: 12rem; width: 16rem; position: relative; } .box__inner { height: 100%; width: 100%; background: rgb(226 232 240); } .box::before { content: ''; position: absolute; left: var(--frame-width); right: var(--frame-width); top: calc(-1 * var(--frame-border-size)); bottom: calc(-1 * var(--frame-border-size)); border-top: var(--frame-height) solid #fff; border-bottom: var(--frame-height) solid #fff; } .box::after { content: ''; position: absolute; top: var(--frame-height); bottom: var(--frame-height); left: calc(-1 * var(--frame-border-size)); right: calc(-1 * var(--frame-border-size)); border-left: var(--frame-width) solid #fff; border-right: var(--frame-width) solid #fff; } ``` ```html index.html
```
================================================ FILE: contents/full-background.mdx ================================================ --- category: Display created: '2020-01-18' description: Create a full background element with CSS keywords: css background size cover, css full background thumbnail: /assets/css-layout/thumbnails/full-background.png title: Full background --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .full-background { /* Center the content */ align-items: center; display: flex; flex-direction: column; justify-content: center; /* Take full size */ height: 100vh; width: 100%; /* Background */ background: url('/path/to/background.jpeg') center center / cover no-repeat; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .full-background { /* Center the content */ align-items: center; display: flex; flex-direction: column; justify-content: center; /* Take full size */ height: 100%; width: 100%; background: url('/assets/css-layout/full-background.jpeg') center center / cover no-repeat; } ``` ```html index.html hidden
```
================================================ FILE: contents/full-screen-menu.mdx ================================================ --- category: Navigation created: '2019-11-30' description: Create a full screen menu with CSS flexbox keywords: css fixed, css flexbox, css menu thumbnail: /assets/css-layout/thumbnails/full-screen-menu.png title: Full screen menu --- ## HTML ```html index.html
``` ## CSS ```css styles.css .full-screen-menu { /* Full screen overlay */ height: 100%; left: 0; position: fixed; top: 0; width: 100%; /* Center the content */ align-items: center; display: flex; justify-content: center; } .full-screen-menu__close { /* Shown at top left corner */ left: 1rem; position: absolute; top: 1rem; } ``` You can use the [close button](https://phuoc.ng/collection/css-layout/close-button/) to create a button for closing the menu. ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .full-screen-menu { /* Take full size */ height: 100%; width: 100%; /* Center the content */ align-items: center; display: flex; justify-content: center; position: relative; background: #374151; } .full-screen-menu__close { left: 0.5rem; position: absolute; top: 0.5rem; /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 1rem; width: 1rem; } .full-screen-menu__close::before, .full-screen-menu__close::after { content: ''; /* Background color */ background-color: #d1d5db; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .full-screen-menu__close::before { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .full-screen-menu__close::after { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```html index.html hidden
```
================================================ FILE: contents/grid-lines-background.mdx ================================================ --- category: Display created: '2023-08-30' description: Create a grid lines background in CSS keywords: grid lines background, linear gradient, radial gradient openGraphCover: /og/css-layout/grid-lines-background.png thumbnail: /assets/css-layout/thumbnails/grid-lines-background.png title: Grid lines background updated: '2023-11-22' --- Adding a grid lines background in CSS is an awesome way to give your website some visual interest and structure. This post will show you two simple ways to achieve this. ## Using background image To create a grid pattern using CSS, you can use the `background-image` property. Start by creating a square image with two lines – one horizontal and one vertical – that intersect at the center of the square. The image can be in either SVG or PNG format. Here's an example of a square image in SVG format: ```html index.html ``` The SVG consists of three rectangles. The first rectangle forms a white square with a size of 40 pixels. The second rectangle is 1 pixel wide and spans the full height to create a vertical line. The `x='50%'` attribute centers the line vertically. Likewise, the last rectangle is 1 pixel high and spans the full width to create a horizontal line. It's worth noting that the last two rectangles are filled with identical colors. Next, let's specify the `background-image` property for the element where you want the grid to show up. Simply use the `url()` function to link to your grid image file. ```css .grid { background-image: url('/path/to/grid.svg'); } ``` If you want the browser to avoid sending additional request to load the background image, then you can embed it like this: ```css .grid { background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Crect width='40' height='40' fill='%23fff' /%3E%3Crect x='50%' width='1' height='100%' fill='rgb(203 213 225)' /%3E%3Crect y='50%' width='100%' height='1' fill='rgb(203 213 225)' /%3E%3C/svg%3E%0A"); } ``` Voila! You now have a grid made up of horizontal and vertical lines that repeat seamlessly. ```css styles.css .grid { height: 16rem; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40'%3E%3Crect width='40' height='40' fill='%23fff' /%3E%3Crect x='50%' width='1' height='100%' fill='rgb(203 213 225)' /%3E%3Crect y='50%' width='100%' height='1' fill='rgb(203 213 225)' /%3E%3C/svg%3E%0A"); } ``` ```html index.html
```
By default, an image will repeat both vertically and horizontally, with each repetition being the same size as the background, which is 40 pixels in this case. But what if you want to change the size of the repeated image? No problem! You can use the `background-size` property to customize the dimensions. For example, if you set it to 20 pixels, you'll create smaller squares instead. Here's the code you need to make it happen. ```css .grid { background-size: 20px; } ``` ## Using linear gradients Another way to create grid lines in CSS is with the `linear-gradient()` function. To make a grid, first, select the element(s) you want to add a grid background to and set the `background-image` property. Then, use the `linear-gradient()` function to specify two colors that are similar or identical, separated by a transparent section of the same width as your desired line thickness. ```css .grid { background-image: linear-gradient(to right, gray 1px, transparent 1px); } ``` The code above creates gray vertical lines that are one pixel thick. You can adjust the line thickness by changing the value of `1px` in both parts of the gradient (i.e., `gray 2px`, `transparent 2px`, for two-pixel-thick lines). To make horizontal lines, change `to right` to `to bottom`. If you want both horizontal and vertical lines, simply combine both gradients. ```css .grid { background-image: linear-gradient(to right, gray 1px, transparent 1px), linear-gradient(to bottom, gray 1px, transparent 1px); } ``` Finally, don't forget to set the size of the squares using the `background-size` property. To adjust the color and spacing of lines, simply change the value of `gray` to any other valid CSS color value, as shown in the example below. ```css styles.css .grid { height: 16rem; background-image: linear-gradient(to right, rgb(203 213 225) 1px, transparent 1px), linear-gradient(to bottom, rgb(203 213 225) 1px, transparent 1px); background-size: 2.5rem 2.5rem; background-position: center center; } ``` ```html index.html
```
## Grid dot background We can use a similar approach to create a grid with a dot background, but this time we'll use the `radial-gradient` function to make circles with a radius of 2 pixels. Don't hesitate to adjust the background color and radius to suit your needs. ```css styles.css .grid { height: 16rem; background-image: radial-gradient(circle, rgb(203 213 225) 2px, #fff 2px); background-size: 2.5rem 2.5rem; background-position: center center; } ``` ```html index.html
```
## See also - [Snap a draggable element to a grid](https://phuoc.ng/collection/react-drag-drop/snap-a-draggable-element-to-a-grid/) ================================================ FILE: contents/grid-without-double-borders.mdx ================================================ --- category: Layout created: '2023-08-27' description: How to create a CSS grid without double borders keywords: css grid openGraphCover: /og/css-layout/grid-without-double-borders.png thumbnail: /assets/css-layout/thumbnails/grid-without-double-borders.png title: Grid without double borders --- CSS grids are an amazing tool for creating complex web page layouts. However, working with default styling can be a bit tricky, especially when it comes to borders. In this post, we'll show you how to create a CSS grid without double borders. First, let's create the grid itself. To do this, we'll use the `display: grid` property. ```css .grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 4rem); } ``` In this example, we've made a 3x3 grid with three columns and three rows. Each row is 4rem tall, and each column takes up an equal fraction of the available space. This means that no matter what size screen you're using, the columns will be evenly spaced. Now that we've got the grid set up, we want to add borders to each cell. But here's the thing: CSS grids will automatically add double borders to adjacent cells. We'll be exploring some solutions to this issue in the next sections. ## Collapsing the borders The grid looks a lot like a table, and as with tables, we face the same issue. But don't worry, there's a solution we can use: the `border-collapse` property. Let me show you an example. ```css .grid { border-collapse: collapse; } .grid__item { border: 1px solid rgb(203 213 225); } ``` In this example, we've set the `border-collapse` property to `collapse`. This should collapse adjacent borders into a single border, and we've also added a 1 pixel border to each cell using the `.grid__item` class. However, the approach doesn't work as expected. Unfortunately, the borders are still duplicated visually, as you can see below. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; height: 16rem; } ``` ```css styles.css .grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 4rem); border-collapse: collapse; width: 12rem; } .grid__item { border: 1px solid rgb(203 213 225); } ``` ```html index.html
```
## Pairing the borders There's an easier way to apply borders to your cells. Instead of setting the border for all four sides, we can apply it to just two. This approach is more natural and straightforward. ```css :root { --grid-border: 1px solid rgb(203 213 225); } .grid__item { border-right: var(--grid-border); border-bottom: var(--grid-border); } ``` The grid will fill in the missing borders at the top and left sides. ```css .grid { border-top: var(--grid-border); border-left: var(--grid-border); } ``` And there you have it! Check it out, it works just as we expected! > Did you notice in the sample code above, how I created a CSS variable to define the border? By using the variable in different places, we can avoid duplicating code everywhere. This is what we call **Don't Repeat Yourself** or **DRY**, and it's always a great practice to follow. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; height: 16rem; } ``` ```css styles.css :root { --grid-border: 1px solid rgb(203 213 225); } .grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 4rem); border-top: var(--grid-border); border-left: var(--grid-border); width: 12rem; } .grid__item { border-right: var(--grid-border); border-bottom: var(--grid-border); } ``` ```html index.html
```
## Using the outline property Another solution for styling elements is to use the CSS `outline` property. The outline creates a visual effect similar to a border, but it doesn't take up space on the target element. ```css .grid__item { outline: 1px solid rgb(203 213 225); } ``` Although it's a step in the right direction, using the `outline` property alone doesn't completely solve the issue of double borders. We're still missing a small piece of the puzzle. But don't worry, because CSS grid has a trick up its sleeve. The `grid-gap` property is here to save the day! This handy property creates space between rows and columns in a CSS grid layout. By specifying the size of the gap between each row and column, we gain more control over the spacing of elements within the grid. ```css .grid { grid-gap: 1px; } ``` We can solve the issue by creating a grid with a 1px gap between each row and column, just like the outline. Here's a visual representation of how it works. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; height: 16rem; } ``` ```css styles.css .grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 4rem); grid-gap: 1px; width: 12rem; } .grid__item { outline: 1px solid rgb(203 213 225); } ``` ```html index.html
```
================================================ FILE: contents/holy-grail.mdx ================================================ --- category: Layout created: '2019-11-16' description: Create a holy grail layout with CSS flexbox keywords: css flexbox, css holy grail layout, css layout thumbnail: /assets/css-layout/thumbnails/holy-grail.png title: Holy grail --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .holy-grail { display: flex; flex-direction: column; } .holy-grail__main { /* Take the remaining height */ flex-grow: 1; /* Layout the left sidebar, main content and right sidebar */ display: flex; flex-direction: row; } .holy-grail__left { width: 25%; } .holy-grail__middle { /* Take the remaining width */ flex-grow: 1; } .holy-grail__right { width: 20%; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .holy-grail { display: flex; flex-direction: column; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; } .holy-grail__header, .holy-grail__footer { padding: 0.25rem; } .holy-grail__main { border-top: 1px solid #d1d5db; border-bottom: 1px solid #d1d5db; /* Take the remaining height */ flex-grow: 1; /* Layout the left sidebar, main content and right sidebar */ display: flex; flex-direction: row; } .holy-grail__left { width: 25%; } .holy-grail__middle { border-left: 1px solid #d1d5db; border-right: 1px solid #d1d5db; /* Take the remaining width */ flex-grow: 1; } .holy-grail__right { width: 20%; } ``` ```html index.html hidden
```
================================================ FILE: contents/indeterminate-progress-bar.mdx ================================================ --- category: Feedback created: '2022-10-02' description: Create an indeterminate progress bar with CSS keywords: css indeterminate progress bar, css progress bar thumbnail: /assets/css-layout/thumbnails/indeterminate-progress-bar.png title: Indeterminate progress bar --- ## HTML ```html index.html
``` ## CSS ```css styles.css .indeterminate-progress-bar { /* Color */ background-color: #d1d5db; /* Rounded border */ border-radius: 9999px; /* Size */ height: 0.5rem; position: relative; overflow: hidden; } .indeterminate-progress-bar__progress { /* Color */ background-color: #3b82f6; /* Rounded border */ border-radius: 9999px; /* Absolute position */ position: absolute; bottom: 0; top: 0; width: 50%; /* Move the bar infinitely */ animation-duration: 2s; animation-iteration-count: infinite; animation-name: indeterminate-progress-bar; } @keyframes indeterminate-progress-bar { from { left: -50%; } to { left: 100%; } } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .indeterminate-progress-bar { /* Color */ background-color: #d1d5db; /* Rounded border */ border-radius: 9999px; width: 16rem; height: 0.5rem; position: relative; overflow: hidden; } .indeterminate-progress-bar__progress { /* Color */ background-color: #3b82f6; /* Rounded border */ border-radius: 9999px; position: absolute; bottom: 0; top: 0; width: 50%; animation-duration: 2s; animation-iteration-count: infinite; animation-name: indeterminate-progress-bar; } @keyframes indeterminate-progress-bar { from { left: -50%; } to { left: 100%; } } ``` ```html index.html hidden
```
## See also - [Progress bar](https://phuoc.ng/collection/css-layout/progress-bar/) - [Spinner](https://phuoc.ng/collection/css-layout/spinner/) ================================================ FILE: contents/initial-avatar.mdx ================================================ --- category: Display created: '2019-12-04' description: Create an initial avatar with CSS keywords: css avatar thumbnail: /assets/css-layout/thumbnails/initial-avatar.png title: Initial avatar --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .initial-avatar { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Colors */ background-color: #d1d5db; color: #fff; /* Rounded border */ border-radius: 50%; height: 3rem; width: 3rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .initial-avatar { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Colors */ background-color: #d1d5db; color: #fff; /* Rounded border */ border-radius: 50%; height: 3rem; width: 3rem; } ``` ```html index.html hidden
PN
```
================================================ FILE: contents/input-addon.mdx ================================================ --- category: Input created: '2019-11-16' description: Create an input add-on with CSS flexbox keywords: css flexbox, css input add-on thumbnail: /assets/css-layout/thumbnails/input-addon.png title: Input addon --- ## HTML ```html index.html
...
...
...
...
``` ## CSS ```css styles.css .input-addon { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; } .input-addon__input { border: none; /* Take the remaining width */ flex: 1; } .input-addon__addon { /* Center the content */ align-items: center; display: flex; justify-content: center; } .input-addon__addon--prepended { border-right: 1px solid #d1d5db; } .input-addon__addon--appended { border-left: 1px solid #d1d5db; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .input-addon { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; /* Demo */ margin-bottom: 0.5rem; width: 16rem; } .input-addon__input { border: none; /* Take the remaining width */ flex: 1; /* Demo */ padding: 0.25rem; margin: 0 0.25rem; width: 5rem; } .input-addon__addon { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Demo */ padding: 0.25rem; } .input-addon__addon--prepended { border-right: 1px solid #d1d5db; } .input-addon__addon--appended { border-left: 1px solid #d1d5db; } ``` ```html index.html hidden
```
================================================ FILE: contents/inverted-corners.mdx ================================================ --- category: Display created: '2021-05-09' description: Create inverted corners with CSS keywords: css border radius, css inverted border radius, css inverted corners thumbnail: /assets/css-layout/thumbnails/inverted-corners.png title: Inverted corners --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css :root { --inverted-corners-background: #d1d5db; --inverted-corners-size: 2rem; } .inverted-corners { background-color: var(--inverted-corners-background); /* Used to position the corner */ position: relative; } .inverted-corners::before { content: ''; /* Absolute position */ bottom: calc(-2 * var(--inverted-corners-size)); left: 0; position: absolute; /* Size */ height: calc(2 * var(--inverted-corners-size)); width: var(--inverted-corners-size); /* Border */ background-color: transparent; border-top-left-radius: var(--inverted-corners-size); box-shadow: var(--inverted-corners-background) 0px calc(-1 * var(--inverted-corners-size)) 0px 0px; } ``` ```css styles.css hidden :root { --inverted-corners-background: #d1d5db; --inverted-corners-size: 2rem; } body { height: 24rem; } .inverted-corners { background-color: var(--inverted-corners-background); /* Used to position the corner */ position: relative; /* Demo */ height: 2rem; width: 100%; } .inverted-corners::before { content: ''; /* Absolute position */ bottom: calc(-2 * var(--inverted-corners-size)); left: 0; position: absolute; /* Size */ height: calc(2 * var(--inverted-corners-size)); width: var(--inverted-corners-size); /* Border */ background-color: transparent; border-top-left-radius: var(--inverted-corners-size); box-shadow: var(--inverted-corners-background) 0px calc(-1 * var(--inverted-corners-size)) 0px 0px; } ``` ```html index.html hidden
```
================================================ FILE: contents/keyboard-shortcut.mdx ================================================ --- category: Display created: '2019-12-16' description: Create a keyboard shortcut with CSS keywords: kbd tag, keyboard shortcut thumbnail: /assets/css-layout/thumbnails/keyboard-shortcut.png title: Keyboard shortcut --- We use the native `kbd` tag to display the keyboard shortcut. ## HTML ```html index.html ... ``` ## CSS ```css styles.css .keyboard-shortcut { /* Background and color */ background-color: rgba(0, 0, 0, 0.1); border-radius: 0.25rem; color: rgba(0, 0, 0, 0.7); /* Bottom shadow */ box-shadow: #d1d5db 0px -4px 0px inset, rgba(0, 0, 0, 0.4) 0px 1px 1px; /* Spacing */ padding: 0.25rem 0.5rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .keyboard-shortcut { /* Background and color */ background-color: rgba(0, 0, 0, 0.1); border-radius: 0.25rem; color: rgba(0, 0, 0, 0.7); /* Bottom shadow */ box-shadow: #d1d5db 0px -4px 0px inset, rgba(0, 0, 0, 0.4) 0px 1px 1px; /* Spacing */ padding: 0.25rem 0.5rem; } ``` ```html index.html hidden ⌘ + C ``` ================================================ FILE: contents/layered-card.mdx ================================================ --- category: Display created: '2021-04-04' description: Create a layered card with CSS keywords: css layered card thumbnail: /assets/css-layout/thumbnails/layered-card.png title: Layered card --- ## HTML ```html index.html
``` ## CSS ```css styles.css .layered-card { position: relative; /* Demo */ height: 6rem; width: 6rem; } .layered-card::before { background: #d1d5db; content: ''; /* Position */ top: 0; left: 0; position: absolute; transform: translate(1rem, 1rem); /* Size */ height: 100%; width: 100%; /* Display under the main content */ z-index: 0; } .layered-card__content { /* Position */ left: 0; position: absolute; top: 0; /* Size */ height: 100%; width: 100%; z-index: 1; background: #fff; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .layered-card { position: relative; /* Demo */ height: 6rem; width: 6rem; } .layered-card::before { background: #d1d5db; content: ''; /* Position */ top: 0; left: 0; position: absolute; transform: translate(1rem, 1rem); /* Size */ height: 100%; width: 100%; /* Display under the main content */ z-index: 0; } .layered-card__content { left: 0; position: absolute; top: 0; /* Size */ height: 100%; width: 100%; z-index: 1; border: 1px solid #d1d5db; background: #fff; } ``` ```html index.html hidden
```
================================================ FILE: contents/linear-gauge.mdx ================================================ --- category: Feedback created: '2023-11-20' description: Create a linear gauge openGraphCover: /og/css-layout/linear-gauge.png thumbnail: /assets/css-layout/thumbnails/linear-gauge.png title: Linear gauge --- A **linear gauge** is a handy tool for displaying numerical values within a specific range. It's like a bar with markings that represent the range of values and an indicator that points to the current value. Linear gauges are great for showing progress, performance, or other quantitative metrics quickly and easily. You can use them in dashboards, reports, or presentations to help people understand complex data at a glance. They're simple and intuitive, making them an effective way to communicate important information in a clear and concise manner. For instance, think of a fitness app that tracks your daily step count. The app could display a linear gauge that shows your progress towards your daily goal, with markings indicating the range of steps from 0 to the goal amount. As you walk throughout the day, the indicator on the gauge would move in real-time to show how many steps you've taken so far. This visualization can motivate users to reach their step goal and monitor their progress over time. Linear gauges can also be used in other contexts, such as fundraising campaigns or sales targets, to track progress towards specific goals and keep stakeholders informed. Linear gauges are also used in real-life situations, like in modern cars with fuel economy gauges. These gauges display how efficiently the vehicle is using fuel, with markings indicating different levels of fuel efficiency. The indicator moves up or down based on how efficiently the car is being driven at any given moment, providing drivers with real-time feedback on their driving habits. These are just a few examples of how linear gauges can be used to communicate important information quickly and effectively. In this post, we'll learn how to create a linear gauge. ## Setting up the layout Setting up a layout for a simple linear gauge can be done with just one element that represents the progress. ```html
``` In order to position the progress indicator inside the gauge, we need to use absolute positioning. First, we set the `position` property of the gauge container to `relative`, so that any child elements with absolute positioning are positioned relative to it. Next, we set the position property of the progress indicator to `absolute`, and give it a `top` and `left` value of 0. This will position it at the top left corner of the gauge container. Finally, we set the `width` of the progress indicator to a percentage value based on the current value being displayed. This will cause it to stretch or shrink horizontally as needed. ```css .gauge { position: relative; } .gauge__progress { position: absolute; top: 0; left: 0; width: 60%; height: 100%; } ``` Setting different background colors for the gauge and progress indicator can make it easier to distinguish between the two elements, improving the gauge's readability. By using contrasting colors, we can highlight the progress indicator and make it stand out against the gauge's background. This is especially helpful when displaying data with a wide range of values or when there are multiple gauges on a single page. Moreover, choosing visually appealing colors can enhance the gauge's overall look and feel, making it more engaging for viewers to interact with. ```css .gauge { background: rgb(203 213 225); } .gauge__progress { background: rgb(99 102 241); } ``` Here's what the gauge looks like: ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .gauge { position: relative; width: 16rem; height: 0.5rem; background: rgb(203 213 225); } .gauge__progress { position: absolute; top: 0; left: 0; width: 60%; height: 100%; background: rgb(99 102 241); } ``` ```html index.html
```
## Adding ticks to the linear gauge To make your linear gauge more informative, it's important to include ticks. Ticks provide visual markers that indicate specific points on the gauge and help users understand where they are on the scale. In this example, we add five ticks between 0 and 100 percent, representing key milestones along the way. This makes it easier for users to quickly gauge their progress and understand their current position. ```html
``` To add ticks to a gauge, we use absolute positioning and set the `left` property to a percentage value based on where we want the tick to appear. For example, to add a tick at the 25% mark, we set `left` to 25%. The tick is then positioned at that point on the gauge. We can adjust the height of each tick using the `height` property and set the `width` to 1px to create a thin vertical line. By default, the tick color matches the gauge container, but we can customize it with CSS to create a more visually appealing and informative gauge. By adding ticks to a gauge, we can provide viewers with additional information about the data being displayed. We can also use different colors or styles for each tick to make the gauge easier to read and interpret. ```css .gauge__tick { position: absolute; top: 100%; height: 0.5rem; width: 1px; background: rgb(203 213 225); } ``` We can make our gauge even more informative by adding smaller ticks, also known as minor ticks, to the axis. We can insert three minor ticks between each major tick by placing them at a percentage value that falls between two adjacent major ticks. This provides more detailed information on the range of values displayed and helps viewers understand the gauge better. ```html
...
``` To make it easier for viewers to distinguish between major and minor ticks, we can use a separate CSS class and adjust its height to make it smaller than the main ticks. This way, viewers can understand the ticks correctly and avoid any confusion. ```css .gauge__tick--minor { height: 0.25rem; } ``` Check out the demo below to see how even small changes can make a big difference with ticks. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .gauge { position: relative; width: 16rem; height: 0.5rem; background: rgb(203 213 225); } .gauge__progress { position: absolute; top: 0; left: 0; width: 60%; height: 100%; background: rgb(99 102 241); } .gauge__tick { position: absolute; top: 100%; height: 0.5rem; width: 1px; background: rgb(203 213 225); } .gauge__tick--minor { height: 0.25rem; } ``` ```html index.html
```
## Enhancing the linear gauge with labels We can make the linear gauge even more informative by adding labels to indicate specific values along the gauge. Labels can be used to show the current value of the progress indicator or to mark important milestones on the gauge. To add a label, we simply create a new element inside the tick element, give it a class name, and set its content to the value we want to display. With this simple addition, our linear gauge becomes even more useful and visually appealing. ```html
50
...
``` In this example, we've added a label to the gauge at the 50% mark. To position the label, we use absolute positioning and set its `left` property to 50%. This centers the label horizontally within the tick element. To center the label vertically, we use the `transform` property to move it up by a quarter of the tick's height. By combining these CSS properties, we can create labels that show data in real-time and give viewers more information about the values being displayed. We can also use different colors or styles for each label to make the gauge more visually appealing and easy to read. ```css .gauge__label { position: absolute; left: 50%; transform: translate(-50%, 0.25rem); } ``` Customizing the appearance of our labels can help make them more visually appealing for viewers. By adjusting properties like font size and color, we can create a polished and professional look for our linear gauge. By combining ticks, labels, and other design elements, we can create a visualization that effectively communicates important information to viewers in an engaging and informative way. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .gauge { position: relative; width: 16rem; height: 0.5rem; background: rgb(203 213 225); } .gauge__progress { position: absolute; top: 0; left: 0; width: 60%; height: 100%; background: rgb(99 102 241); } .gauge__tick { position: absolute; top: 100%; height: 0.5rem; width: 1px; background: rgb(203 213 225); } .gauge__tick--minor { height: 0.25rem; } .gauge__label { position: absolute; left: 50%; transform: translate(-50%, 0.5rem); } ``` ```html index.html
0
25
50
75
100
```
By changing the position from `left` to `top`, we can easily create a horizontal gauge as follows: ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .gauge { position: relative; height: 16rem; width: 0.5rem; background: rgb(203 213 225); } .gauge__progress { position: absolute; top: 0; left: 0; height: 60%; width: 100%; background: rgb(99 102 241); } .gauge__tick { position: absolute; left: 100%; width: 0.5rem; height: 1px; background: rgb(203 213 225); } .gauge__tick--minor { width: 0.25rem; } .gauge__label { position: absolute; left: 50%; transform: translate(0.5rem, -50%); } ``` ```html index.html
0
25
50
75
100
```
## Conclusion CSS and HTML give us the power to create linear gauges that are not only informative but also visually appealing. By adding ticks and labels to our gauge, we can provide more context for viewers to easily interpret the data in real-time. Customizing the colors and styles of our gauge elements can create a more engaging user experience that encourages viewers to interact with the data. Overall, CSS and HTML offer a robust toolkit for creating effective linear gauges that communicate important information clearly and concisely. ================================================ FILE: contents/lined-paper.mdx ================================================ --- category: Display created: '2020-01-17' description: Create lined paper with CSS keywords: css linear gradient, css lined paper, css multiple horizontal lines thumbnail: /assets/css-layout/thumbnails/lined-paper.png title: Lined paper --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .lined-paper { /* Lined background */ background-image: linear-gradient(#d1d5db 1px, transparent 0px); background-size: 100% 2em; /* Display the content on top of the lines. The line height must be the same as the background size defined above */ background-position-y: 1.5rem; line-height: 2em; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .lined-paper { /* Lined background */ background-image: linear-gradient(#d1d5db 1px, transparent 0px); background-size: 100% 2em; /* Display the content on top of the lines. The line height must be the same as the background size defined above */ background-position-y: 1.5rem; line-height: 2em; /* Demo */ overflow: hidden; } ``` ```html index.html hidden
Cascading Style Sheets (CSS) is a style sheet language used for describing the presentation of a document written in a markup language like HTML. CSS is a cornerstone technology of the World Wide Web, alongside HTML and JavaScript.
```
================================================ FILE: contents/masonry-grid.mdx ================================================ --- category: Layout created: '2021-04-28' description: Create a masonry grid with CSS keywords: css column-count, css column-gap, css masonry, css masonry grid thumbnail: /assets/css-layout/thumbnails/masonry-grid.png title: Masonry grid --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .masonry-grid { /* It is split into 3 columns */ column-count: 3; /* The space between columns */ column-gap: 1rem; } .masonry-grid__item { /* Prevent a column from breaking into multiple columns */ break-inside: avoid; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .masonry-grid { /* It is split into 3 columns */ column-count: 3; /* The space between columns */ column-gap: 1rem; /* Demo */ height: 100%; width: 100%; } .masonry-grid__item { /* Prevent a column from breaking into multiple columns */ break-inside: avoid; /* Misc */ margin-bottom: 1rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/media-object.mdx ================================================ --- category: Display created: '2019-11-16' description: Create a media object with CSS flexbox keywords: css flexbox, media object thumbnail: /assets/css-layout/thumbnails/media-object.png title: Media object --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .media-object { /* Align sub-items to top */ align-items: start; display: flex; } .media-object__media { margin-right: 0.5rem; } .media-object__content { /* Take the remaining width */ flex: 1; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .square { background: #d1d5db; height: var(--square-size); width: var(--square-size); } .square--sm { --square-size: 0.5rem; } .square--md { --square-size: 2rem; } .square--lg { --square-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .media-object { /* Align sub-items to top */ align-items: start; display: flex; /* Demo */ width: 16rem; } .media-object__media { margin-right: 0.5rem; } .media-object__content { /* Take the remaining width */ flex: 1; } ``` ```html index.html hidden
```
================================================ FILE: contents/mega-menu.mdx ================================================ --- category: Navigation created: '2019-12-29' description: Create a mega menu with CSS keywords: css mega menu thumbnail: /assets/css-layout/thumbnails/mega-menu.png title: Mega menu --- ## HTML ```html index.html
...
...
...
...
``` ## CSS ```css styles.css .mega-menu { /* Used to position the mega menu */ position: relative; } .mega-menu__trigger:hover .mega-menu__content { /* Show the mega menu when hovering the trigger item */ display: block; } .mega-menu__content { /* Border */ border: 1px solid #d1d5db; margin-top: -1px; /* Hidden by default */ display: none; /* Absolute position */ left: 0px; position: absolute; top: 100%; /* Take full width */ width: 100%; /* Displayed on top of other elements */ background: #fff; z-index: 9999; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden .mega-menu { align-items: center; display: flex; justify-content: center; position: relative; border: 1px solid #d1d5db; border-radius: 0.25rem; /* Demo */ width: 100%; } .mega-menu__item { display: flex; align-items: center; height: 100%; flex: 1; padding: 0.25rem 0.5rem; } .mega-menu__item:not(:last-child) { border-right: 1px solid #d1d5db; } .mega-menu__trigger { cursor: pointer; /* Demo */ height: 2rem; align-items: center; display: flex; justify-content: center; } .mega-menu__content { /* Border */ border: 1px solid #d1d5db; /* margin-top: -1px; */ /* Hidden by default */ display: none; /* Position it right below the trigger element */ left: 0; padding-top: 0.25rem; position: absolute; top: 100%; /* Take full width */ width: 100%; /* It should be on the top of other elements */ background-color: #fff; z-index: 9999; } /* Show the mega menu when hovering the trigger item */ .mega-menu__trigger:hover .mega-menu__content { display: block; } ``` ```html index.html hidden
```
================================================ FILE: contents/menu.mdx ================================================ --- category: Navigation created: '2019-11-17' description: Create a menu with CSS flexbox keywords: css flexbox, css menu thumbnail: /assets/css-layout/thumbnails/menu.png title: Menu --- ## HTML ```html index.html ``` ## CSS ```css styles.css .menu { display: flex; flex-direction: column; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; } .menu__item { /* Center the content horizontally */ align-items: center; display: flex; } .menu__hotkey { /* Push the hot key to the right */ margin-left: auto; } .menu__divider { border-bottom: 1px solid #d1d5db; height: 1px; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .menu { display: flex; flex-direction: column; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; /* Demo */ width: 16rem; } .menu__item { /* Center the content horizontally */ align-items: center; display: flex; height: 2rem; padding: 0.25rem; } .menu__item:hover { background: #e5e7eb; } .menu__hotkey { /* Push the hot key to the right */ margin-left: auto; } .menu__divider { border-bottom: 1px solid #d1d5db; height: 1px; } ``` ```html index.html hidden ``` ================================================ FILE: contents/modal.mdx ================================================ --- category: Feedback created: '2019-11-17' description: Create a modal with CSS flexbox keywords: css dialog, css flexbox, css modal thumbnail: /assets/css-layout/thumbnails/modal.png title: Modal --- ## HTML ```html index.html ``` ## CSS ```css styles.css .modal { /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; } .modal__header { display: flex; justify-content: space-between; /* Border */ border-bottom: 1px solid #d1d5db; } .modal__footer { display: flex; /* Push the buttons to the right */ justify-content: flex-end; /* Border */ border-top: 1px solid #d1d5db; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .modal { /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; flex-direction: column; /* Demo */ width: 16rem; } .modal__header { display: flex; justify-content: space-between; /* Border */ border-bottom: 1px solid #d1d5db; padding: 0.25rem 0.5rem; } .modal__body { flex: 1; overflow: auto; } .modal__footer { display: flex; /* Push the buttons to the right */ justify-content: flex-end; /* Border */ border-top: 1px solid #d1d5db; padding: 0.25rem 0.5rem; } ``` ```html index.html hidden ``` ================================================ FILE: contents/nested-dropdowns.mdx ================================================ --- category: Navigation created: '2020-01-13' description: Create nested dropdown menu with CSS keywords: css dropdown menu, css multi-level dropdown menu, css nested dropdown menu thumbnail: /assets/css-layout/thumbnails/nested-dropdowns.png title: Nested dropdowns --- ## HTML ```html index.html ``` ## CSS ```css styles.css .nested-dropdowns { /* Border */ border: 1px solid #d1d5db; display: flex; /* Reset list styles */ list-style-type: none; margin: 0; padding: 0; } .nested-dropdowns li { cursor: pointer; /* Spacing */ padding: 0.25rem; /* Used to position the sub nested-dropdowns */ position: relative; } /* The sub nested-dropdowns */ .nested-dropdowns ul { /* Border */ border: 1px solid #d1d5db; /* Hidden by default */ display: none; /* Absolute position */ left: 0; position: absolute; top: 100%; /* Reset styles */ list-style-type: none; margin: 0; padding: 0; } /* The second level sub nested-dropdowns */ .nested-dropdowns ul ul { left: 100%; position: absolute; top: 0; } /* Change background color of list item when being hovered */ .nested-dropdowns li:hover { background-color: rgba(0, 0, 0, 0.1); } /* Show the direct sub nested-dropdowns when hovering the list item */ .nested-dropdowns li:hover > ul { display: block; } ``` ```css placeholders.css hidden .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; height: 32rem; } .nested-dropdowns { /* Border */ border: 1px solid #d1d5db; display: flex; /* Reset list styles */ list-style-type: none; margin: 0; padding: 0; } .nested-dropdowns li { cursor: pointer; /* Spacing */ padding: 0.25rem; /* Used to position the sub nested-dropdowns */ position: relative; } /* The sub nested-dropdowns */ .nested-dropdowns ul { /* Border */ border: 1px solid #d1d5db; /* Hidden by default */ display: none; /* Absolute position */ left: 0; position: absolute; top: 100%; /* Reset styles */ list-style-type: none; margin: 0; padding: 0; } /* The second level sub nested-dropdowns */ .nested-dropdowns ul ul { left: 100%; position: absolute; top: 0; } /* Change background color of list item when being hovered */ .nested-dropdowns li:hover { background-color: rgba(0, 0, 0, 0.1); } /* Show the direct sub nested-dropdowns when hovering the list item */ .nested-dropdowns li:hover > ul { display: block; } /* Demo */ .nested-dropdowns__item { align-items: center; display: flex; } .nested-dropdowns__arrow { margin-left: 0.25rem; } ``` ```html index.html hidden ``` ================================================ FILE: contents/notification.mdx ================================================ --- category: Feedback created: '2019-11-17' description: Create a notification with CSS flexbox keywords: css alert, css flexbox, css notification thumbnail: /assets/css-layout/thumbnails/notification.png title: Notification --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .notification { display: flex; } .notification__body { flex: 1; margin-right: 0.5rem; } ``` The [close button](https://phuoc.ng/collection/css-layout/close-button/) represents the button for closing the notification. ```css .notification__close { /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 1rem; width: 1rem; /* Used to position the inner */ position: relative; } .notification__close-line { /* Background color */ background-color: #d1d5db; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .notification__close-line--first { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .notification__close-line--second { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .notification { display: flex; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem; width: 16rem; } .notification__body { flex: 1; margin-right: 0.5rem; } .notification__close { /* Reset */ background-color: transparent; border-color: transparent; /* Cursor */ cursor: pointer; /* Size */ height: 1rem; width: 1rem; /* Used to position the inner */ position: relative; } .notification__close-line { /* Background color */ background-color: #d1d5db; /* Position */ position: absolute; /* Size */ height: 1px; width: 100%; } .notification__close-line--first { /* Position */ left: 0px; top: 50%; transform: translate(0%, -50%) rotate(45deg); /* Size */ height: 1px; width: 100%; } .notification__close-line--second { /* Position */ left: 50%; top: 0px; transform: translate(-50%, 0%) rotate(45deg); /* Size */ height: 100%; width: 1px; } ``` ```html index.html hidden
```
================================================ FILE: contents/overlay-play-button.mdx ================================================ --- category: Display created: '2019-11-30' description: Create an overlay play button with CSS flexbox keywords: css flexbox thumbnail: /assets/css-layout/thumbnails/overlay-play-button.png title: Overlay play button --- ## HTML ```html index.html
``` ## CSS ```css styles.css .overlay-play-button { /* Used to position the overlay */ position: relative; } .overlay-play-button__overlay { /* Position */ left: 0; position: absolute; top: 0; /* Take full size */ height: 100%; width: 100%; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Add a dark background */ background-color: rgba(0, 0, 0, 0.25); } .overlay-play-button__play { border: 0.25rem solid #fff; border-radius: 9999px; height: 3rem; width: 3rem; /* Center the content */ align-items: center; display: flex; justify-content: center; } ``` ```css placeholders.css hidden .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .overlay-play-button { /* Used to position the overlay */ position: relative; /* Demo */ height: 100%; width: 100%; } .overlay-play-button__overlay { /* Position */ left: 0; position: absolute; top: 0; /* Take full size */ height: 100%; width: 100%; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Add a dark background */ background-color: #4b5563; } .overlay-play-button__play { border: 0.25rem solid #fff; border-radius: 9999px; height: 3rem; width: 3rem; align-items: center; display: flex; justify-content: center; } ``` ```html index.html hidden
```
================================================ FILE: contents/pagination.mdx ================================================ --- category: Navigation created: '2019-11-17' description: Create a pagination with CSS flexbox keywords: css flexbox, css pagination thumbnail: /assets/css-layout/thumbnails/pagination.png title: Pagination --- ## HTML ```html index.html ``` ## CSS ```css styles.css .pagination { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 4px; } .pagination__item { /* Center the content */ align-items: center; display: flex; justify-content: center; } .pagination__item:not(:last-child) { /* Right border */ border-right: 1px solid #d1d5db; } .pagination__item--active { background-color: #d1d5db; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .pagination { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 4px; } .pagination__item { /* Center the content */ align-items: center; display: flex; justify-content: center; padding: 0.25rem 0.5rem; } .pagination__item:not(:last-child) { /* Right border */ border-right: 1px solid #d1d5db; } .pagination__item--active { background-color: #d1d5db; } ``` ```html index.html hidden ``` ================================================ FILE: contents/pie-chart.mdx ================================================ --- category: Feedback created: '2023-11-17' description: Create a pie chart openGraphCover: /og/css-layout/pie-chart.png thumbnail: /assets/css-layout/thumbnails/pie-chart.png title: Pie chart --- Pie charts are a great way to visually represent data. They show data as parts of a whole, making it easy to compare and analyze. Pie charts are especially helpful when working with percentages or proportions that add up to 100%. They can also help identify trends, patterns, and outliers in the data. By using different colors and labeling each slice, you can create a clear and easy-to-understand representation of complex information. In this post, we'll show you how to create a pie chart using pure HTML and CSS. It's a simple yet effective way to communicate important data points to your audience. Let's get started! ## Setting up the layout Generating a pie chart is a simple process. A pie chart is usually placed in a circle. To begin, we divide the circle into two equal halves. ```html
``` To create the chart, we rotate one half of the circle based on the percentage of progress being displayed, while the other half remains stationary as the chart's background. In the next section, we'll dive into the details of how to implement this idea. ## Positioning halves To create a circle shape for our container, we can use the `border-radius` property and set it to 50%. This will round all four corners and voila! We have a perfect circle. Don't forget to specify the `height` and `width` of the circle to determine its size. If both values are the same, our circle will be perfectly round and symmetrical. ```css .circle { border-radius: 50%; height: 12rem; width: 12rem; } ``` Both halves of the circle are positioned absolutely, so we need to change the `position` style to `relative`. ```css .circle { position: relative; overflow: hidden; } ``` When creating a pie chart inside a circle, it's crucial to use the `overflow: hidden` property. This ensures that any parts of the pie chart that extend beyond the bounds of the circle are hidden from view, giving the chart a professional and polished look. To position the two halves of the circle, we use `position: absolute` in CSS. This lets us place the elements anywhere we want within their parent container. Both halves should have a height of 50% and a width of 100%, so they each occupy half of the circle. To ensure proper positioning, we also set `transform-origin: 50% 100%;`. This ensures that when we rotate one of the halves, it rotates around its bottom center point, which is exactly what we need to create a pie chart. ```css .circle__half { position: absolute; top: 0; height: 50%; width: 100%; transform-origin: 50% 100%; } ``` To give the first half of the circle a background color, we can apply a CSS style to it. This will make the portion of the chart that represents completed progress have a solid color. ```css .circle__half--1 { background: rgb(99 102 241); } ``` By using positioning properties, we can easily create a pie chart. We rotate one half of the circle based on the percentage of progress being displayed, while the other half remains stationary, acting as the chart's background. To illustrate, let's say we want to display progress by rotating the second half of the circle. In the sample code below, we rotate it by 120 degrees: ```css .circle__half--2 { transform: rotate(120deg); } ``` To make the second half of the circle transparent, we need to set its `background` property to `inherit`. This is because we only want the first half of the circle to have a solid color while the second half should be see-through to show the underlying container. By setting `background: inherit`, we tell the browser to use the same background color as its parent element. This creates a smooth transition between our pie chart and its surrounding container. ```css .circle__half--2 { background: inherit; } ``` Take a look at the demo below: ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .circle { background: rgb(203 213 225); border-radius: 50%; position: relative; overflow: hidden; height: 12rem; width: 12rem; } .circle__half { position: absolute; top: 0; height: 50%; width: 100%; transform-origin: 50% 100%; } .circle__half--1 { background: rgb(99 102 241); } .circle__half--2 { background: inherit; transform: rotate(120deg); } ``` ```html index.html
```
Keep in mind that if you want to display a pie chart with a degree greater than 180, the second half must have the same background color as the first half. ```css .circle__half--2 { background: rgb(99 102 241); transform: rotate(60deg); } ``` Here's an example of how to create a pie chart using 240 degrees. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } ``` ```css styles.css .circle { background: rgb(203 213 225); border-radius: 50%; position: relative; overflow: hidden; height: 12rem; width: 12rem; } .circle__half { position: absolute; top: 0; height: 50%; width: 100%; transform-origin: 50% 100%; } .circle__half--1 { background: rgb(99 102 241); } .circle__half--2 { background: rgb(99 102 241); transform: rotate(60deg); } ``` ```html index.html
```
## Conclusion Pie charts are an excellent way to visually represent data. They help viewers quickly and easily understand how different parts relate to the whole. With pure HTML and CSS, creating a pie chart is simple and customizable. In this post, we'll cover the basics of creating a pie chart in CSS. You'll learn how to position the circle halves using absolute positioning and `transform-origin`. We'll also discuss setting background colors for each half and rotating one half based on the progress percentage. By using these techniques, you can create beautiful and informative pie charts that will impress your audience. Remember to keep it simple, avoid cluttering your chart with too much information, and label each slice clearly. Use colors sparingly to ensure viewers can easily understand what they're looking at. ================================================ FILE: contents/popover-arrow.mdx ================================================ --- category: Feedback created: '2019-12-03' description: Create a popover arrow with CSS keywords: css arrow, css thumbnail: /assets/css-layout/thumbnails/popover-arrow.png title: Popover arrow --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .popover-arrow { /* Border */ border: 1px solid #d1d5db; /* Used to position the arrow */ position: relative; } .popover-arrow__arrow { /* Size */ height: 0.5rem; width: 0.5rem; background-color: #fff; position: absolute; } .popover-arrow__arrow--tl { /* Position at the top left corner */ left: 1rem; top: 0; /* Border */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--tc { /* Position at the top center */ left: 50%; top: 0; /* Border */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--tr { /* Position at the top right corner */ right: 1rem; top: 0; /* Border */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--rt { /* Position at the right top corner */ right: 0; top: 1rem; /* Border */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, 50%) rotate(45deg); } .popover-arrow__arrow--rc { /* Position at the right center */ right: 0; top: 50%; /* Border */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--rb { /* Position at the right bottom corner */ bottom: 1rem; right: 0; /* Border */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--bl { /* Position at the bottom left corner */ bottom: -0.5rem; left: 1rem; /* Border */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--bc { /* Position at the bottom center */ bottom: -0.5rem; left: 50%; /* Border */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--br { /* Position at the bottom right corner */ bottom: -0.5rem; right: 1rem; /* Border */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--lt { /* Position at the left top corner */ left: 0; top: 1rem; /* Border */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translate(-50%, 50%) rotate(45deg); } .popover-arrow__arrow--lc { /* Position at the left center */ left: 0; top: 50%; /* Border */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--lb { /* Position at the left bottom corner */ bottom: 1rem; left: 0; /* Border */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; height: 24rem; } .popover-arrow { /* Border */ border: 1px solid #d1d5db; /* Used to position the arrow */ position: relative; /* Demo */ height: 16rem; width: 16rem; } .popover-arrow__arrow { /* Size */ height: 1rem; width: 1rem; background-color: #fff; position: absolute; } .popover-arrow__arrow--tl { /* Position at the top left corner */ left: 1rem; top: 0; /* Border */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--tc { /* Position at the top center */ left: 50%; top: 0; /* Border */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--tr { /* Position at the top right corner */ right: 1rem; top: 0; /* Border */ border-left: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--rt { /* Position at the right top corner */ right: 0; top: 1rem; /* Border */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, 50%) rotate(45deg); } .popover-arrow__arrow--rc { /* Position at the right center */ right: 0; top: 50%; /* Border */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--rb { /* Position at the right bottom corner */ bottom: 1rem; right: 0; /* Border */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--bl { /* Position at the bottom left corner */ bottom: -1rem; left: 1rem; /* Border */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translate(50%, -50%) rotate(45deg); } .popover-arrow__arrow--bc { /* Position at the bottom center */ bottom: -1rem; left: 50%; /* Border */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--br { /* Position at the bottom right corner */ bottom: -1rem; right: 1rem; /* Border */ border-bottom: 1px solid #d1d5db; border-right: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--lt { /* Position at the left top corner */ left: 0; top: 1rem; /* Border */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translate(-50%, 50%) rotate(45deg); } .popover-arrow__arrow--lc { /* Position at the left center */ left: 0; top: 50%; /* Border */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } .popover-arrow__arrow--lb { /* Position at the left bottom corner */ bottom: 1rem; left: 0; /* Border */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translate(-50%, -50%) rotate(45deg); } ``` ```html index.html hidden
```
## See also - [Speech bubble](https://phuoc.ng/collection/css-layout/speech-bubble/) - [Triangle buttons](https://phuoc.ng/collection/css-layout/triangle-buttons/) ================================================ FILE: contents/presence-indicator.mdx ================================================ --- category: Feedback created: '2019-11-29' description: Create a presence indicator with CSS keywords: css indicator thumbnail: /assets/css-layout/thumbnails/presence-indicator.png title: Presence indicator --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .presence-indicator { position: relative; } .presence-indicator__indicator { /* Shown at the bottom right corner */ bottom: 0; position: absolute; right: 0; transform: translate(50%, 50%); /* Rounded border */ border-radius: 9999px; height: 1rem; width: 1rem; /* Background color */ background-color: #22c55e; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .presence-indicator { position: relative; /* Demo */ background-color: #d1d5db; border-radius: 9999px; height: 6rem; width: 6rem; } .presence-indicator__indicator { /* Shown at the bottom right corner */ bottom: 0; position: absolute; right: 0; transform: translate(50%, 50%); /* Rounded border */ border-radius: 9999px; height: 1rem; width: 1rem; /* Background color */ background-color: #22c55e; } ``` ```html index.html hidden
```
================================================ FILE: contents/previous-next-buttons.mdx ================================================ --- category: Navigation created: '2019-11-17' description: Create previous and next buttons with CSS flexbox keywords: css flexbox, css pagination thumbnail: /assets/css-layout/thumbnails/previous-next-buttons.png title: Previous next buttons --- ## HTML ```html index.html
``` ## CSS ```css styles.css .previous-next-buttons { align-items: center; display: flex; justify-content: space-between; } ``` You can use the [arrow buttons](https://phuoc.ng/collection/css-layout/arrow-buttons/) to create the previous and next buttons. ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .previous-next-buttons { align-items: center; display: flex; justify-content: space-between; /* Demo */ width: 16rem; } .previous-next-buttons__nav { position: relative; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem 0.5rem; align-items: center; display: flex; justify-content: center; height: 2rem; width: 3rem; } .previous-next-buttons__button { /* Transparent background */ background-color: transparent; /* Size */ height: 0.5rem; width: 0.5rem; } .previous-next-buttons__button--r { /* Edges */ border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; transform: translateX(-25%) rotate(45deg); } .previous-next-buttons__button--l { /* Edges */ border-bottom: 1px solid #d1d5db; border-left: 1px solid #d1d5db; transform: translateX(25%) rotate(45deg); } ``` ```html index.html hidden
```
================================================ FILE: contents/price-tag.mdx ================================================ --- category: Display created: '2021-04-03' description: Create a price tag with CSS keywords: css price tag thumbnail: /assets/css-layout/thumbnails/price-tag.png title: Price tag --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css :root { --price-tag-background: #d1d5db; --price-tag-height: 2rem; } .price-tag { background: var(--price-tag-background); color: #fff; /* Center the price */ align-items: center; display: flex; justify-content: center; /* Used to position the triangle */ position: relative; /* Size */ height: var(--price-tag-height); /* Spacing */ padding: 0.25rem 0.5rem; } /* The triangle */ .price-tag::before { content: ''; border-color: transparent var(--price-tag-background) transparent transparent; border-style: solid; border-width: calc(var(--price-tag-height) / 2) calc(var(--price-tag-height) / 2) calc(var(--price-tag-height) / 2) 0rem; /* Position */ left: 0px; position: absolute; top: 0px; transform: translate(-100%, 0px); } /* The dot */ .price-tag::after { content: ''; /* Make it like a cirle */ background: #fff; border-radius: 9999rem; /* Position */ left: 0; position: absolute; top: 50%; transform: translate(-0.5rem, -50%); /* Size */ height: 0.5rem; width: 0.5rem; } ``` ```css styles.css hidden :root { --price-tag-background: #d1d5db; --price-tag-height: 2rem; } body { align-items: center; display: flex; justify-content: center; } .price-tag { background: var(--price-tag-background); color: #fff; /* Center the price */ align-items: center; display: flex; justify-content: center; /* Used to position the triangle */ position: relative; /* Size */ height: var(--price-tag-height); /* Spacing */ padding: 0.25rem 0.5rem; } /* The triangle */ .price-tag::before { content: ''; border-color: transparent var(--price-tag-background) transparent transparent; border-style: solid; border-width: calc(var(--price-tag-height) / 2) calc(var(--price-tag-height) / 2) calc(var(--price-tag-height) / 2) 0rem; /* Position */ left: 0px; position: absolute; top: 0px; transform: translate(-100%, 0px); } /* The dot */ .price-tag::after { content: ''; /* Make it like a cirle */ background: #fff; border-radius: 9999rem; /* Position */ left: 0; position: absolute; top: 50%; transform: translate(-0.5rem, -50%); /* Size */ height: 0.5rem; width: 0.5rem; } ``` ```html index.html hidden
99.99$
```
================================================ FILE: contents/pricing-table.mdx ================================================ --- category: Display created: '2019-11-18' description: Create a pricing table with CSS flexbox keywords: css flexbox, css pricing table thumbnail: /assets/css-layout/thumbnails/pricing-table.png title: Pricing table --- ## HTML ```html index.html
... ... ... ...
...
``` ## CSS ```css styles.css .pricing-table { /* Content is centered horizontally */ align-items: center; display: flex; justify-content: center; } .pricing-table__column { /* Content is centered vertically */ align-items: center; display: flex; flex-direction: column; justify-content: center; /* Make all columns have the same width */ flex: 1; /* OPTIONAL: Space between columns */ margin: 0 0.5rem; /* OPTIONAL: Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden .pricing-table { align-items: center; display: flex; justify-content: center; } .pricing-table__column { border: 1px solid #d1d5db; border-radius: 0.25rem; margin: 0 0.25rem; padding: 0.25rem; width: 16rem; align-items: center; display: flex; flex-direction: column; } ``` ```html index.html hidden
```
================================================ FILE: contents/progress-bar.mdx ================================================ --- category: Feedback created: '2019-11-17' description: Create a progress bar with CSS flexbox keywords: css flexbox, css progress bar thumbnail: /assets/css-layout/thumbnails/progress-bar.png title: Progress bar --- ## HTML ```html index.html
40%
``` ## CSS ```css styles.css .progress-bar { /* Colors */ background-color: #d1d5db; /* Rounded border */ border-radius: 9999px; padding: 0.25rem; } .progress-bar__progress { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Colors */ background-color: #3b82f6; color: #fff; /* Rounded border */ border-radius: 9999px; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .progress-bar { /* Colors */ background-color: #d1d5db; /* Rounded border */ border-radius: 9999px; padding: 0.25rem; /* Demo */ width: 16rem; } .progress-bar__progress { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Colors */ background-color: #3b82f6; color: #fff; /* Rounded border */ border-radius: 9999px; width: 40%; } ``` ```html index.html hidden
40%
```
## See also - [Indeterminate progress bar](https://phuoc.ng/collection/css-layout/indeterminate-progress-bar/) ================================================ FILE: contents/property-list.mdx ================================================ --- category: Display created: '2019-11-25' description: Create a property list with CSS flexbox keywords: css flexbox, property list thumbnail: /assets/css-layout/thumbnails/property-list.png title: Property list --- ## HTML ```html index.html
...
...
... ``` ## CSS ```css styles.css .property-list { /* Content is center horizontally */ align-items: center; display: flex; border-bottom: 1px solid #d1d5db; /* Spacing */ margin: 0; padding: 0.25rem 0; } .property-list__key { /* Take the available width */ flex: 1; } .property-list__value { margin-left: 0.5rem; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .property-list { /* Content is center horizontally */ align-items: center; display: flex; border-bottom: 1px solid #d1d5db; /* Spacing */ margin: 0; padding: 0.5rem 0; width: 16rem; } .property-list__key { /* Take the remaining width */ flex: 1; } .property-list__value { margin-left: 0.5rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/questions-and-answers.mdx ================================================ --- category: Display created: '2019-11-23' description: Create a questions and answers section with CSS flexbox keywords: css accordion, css faq, css flexbox thumbnail: /assets/css-layout/thumbnails/questions-and-answers.png title: Questions and answers --- ## HTML ```html index.html
...
...
...
``` ## CSS ```css styles.css .questions-and-answers__item:not(:last-child) { border-bottom: 1px solid #d1d5db; } .questions-and-answers__header { align-items: center; display: flex; justify-content: center; cursor: pointer; padding: 0.5rem; } .questions-and-answers__toggle { margin-right: 0.25rem; } .questions-and-answers__title { /* Take the available width */ flex: 1; } .questions-and-answers__content { padding: 0 0.5rem; } .questions-and-answers__item--collapsed .questions-and-answers__content { display: none; } .questions-and-answers__item--expanded .questions-and-answers__content { display: block; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .questions-and-answers { width: 16rem; } .questions-and-answers__item:not(:last-child) { border-bottom: 1px solid #d1d5db; } .questions-and-answers__header { align-items: center; display: flex; justify-content: center; cursor: pointer; padding: 0.5rem; } .questions-and-answers__toggle { margin-right: 0.25rem; } .questions-and-answers__title { flex: 1; } .questions-and-answers__content { padding: 0 0.5rem; } .questions-and-answers__item--collapsed .questions-and-answers__content { display: none; } .questions-and-answers__item--expanded .questions-and-answers__content { display: block; } ``` ```html index.html hidden
```
================================================ FILE: contents/radial-progress-bar.mdx ================================================ --- category: Feedback created: '2019-11-30' description: Create a radial progress bar with CSS flexbox keywords: css clip rect, css flexbox, css progress bar thumbnail: /assets/css-layout/thumbnails/radial-progress-bar.png title: Radial progress bar --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css :root { --radial-progress-bar-size: 8rem; --radial-progress-bar-border-width: 0.75rem; } .radial-progress-bar { position: relative; height: var(--radial-progress-bar-size); width: var(--radial-progress-bar-size); } .radial-progress-bar__percentages { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Rounded border */ border: var(--radial-progress-bar-border-width) solid #d1d5db; border-radius: 9999px; /* Size */ height: 100%; width: 100%; } .radial-progress-bar__curve { /* Position */ left: 0; position: absolute; top: 0; /* Take full size */ height: 100%; width: 100%; /* If percentages is less than 50 */ /* clip: rect( 0px, var(--radial-progress-bar-size), var(--radial-progress-bar-size), calc(var(--radial-progress-bar-size) * 0.5), 0px ); */ /* If percentages is greater than or equals to 50 */ clip: rect(auto, auto, auto, auto); } .radial-progress-bar__half { /* Take full size */ height: 100%; position: absolute; width: 100%; /* Background color of curve. The border width should be the same as the area showing the percentages */ border: var(--radial-progress-bar-border-width) solid #3b82f6; border-radius: 9999px; } .radial-progress-bar__half--first { /* Position */ clip: rect(0px, calc(var(--radial-progress-bar-size) * 0.5), var(--radial-progress-bar-size), 0px); /* Number of percentages * 360 / 100 */ transform: rotate(270deg); } .radial-progress-bar__half--second { /* Position */ clip: rect(0px, calc(var(--radial-progress-bar-size) * 0.5), var(--radial-progress-bar-size), 0px); /* If percentages is less than 50 */ /* transform: rotate(0deg); */ /* If percentages is greater than or equals to 50 */ transform: rotate(180deg); } ``` ```css styles.css hidden :root { --radial-progress-bar-size: 8rem; --radial-progress-bar-border-width: 0.75rem; } body { align-items: center; display: flex; justify-content: center; } .radial-progress-bar { position: relative; height: var(--radial-progress-bar-size); width: var(--radial-progress-bar-size); } .radial-progress-bar__percentages { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Rounded border */ border: var(--radial-progress-bar-border-width) solid #d1d5db; border-radius: 9999px; /* Size */ height: 100%; width: 100%; } .radial-progress-bar__curve { /* Position */ left: 0; position: absolute; top: 0; /* Take full size */ height: 100%; width: 100%; /* If percentages is less than 50 */ // clip: rect(0px, var(--radial-progress-bar-size), var(--radial-progress-bar-size), calc(var(--radial-progress-bar-size) * 0.5), 0px); /* If percentages is greater than or equals to 50 */ clip: rect(auto, auto, auto, auto); } .radial-progress-bar__half { /* Take full size */ height: 100%; position: absolute; width: 100%; /* Background color of curve. The border width should be the same as the area showing the percentages */ border: var(--radial-progress-bar-border-width) solid #3b82f6; border-radius: 9999px; } .radial-progress-bar__half--first { /* Position */ clip: rect(0px, calc(var(--radial-progress-bar-size) * 0.5), var(--radial-progress-bar-size), 0px); /* Number of percentages * 360 / 100 */ transform: rotate(270deg); } .radial-progress-bar__half--second { /* Position */ clip: rect(0px, calc(var(--radial-progress-bar-size) * 0.5), var(--radial-progress-bar-size), 0px); /* If percentages is less than 50 */ // transform: rotate(0deg); /* If percentages is greater than or equals to 50 */ transform: rotate(180deg); } ``` ```html index.html hidden
75%
```
================================================ FILE: contents/radio-button-group.mdx ================================================ --- category: Input created: '2019-12-01' description: Create a radio button group with CSS flexbox keywords: css flexbox, css radio button thumbnail: /assets/css-layout/thumbnails/radio-button-group.png title: Radio button group --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .radio-button-group { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 2rem; } .radio-button-group__label { /* Center the content */ align-items: center; display: inline-flex; border-right: 1px solid #d1d5db; padding: 0.5rem; /* For not selected radio */ background-color: transparent; color: #ccc; } .radio-button-group__label:last-child { /* Remove the right border from the last label */ border-right-color: transparent; } .radio-button-group__label--selected { /* For selected radio */ background-color: #3b82f6; color: #fff; margin-top: -1px; margin-bottom: -1px; } .radio-button-group__input { /* Hide it */ display: none; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .radio-button-group { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 2rem; } .radio-button-group__label { /* Center the content */ align-items: center; display: inline-flex; border-right: 1px solid #d1d5db; padding: 0.5rem; /* For not selected radio */ background-color: transparent; color: #ccc; } .radio-button-group__label:last-child { /* Remove the right border from the last label */ border-right-color: transparent; } .radio-button-group__label--selected { /* For selected radio */ background-color: #3b82f6; color: #fff; margin-top: -1px; margin-bottom: -1px; } .radio-button-group__input { /* Hide it */ display: none; } ``` ```html index.html hidden
```
================================================ FILE: contents/radio-switch.mdx ================================================ --- category: Input created: '2019-11-24' description: Create a radio switch with CSS flexbox keywords: css flexbox, css radio switch, css switch thumbnail: /assets/css-layout/thumbnails/radio-switch.png title: Radio switch --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .radio-switch { background-color: #d1d5db; border-radius: 9999px; display: inline-flex; padding: 0.25rem; } .radio-switch__label { border-radius: 9999px; cursor: pointer; padding: 0.25rem 0.5rem; } .radio-switch__label--selected { /* For selected radio only */ background-color: #3b82f6; color: #fff; } .radio-switch__input { display: none; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .radio-switch { background-color: #d1d5db; border-radius: 9999px; display: inline-flex; padding: 0.25rem; } .radio-switch__label { border-radius: 9999px; cursor: pointer; padding: 0.25rem 0.5rem; } .radio-switch__label--selected { /* For selected radio only */ background-color: #3b82f6; color: #fff; } .radio-switch__input { display: none; } ``` ```html index.html hidden
```
================================================ FILE: contents/rating.mdx ================================================ --- category: Input created: '2019-11-26' description: Create a star rating with CSS flexbox keywords: css flexbox, css star rating thumbnail: /assets/css-layout/thumbnails/rating.png title: Rating --- ## HTML ```html index.html
``` ## CSS ```css styles.css .rating { /* Center the content */ align-items: center; display: flex; justify-content: center; flex-direction: row-reverse; } .rating__star:hover, .rating__star:hover ~ .rating__star { color: transparent; } /* Make all previous stars selected when hover on a star Note that we use \`flex-direction: row-reverse\` on the container */ .rating__star:hover:before, .rating__star:hover ~ .rating__star:before { color: #eab308; content: '★'; left: 0; position: absolute; } .rating__star { font-size: 1.5rem; /* Reset styles for button */ background-color: transparent; border: transparent; margin: 0 2px; padding: 0; /* Used to position the hover state */ position: relative; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .rating { /* Center the content */ align-items: center; display: flex; justify-content: center; flex-direction: row-reverse; } .rating__star:hover, .rating__star:hover ~ .rating__star { color: transparent; } /* Make all previous stars selected when hover on a star Note that we use \`flex-direction: row-reverse\` on the container */ .rating__star:hover:before, .rating__star:hover ~ .rating__star:before { color: #eab308; content: '★'; left: 0; position: absolute; } .rating__star { font-size: 1.5rem; /* Reset styles for button */ background-color: transparent; border: transparent; margin: 0 2px; padding: 0; /* Used to position the hover state */ position: relative; } ``` ```html index.html hidden
```
================================================ FILE: contents/resizable-element.mdx ================================================ --- category: Feedback created: '2019-12-10' description: Create resizable indicators with CSS keywords: css resizable, css resize cursor thumbnail: /assets/css-layout/thumbnails/resizable-element.png title: Resizable element --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .resizable-element { /* Border */ border: 1px dashed #d1d5db; /* Used to position the squares */ position: relative; } .resizable-element__resizer { /* Border */ border: 1px solid #d1d5db; position: absolute; /* Size */ height: 0.75rem; width: 0.75rem; } .resizable-element__resizer--tl { /* Resize cursor */ cursor: nwse-resize; /* Positioned at the top left corner */ left: 0px; top: 0px; transform: translate(-50%, -50%); } .resizable-element__resizer--tc { /* Resize cursor */ cursor: ns-resize; /* Positioned at the middle of top side */ left: 50%; top: 0px; transform: translate(-50%, -50%); } .resizable-element__resizer--tr { /* Resize cursor */ cursor: nesw-resize; /* Positioned at the top right corner */ right: 0px; top: 0px; transform: translate(50%, -50%); } .resizable-element__resizer--rc { /* Resize cursor */ cursor: ew-resize; /* Positioned at the middle of right side */ right: 0px; top: 50%; transform: translate(50%, -50%); } .resizable-element__resizer--rb { /* Resize cursor */ cursor: nwse-resize; /* Positioned at the right bottom corner */ bottom: 0px; right: 0px; transform: translate(50%, 50%); } .resizable-element__resizer--bc { /* Resize cursor */ cursor: ns-resize; /* Positioned at the middle of bottom side */ bottom: 0px; right: 50%; transform: translate(50%, 50%); } .resizable-element__resizer--bl { /* Resize cursor */ cursor: nesw-resize; /* Positioned at the bottom left corner */ bottom: 0px; left: 0px; transform: translate(-50%, 50%); } .resizable-element__resizer--lc { /* Resize cursor */ cursor: ew-resize; /* Positioned at the middle of left side */ left: 0px; top: 50%; transform: translate(-50%, -50%); } ``` You can move the mouse over each squares located at the corners and the middle of sides to see the cursors which indicate the associated side can be resized. ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; height: 24rem; } .resizable-element { /* Border */ border: 1px dashed #d1d5db; /* Used to position the squares */ position: relative; /* Demo */ height: 16rem; width: 16rem; } .resizable-element__resizer { /* Border */ border: 1px solid #d1d5db; position: absolute; /* Size */ height: 0.75rem; width: 0.75rem; } .resizable-element__resizer--tl { /* Resize cursor */ cursor: nwse-resize; /* Positioned at the top left corner */ left: 0px; top: 0px; transform: translate(-50%, -50%); } .resizable-element__resizer--tc { /* Resize cursor */ cursor: ns-resize; /* Positioned at the middle of top side */ left: 50%; top: 0px; transform: translate(-50%, -50%); } .resizable-element__resizer--tr { /* Resize cursor */ cursor: nesw-resize; /* Positioned at the top right corner */ right: 0px; top: 0px; transform: translate(50%, -50%); } .resizable-element__resizer--rc { /* Resize cursor */ cursor: ew-resize; /* Positioned at the middle of right side */ right: 0px; top: 50%; transform: translate(50%, -50%); } .resizable-element__resizer--rb { /* Resize cursor */ cursor: nwse-resize; /* Positioned at the right bottom corner */ bottom: 0px; right: 0px; transform: translate(50%, 50%); } .resizable-element__resizer--bc { /* Resize cursor */ cursor: ns-resize; /* Positioned at the middle of bottom side */ bottom: 0px; right: 50%; transform: translate(50%, 50%); } .resizable-element__resizer--bl { /* Resize cursor */ cursor: nesw-resize; /* Positioned at the bottom left corner */ bottom: 0px; left: 0px; transform: translate(-50%, 50%); } .resizable-element__resizer--lc { /* Resize cursor */ cursor: ew-resize; /* Positioned at the middle of left side */ left: 0px; top: 50%; transform: translate(-50%, -50%); } ``` ```html index.html hidden
```
================================================ FILE: contents/ribbon.mdx ================================================ --- category: Display created: '2019-12-01' description: Create a ribbon with CSS keywords: css ribbon thumbnail: /assets/css-layout/thumbnails/ribbon.png title: Ribbon --- ## HTML ```html index.html
``` ## CSS ```css styles.css .ribbon { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 2rem; /* Use to position the corners */ position: relative; } .ribbon__content { /* Background color */ background-color: #9ca3af; z-index: 1; height: 100%; width: 100%; } .ribbon__side { bottom: -0.5rem; position: absolute; /* Displayed under the ribbon */ z-index: 1; /* Background */ border: 1rem solid #d1d5db; } .ribbon__side--l { /* Position */ left: -1.5rem; border-color: #d1d5db #d1d5db #d1d5db transparent; } .ribbon__side--r { /* Position */ right: -1.5rem; border-color: #d1d5db transparent #d1d5db #d1d5db; } .ribbon__triangle { position: absolute; top: 100%; border: 0.5rem solid transparent; border-bottom-width: 0; border-top-color: #aaa; } .ribbon__triangle--l { border-right-width: 0; left: 0; } .ribbon__triangle--r { border-left-width: 0; right: 0; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .ribbon { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 2rem; width: 4rem; /* For demo */ /* Use to position the corners */ position: relative; } .ribbon__content { /* Background color */ background-color: #9ca3af; z-index: 1; height: 100%; width: 100%; } .ribbon__side { bottom: -0.5rem; position: absolute; /* Background */ border: 1rem solid #d1d5db; } .ribbon__side--l { /* Position */ left: -1.5rem; border-color: #d1d5db #d1d5db #d1d5db transparent; } .ribbon__side--r { /* Position */ right: -1.5rem; border-color: #d1d5db transparent #d1d5db #d1d5db; } .ribbon__triangle { position: absolute; top: 100%; border: 0.5rem solid transparent; border-bottom-width: 0; border-top-color: #6b7280; z-index: 1; } .ribbon__triangle--l { border-right-width: 0; left: 0; } .ribbon__triangle--r { border-left-width: 0; right: 0; } ``` ```html index.html hidden
```
================================================ FILE: contents/same-height-columns.mdx ================================================ --- category: Layout created: '2019-11-17' description: Create same height columns with CSS flexbox keywords: css flexbox, css layout, css same height columns thumbnail: /assets/css-layout/thumbnails/same-height-columns.png title: Same height columns --- ## HTML ```html index.html
...
...
...
...
``` ## CSS ```css styles.css .same-height-columns { display: flex; } .same-height-columns__column { flex: 1; /* Space between columns */ margin: 0 8px; /* Layout each column */ display: flex; flex-direction: column; } .same-height-columns__content { /* Take available height */ flex: 1; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .same-height-columns { display: flex; /* Demo */ width: 100%; height: 100%; } .same-height-columns__column { flex: 1; /* Space between columns */ margin: 0 0.25rem; /* Layout each column */ display: flex; flex-direction: column; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem; } .same-height-columns__content { /* Take available height */ flex: 1; } ``` ```html index.html hidden
```
================================================ FILE: contents/search-box.mdx ================================================ --- category: Input created: '2019-11-22' description: Create a search box with CSS flexbox keywords: css flexbox, css search box thumbnail: /assets/css-layout/thumbnails/search-box.png title: Search box --- ## HTML ```html index.html ``` ## CSS ```css styles.css .search-box { display: flex; /* If you want to place the icon before the text input */ flex-direction: row-reverse; /* Border */ border: 1px solid #d1d5db; } .search-box__input { border-color: transparent; /* Take available width */ flex: 1; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .search-box { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; align-items: center; /* Demo */ padding: 0.25rem; width: 16rem; } .search-box__input { border-color: transparent; /* Take available width */ flex: 1; height: 2rem; margin-right: 0.25rem; /* Demo */ width: 6rem; } ``` ```html index.html hidden ``` ================================================ FILE: contents/separator.mdx ================================================ --- category: Display created: '2019-11-21' description: Create a separator with CSS flexbox keywords: css divider, css flexbox, css separator thumbnail: /assets/css-layout/thumbnails/separator.png title: Separator --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .separator { /* Content is centered horizontally */ align-items: center; display: flex; /* Used to set the position of text */ position: relative; } .separator__content { /* We won't see the separator line */ background: #fff; /* Displayed at the center of separator */ left: 50%; position: absolute; top: 50%; transform: translate(-50%, -50%); /* Spacing */ padding: 0 0.25rem; /* Demo */ width: 60%; } .separator__separator { border-bottom: 1px solid #d1d5db; height: 1px; width: 100%; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .separator { /* Content is centered horizontally */ align-items: center; display: flex; /* Used to set the position of text */ position: relative; /* Demo */ width: 20rem; } .separator__content { /* We won't see the separator line */ background: #fff; /* Displayed at the center of separator */ left: 50%; position: absolute; top: 50%; transform: translate(-50%, -50%); /* Spacing */ padding: 0 0.25rem; /* Demo */ width: 60%; } .separator__separator { border-bottom: 1px solid #d1d5db; height: 1px; width: 100%; } ``` ```html index.html hidden
```
================================================ FILE: contents/sidebar.mdx ================================================ --- category: Layout created: '2019-11-16' description: Create a sidebar with CSS flexbox keywords: css flexbox, css layout, css sidebar thumbnail: /assets/css-layout/thumbnails/sidebar.png title: Sidebar --- ## HTML ```html index.html ``` ## CSS ```css styles.css .sidebar { display: flex; } .sidebar__sidebar { width: 30%; } .sidebar__main { /* Take the remaining width */ flex: 1; /* Make it scrollable */ overflow: auto; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .sidebar { display: flex; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; } .sidebar__sidebar { border-right: 1px solid #d1d5db; width: 30%; /* Demo */ display: flex; flex-direction: column; justify-content: flex-end; } .sidebar__main { /* Take the remaining width */ flex: 1; /* Make it scrollable */ overflow: auto; } ``` ```html index.html hidden ``` ================================================ FILE: contents/simple-grid.mdx ================================================ --- category: Layout created: '2019-11-22' description: Create a simple grid with CSS flexbox keywords: css flexbox, css flexbox grid, css grid, css layout thumbnail: /assets/css-layout/thumbnails/simple-grid.png title: Simple grid --- ## HTML ```html index.html
25%
...
``` ## CSS ```css styles.css .simple-grid { display: flex; margin-left: -0.25rem; margin-right: -0.25rem; } .simple-grid__cell { padding-left: 0.25rem; padding-right: 0.25rem; } .simple-grid__cell--fill { flex: 1; } /* Cell with given width */ .simple-grid__cell--1\/2 { flex: 0 0 50%; } .simple-grid__cell--1\/3 { flex: 0 0 33.3333333%; } .simple-grid__cell--1\/4 { flex: 0 0 25%; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden .simple-grid { display: flex; margin-left: -0.25rem; margin-right: -0.25rem; /* Demo */ margin-bottom: 0.25em; margin-top: 0.25em; height: 4rem; width: 100%; } .simple-grid__cell { padding-left: 0.25rem; padding-right: 0.25rem; } /* Cell with given width */ .simple-grid__cell--1\/2 { flex: 0 0 50%; } .simple-grid__cell--1\/3 { flex: 0 0 33.3333333%; } .simple-grid__cell--1\/4 { flex: 0 0 25%; } .simple-grid__cell--fill { flex: 1; } ``` ```html index.html hidden
```
================================================ FILE: contents/slider.mdx ================================================ --- category: Input created: '2019-11-17' description: Create a slider with CSS flexbox keywords: css flexbox, css slider thumbnail: /assets/css-layout/thumbnails/slider.png title: Slider --- ## HTML ```html index.html
``` ## CSS ```css styles.css .slider { /* Content is centered horizontally */ align-items: center; display: flex; /* Size */ height: 2rem; } .slider__left { height: 2px; /* Colors */ background-color: #d1d5db; } .slider__circle { /* Size */ height: 2rem; width: 2rem; /* Rounded border */ border-radius: 9999px; /* Colors */ background-color: #3b82f6; } .slider__right { /* Take the remaining width */ flex: 1; height: 2px; /* Colors */ background-color: #d1d5db; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .slider { /* Content is centered horizontally */ align-items: center; display: flex; /* Size */ height: 2rem; /* Demo */ width: 16rem; } .slider__left { height: 2px; /* Colors */ background-color: #d1d5db; } .slider__circle { /* Size */ height: 2rem; width: 2rem; /* Rounded border */ border-radius: 9999px; /* Colors */ background-color: #3b82f6; } .slider__right { /* Take the remaining width */ flex: 1; height: 2px; /* Colors */ background-color: #d1d5db; } ``` ```html index.html hidden
```
================================================ FILE: contents/speech-bubble.mdx ================================================ --- category: Display created: '2023-08-31' description: Create a speech bubble in CSS keywords: css speech bubble openGraphCover: /og/css-layout/speech-bubble.png thumbnail: /assets/css-layout/thumbnails/speech-bubble.png title: Speech bubble --- Speech bubbles are a popular and effective way to show dialogue or thoughts in a visual way. You've probably seen them in comics, cartoons, ads, and social media posts. They add humor, emotion, and personality to a design while also giving context to the viewer. Plus, speech bubble layouts can make text-heavy designs more engaging by breaking them up. In this post, we'll learn how to make a speech bubble layout using CSS. Let's get started! ## Markup You only need to provide one element to add the speed bubble effect. ```html
``` ## Adding a triangle To create a speech bubble, we can display a triangle at the bottom-left corner of the container. Rather than adding an external element to the container, we can create the triangle using the `::before` pseudo-element. Here's an example to help you visualize it: ```css .speech-bubble { position: relative; } .speech-bubble::before { content: ''; position: absolute; bottom: 0; left: -1rem; border-width: 1rem; border-style: solid; border-color: transparent transparent rgb(226 232 240) transparent; } ``` First, we set the `position` property of the container to `relative`. This allowed us to position the triangle using absolute positioning. But the real magic comes from the `::before` pseudo-element. We used the `content` property to add an empty string to this element. That may seem weird, but it's necessary because pseudo-elements require content to be displayed. To position the triangle where we wanted it, we used the `bottom` and `left` properties. By setting the `left` property to a negative value, we moved half of the triangle outside of the container. Finally, we created the triangle shape by setting the `border-color` property to transparent for the top, left, and right borders. This made the perfect triangle we were looking for. If you want to change the direction or position of the triangle, it's easy to do by following this [post](https://phuoc.ng/collection/css-layout/triangle-buttons/). Let's take a moment to review the progress we've made with these steps. ```css demo.css hidden .playground__root { align-items: center; display: flex; justify-content: center; height: 16rem; } ``` ```css :root { --speech-bubble-background: rgb(226 232 240); --speech-bubble-arrow-size: 1rem; } .speech-bubble { position: relative; background: var(--speech-bubble-background); border-radius: 0.25rem; height: 4rem; width: 12rem; } .speech-bubble::before { content: ''; position: absolute; bottom: 0; left: calc(-1 * var(--speech-bubble-arrow-size)); border-width: var(--speech-bubble-arrow-size); border-style: solid; border-color: transparent transparent var(--speech-bubble-background) transparent; } ``` ```html
```
## Using two pseudo-elements In the previous section, we used the `::before` pseudo-element to create a triangle. Now, let's take it a step further and create two circles using the `::before` and `::after` pseudo-elements. Take a look at the demo below to see how it looks: ```css demo.css hidden .playground__root { align-items: center; display: flex; justify-content: center; height: 16rem; } ``` ```css :root { --speech-bubble-background: rgb(226 232 240); } .speech-bubble { position: relative; background: var(--speech-bubble-background); border-radius: 9999px; height: 4rem; width: 12rem; } .speech-bubble::before, .speech-bubble::after { content: ''; position: absolute; bottom: 0; left: 0; border-radius: 9999px; background: var(--speech-bubble-background); } .speech-bubble::before { height: 1.5rem; width: 1.5rem; transform: translate(-0.5rem, 0.5rem); } .speech-bubble::after { height: 0.75rem; width: 0.75rem; transform: translate(-1rem, 1rem); } ``` ```html
```
To achieve this, we position both pseudo-elements absolutely at the bottom-left corner of the container, just like in the previous example. ```css .speech-bubble::before, .speech-bubble::after { content: ''; position: absolute; bottom: 0; left: 0; } ``` However, each of them is positioned differently by using the `transform` property. Let's take a closer look at the `transform` declaration for the `::before` pseudo-element. The first and second numbers move the element along the horizontal (X) and vertical (Y) axis, respectively. ```css .speech-bubble::before { transform: translate(-0.5rem, 0.5rem); } ``` ## See also - [Popover arrow](https://phuoc.ng/collection/css-layout/popover-arrow/) - [Typing indicator](https://phuoc.ng/collection/css-animation/typing-indicator/) - [Triangle buttons](https://phuoc.ng/collection/css-layout/triangle-buttons/) ================================================ FILE: contents/spin-button.mdx ================================================ --- category: Input created: '2019-11-25' description: Create a spin button with CSS flexbox keywords: css flexbox, css spin button thumbnail: /assets/css-layout/thumbnails/spin-button.png title: Spin button --- ## HTML ```html index.html
``` ## CSS ```css styles.css .spin-button { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; overflow: hidden; } .spin-button__input { border-color: transparent; padding: 0.5rem; /* Demo */ width: 8rem; } .spin-button__buttons { /* Content is centered vertically */ display: flex; flex-direction: column; justify-content: center; /* Left border */ border-left: 1px solid #d1d5db; } .spin-button__button { /* Reset */ background: #fff; border-color: transparent; cursor: pointer; /* Make buttons have the same height */ flex: 1; } ``` You can use the [triangle buttons](https://phuoc.ng/collection/css-layout/triangle-buttons/) to create the up and down buttons: ```css placeholders.css hidden .triangle { border-style: solid; height: 0; width: 0; } .triangle--t { border-color: transparent transparent #d1d5db transparent; border-width: 0 var(--triangle-size) var(--triangle-size) var(--triangle-size); } .triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 var(--triangle-size) 1rem; } .triangle--b { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 var(--triangle-size); } .triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: var(--triangle-size) 1rem var(--triangle-size) 0; } .triangle--tr { border-color: transparent #d1d5db transparent transparent; border-width: 0 var(--triangle-size) var(--triangle-size) 0; } .triangle--br { border-color: transparent transparent #d1d5db transparent; border-width: 0 0 var(--triangle-size) var(--triangle-size); } .triangle--bl { border-color: transparent transparent transparent #d1d5db; border-width: var(--triangle-size) 0 0 var(--triangle-size); } .triangle--tl { border-color: #d1d5db transparent transparent transparent; border-width: var(--triangle-size) var(--triangle-size) 0 0; } .triangle--sm { --triangle-size: 0.5rem; } .triangle--md { --triangle-size: 2rem; } .triangle--lg { --triangle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .spin-button { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; overflow: hidden; } .spin-button__input { border-color: transparent; padding: 0.5rem; /* Demo */ width: 8rem; } .spin-button__buttons { /* Content is centered vertically */ display: flex; flex-direction: column; justify-content: center; /* Left border */ border-left: 1px solid #d1d5db; } .spin-button__button { /* Reset */ background: #fff; border-color: transparent; cursor: pointer; /* Make buttons have the same height */ flex: 1; } ``` ```html index.html hidden
```
## See also - [Build a spin input](https://phuoc.ng/collection/html-dom/build-a-spin-input/) ================================================ FILE: contents/spinner.mdx ================================================ --- category: Feedback created: '2022-10-03' description: Create a loading spinner with CSS keywords: css loading spinner, css spinner thumbnail: /assets/css-layout/thumbnails/spinner.png title: Spinner --- ## HTML ```html index.html
``` ## CSS ```css styles.css .spinner { /* Size */ height: 4rem; width: 4rem; /* Create a curve at the top */ border: 4px solid #d1d5db; border-top-color: #3b82f6; border-radius: 50%; animation: spinner 800ms linear infinite; } @keyframes spinner { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .spinner { height: 4rem; width: 4rem; border: 4px solid #d1d5db; border-top-color: #3b82f6; border-radius: 50%; animation: spinner 800ms linear infinite; } @keyframes spinner { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } ``` ```html index.html hidden
```
## See also - [Indeterminate progress bar](https://phuoc.ng/collection/css-layout/indeterminate-progress-bar/) ================================================ FILE: contents/split-navigation.mdx ================================================ --- category: Navigation created: '2019-11-22' description: Create a split navigation with CSS flexbox keywords: css flexbox, css menu, css navigation, css split navigation thumbnail: /assets/css-layout/thumbnails/split-navigation.png title: Split navigation --- ## HTML ```html index.html ``` ## CSS ```css styles.css .split-navigation { /* Content is centered horizontally */ align-items: center; display: flex; /* Reset styles */ list-style-type: none; margin: 0; padding: 0 0 0.5rem 0; } .split-navigation__item { margin-right: 0.25rem; /* Demo */ width: 1.25rem; } .split-navigation__item--right { /* Sticks to the right */ margin-left: auto; margin-right: 0; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .split-navigation { /* Content is centered horizontally */ align-items: center; display: flex; /* Reset styles */ list-style-type: none; margin: 0; padding: 0 0 0.5rem 0; /* Demo */ border-bottom: 1px solid #d1d5db; width: 16rem; } .split-navigation__item { margin-right: 0.25rem; /* Demo */ width: 1.25rem; } .split-navigation__item--right { /* Sticks to the right */ margin-left: auto; margin-right: 0; } ``` ```html index.html hidden ``` ================================================ FILE: contents/split-screen.mdx ================================================ --- category: Layout created: '2019-11-17' description: Create a split screen with CSS flexbox keywords: css flexbox, css layout, css split screen thumbnail: /assets/css-layout/thumbnails/split-screen.png title: Split screen --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .split-screen { display: flex; } .split-screen__half { flex: 1; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .split-screen { display: flex; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; } .split-screen__half { flex: 1; /* Demo */ align-items: center; display: flex; justify-content: center; } .split-screen__half:first-child { border-right: 1px solid #d1d5db; } ``` ```html index.html hidden
```
================================================ FILE: contents/stacked-cards.mdx ================================================ --- category: Display created: '2019-12-25' description: Create stacked cards with CSS keywords: css card, css stacked cards, css transform rotate thumbnail: /assets/css-layout/thumbnails/stacked-cards.png title: Stacked cards --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .stacked-cards { /* Used to position the stacked cards */ position: relative; border: 1px solid #d1d5db; border-radius: 0.25rem; } .stacked-cards__card { /* Absolute position */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Displayed under the container */ z-index: 1; /* Background and border colors */ background-color: rgb(255, 255, 255); border: 1px solid #d1d5db; /* Rotate it. Change the number of degrees for the following cards */ transform: rotate(5deg); } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .stacked-cards { /* Used to position the stacked cards */ position: relative; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 16rem; width: 16rem; } .stacked-cards__card { /* Absolute position */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Displayed under the container */ z-index: 1; /* Background and border colors */ background-color: rgb(255, 255, 255); border: 1px solid #d1d5db; } .stacked-cards__card--1st { /* Rotate it. Change the number of degrees for the following cards */ transform: rotate(5deg); } .stacked-cards__card--2nd { /* Rotate it. Change the number of degrees for the following cards */ transform: rotate(10deg); } .stacked-cards__card--3rd { /* Rotate it. Change the number of degrees for the following cards */ transform: rotate(15deg); } ``` ```html index.html hidden
```
================================================ FILE: contents/stamp-border.mdx ================================================ --- category: Display created: '2020-01-16' description: Create stamp border with CSS keywords: css radial gradient, css stamp border thumbnail: /assets/css-layout/thumbnails/stamp-border.png title: Stamp border --- ## HTML ```html index.html
``` ## CSS ```css styles.css .stamp-border { /* Background */ background-color: #d1d5db; background-image: radial-gradient(#fff 50%, transparent 50%); background-position: -0.25rem -0.25rem; background-repeat: repeat; background-size: 0.5rem 0.5rem; /* Spacing */ padding: 0.25rem; } .stamp-border__content { /* Background */ background-color: #d1d5db; height: 100%; width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .stamp-border { /* Background */ background-color: #d1d5db; background-image: radial-gradient(#fff 50%, transparent 50%); background-position: -0.25rem -0.25rem; background-repeat: repeat; background-size: 0.5rem 0.5rem; /* Spacing */ padding: 0.25rem; /* Demo */ height: 100%; width: 100%; } .stamp-border__content { /* Background */ background-color: #d1d5db; height: 100%; width: 100%; } ``` ```html index.html hidden
```
================================================ FILE: contents/statistic.mdx ================================================ --- category: Display created: '2019-12-30' description: Create a statistic component with CSS flexbox keywords: css flexbox, css statistic thumbnail: /assets/css-layout/thumbnails/statistic.png title: Statistic --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .statistic { /* Center the content */ align-items: center; display: inline-flex; flex-direction: column; } .statistic__value { /* Big font size */ font-size: 4rem; font-weight: 500; } .statistic__label { /* Smaller font size */ font-size: 1rem; font-weight: 700; /* Uppercase the label */ text-transform: uppercase; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .statistic { /* Center the content */ align-items: center; display: inline-flex; flex-direction: column; } .statistic__value { /* Big font size */ font-size: 3rem; font-weight: 500; } .statistic__label { /* Smaller font size */ font-size: 1rem; font-weight: 700; /* Uppercase the label */ text-transform: uppercase; } ``` ```html index.html hidden
9k+
stars
```
================================================ FILE: contents/status-light.mdx ================================================ --- category: Display created: '2020-01-12' description: Create a status light with CSS flexbox keywords: css flexbox, css status light thumbnail: /assets/css-layout/thumbnails/status-light.png title: Status light --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .status-light { /* Center the content */ align-items: center; display: flex; } .status-light__status { /* Background color */ background-color: #16a34a; /* Rounded border */ border-radius: 9999px; /* Size */ height: 0.5rem; width: 0.5rem; /* Spacing */ margin-right: 0.5rem; } .status-light__content { /* Take available width */ flex: 1; } ``` ```css placeholders.css hidden .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .status-light { /* Center the content */ align-items: center; display: flex; /* Demo */ width: 8rem; } .status-light__status { /* Background color */ background-color: #16a34a; /* Rounded border */ border-radius: 9999px; /* Size */ height: 0.5rem; width: 0.5rem; /* Spacing */ margin-right: 0.5rem; } .status-light__content { /* Take available width */ flex: 1; } ``` ```html index.html hidden
```
================================================ FILE: contents/stepper-input.mdx ================================================ --- category: Input created: '2019-11-16' description: Create a stepper input with CSS flexbox keywords: css flexbox, css stepper input thumbnail: /assets/css-layout/thumbnails/stepper-input.png title: Stepper input --- ## HTML ```html index.html
``` ## CSS ```css styles.css .stepper-input { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; /* Size */ height: 2rem; } .stepper-input__button { /* Reset */ background: #d1d5db; border: none; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ width: 2rem; } .stepper-input__content { flex: 1; } .stepper-input__input { /* Reset */ border: none; /* Take full size of its container */ height: 100%; width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .stepper-input { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; /* Size */ height: 2rem; width: 16rem; } .stepper-input__button { /* Reset */ background: #d1d5db; border: none; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ width: 2rem; } .stepper-input__content { flex: 1; } .stepper-input__input { /* Reset */ border: none; /* Take full size of its container */ height: 100%; width: 100%; } ``` ```html index.html hidden
```
================================================ FILE: contents/sticky-footer.mdx ================================================ --- category: Layout created: '2019-11-15' description: Create a sticky footer with CSS flexbox keywords: css flexbox, css layout, css sticky, css sticky footer thumbnail: /assets/css-layout/thumbnails/sticky-footer.png title: Sticky footer --- ## HTML ```html index.html ``` ## CSS ```css styles.css .sticky-footer { display: flex; flex-direction: column; height: 100%; } .sticky-footer__header, .sticky-footer__footer { flex-shrink: 0; } .sticky-footer__main { flex-grow: 1; } ``` The footer always sticks to the bottom if the main content is short. ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .sticky-footer { display: flex; flex-direction: column; height: 100%; /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; width: 100%; } .sticky-footer__header, .sticky-footer__footer { flex-shrink: 0; /* Demo */ padding: 0.25rem; } .sticky-footer__main { flex-grow: 1; /* Demo */ border-top: 1px solid #d1d5db; border-bottom: 1px solid #d1d5db; padding: 0.25rem; } ``` ```html index.html hidden ``` ================================================ FILE: contents/sticky-header.mdx ================================================ --- category: Layout created: '2019-11-15' description: Create a sticky header with CSS keywords: css layout, css position sticky, css sticky header thumbnail: /assets/css-layout/thumbnails/sticky-header.png title: Sticky header --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .sticky-header__header { /* Stick to the top */ position: sticky; top: 0; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .sticky-header { /* Demo */ border: 1px solid #d1d5db; border-radius: 0.25rem; height: 100%; width: 100%; } .sticky-header__header { /* Stick to the top */ position: sticky; top: 0; /* Demo */ padding: 0.25rem; border-bottom: 1px solid #d1d5db; } ``` ```html index.html hidden ``` ================================================ FILE: contents/sticky-sections.mdx ================================================ --- category: Layout created: '2019-12-19' description: Create sticky sections with CSS keywords: css layout, css sticky, css sticky sections thumbnail: /assets/css-layout/thumbnails/sticky-sections.png title: Sticky sections --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .sticky-sections { height: 100%; overflow: scroll; } .sticky-sections__section { /* Take full size */ height: 100%; width: 100%; /* Stick to the top */ position: sticky; top: 0; } ``` ```css styles.css hidden .sticky-sections { height: 24rem; /* Demo */ width: 100%; } .sticky-sections__section { /* Take full size */ height: 25%; width: 100%; /* Stick to the top */ position: sticky; top: 0; } /* Demo */ .sticky-sections__section:nth-child(1) { background-color: #e5e7eb; } .sticky-sections__section:nth-child(2) { background-color: #d1d5db; } .sticky-sections__section:nth-child(3) { background-color: #9ca3af; } .sticky-sections__section:nth-child(4) { background-color: #6b7280; } ``` ```html index.html hidden
```
================================================ FILE: contents/sticky-table-column.mdx ================================================ --- category: Display created: '2019-12-29' description: Create sticky table column with CSS keywords: css position sticky, css sticky table column thumbnail: /assets/css-layout/thumbnails/sticky-table-column.png title: Sticky table column --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .sticky-table-headers__sticky { /* Background color */ background-color: #9ca3af; /* Stick to the left */ left: 0; position: sticky; /* Displayed on top of other rows when scrolling */ z-index: 9999; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .sticky-table-column { /* Demo */ border-collapse: collapse; width: 100%; } .sticky-table-column tbody { border-bottom: 1px solid #d1d5db; } .sticky-table-column tr { border-top: 1px solid #d1d5db; } .sticky-table-column__sticky { /* Background color */ background-color: #9ca3af; /* Stick to the left */ left: 0; position: sticky; /* Displayed on top of other rows when scrolling */ z-index: 9999; padding: 0 0.25rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/sticky-table-headers.mdx ================================================ --- category: Display created: '2019-12-26' description: Create sticky table headers with CSS keywords: css position sticky, css sticky table headers thumbnail: /assets/css-layout/thumbnails/sticky-table-headers.png title: Sticky table headers --- ## HTML ```html index.html ...
``` ## CSS ```css styles.css .sticky-table-headers__sticky { /* Background color */ background-color: #9ca3af; /* Stick to the left */ left: 0; position: sticky; /* Displayed on top of other rows when scrolling */ z-index: 9999; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden body { height: 24rem; } .sticky-table-headers { /* Demo */ border-collapse: collapse; width: 100%; } .sticky-table-headers tbody { border-bottom: 1px solid #d1d5db; } .sticky-table-headers thead td { padding: 0.25rem; } .sticky-table-headers tr { border-top: 1px solid #d1d5db; } .sticky-table-headers__sticky { /* Background color */ background-color: #9ca3af; /* Stick to the left */ left: 0; position: sticky; /* Displayed on top of other rows when scrolling */ z-index: 9999; } ``` ```html index.html hidden
```
================================================ FILE: contents/switch.mdx ================================================ --- category: Input created: '2019-11-17' description: Create a switch with CSS flexbox keywords: css custom checkbox, css flexbox, css switch, css switcher thumbnail: /assets/css-layout/thumbnails/switch.png title: Switch --- The checkbox is placed inside a label. So when clicking on the label, the checkbox will be checked even though it's hidden. ## HTML ```html index.html ``` ## CSS ```css styles.css .switch { display: flex; /* Rounded border */ border-radius: 9999px; /* Size */ height: 2rem; width: 4rem; /* Demo */ margin-bottom: 0.5rem; } .switch__input { /* Hide the input */ display: none; } .switch__circle { /* Rounded border */ border-radius: 9999px; /* Size */ width: 2rem; background-color: #fff; } ``` The switch comes with two variants: ```css /* ON status */ .switch--on { background-color: #357edd; border: 1px solid #357edd; /* Push the circle to the right */ justify-content: flex-end; } /* OFF status */ .switch--off { background-color: #d1d5db; border: 1px solid #d1d5db; } .switch--off .switch__circle { border: 1px solid #d1d5db; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .switch { display: flex; /* Rounded border */ border-radius: 9999px; /* Size */ height: 2rem; width: 4rem; /* Demo */ margin-bottom: 0.5rem; } .switch__input { /* Hide the input */ display: none; } .switch__circle { /* Rounded border */ border-radius: 9999px; /* Size */ width: 2rem; background-color: #fff; } /* ON status */ .switch--on { background-color: #357edd; border: 1px solid #357edd; /* Push the circle to the right */ justify-content: flex-end; } /* OFF status */ .switch--off { background-color: #d1d5db; border: 1px solid #d1d5db; } .switch--off .switch__circle { border: 1px solid #d1d5db; } ``` ```html index.html hidden ``` ================================================ FILE: contents/tab.mdx ================================================ --- category: Navigation created: '2019-11-22' description: Create tabs with CSS flexbox keywords: css flexbox, css navigation, css tab thumbnail: /assets/css-layout/thumbnails/tab.png title: Tab --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .tab { /* Center the content */ align-items: center; display: flex; justify-content: center; } .tab__item { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; padding: 0.5rem 1rem; } .tab__item--active { /* Border */ border: 1px solid #d1d5db; /* Hide the bottom border */ border-bottom-color: transparent; /* Border radius */ border-top-left-radius: 2px; border-top-right-radius: 2px; } .tab__item--inactive { /* Has only the bottom border */ border-bottom: 1px solid #d1d5db; } ``` ```css placeholders.css hidden .circle { background: #d1d5db; border-radius: 9999px; height: var(--circle-size); width: var(--circle-size); } .circle--sm { --circle-size: 0.5rem; } .circle--md { --circle-size: 1.5rem; } .circle--lg { --circle-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .tab { /* Center the content */ align-items: center; display: flex; justify-content: center; } .tab__item { border-top-left-radius: 0.25rem; border-top-right-radius: 0.25rem; padding: 0.5rem 1rem; } .tab__item--active { /* Border */ border: 1px solid #d1d5db; /* Hide the bottom border */ border-bottom-color: transparent; /* Border radius */ border-top-left-radius: 2px; border-top-right-radius: 2px; } .tab__item--inactive { /* Has only the bottom border */ border-bottom: 1px solid #d1d5db; } ``` ```html index.html hidden
```
================================================ FILE: contents/teardrop.mdx ================================================ --- category: Display created: '2019-12-30' description: Create a teardrop with CSS keywords: css border radius, css teardrop, css water drop shape, css water droplet thumbnail: /assets/css-layout/thumbnails/teardrop.png title: Teardrop --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .teardrop { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Border */ border: 2px solid #d1d5db; border-radius: 0px 50% 50% 50%; /* Angle at the top */ transform: rotate(45deg); /* Size */ height: 4rem; width: 4rem; } .teardrop__content { transform: rotate(-45deg); } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .teardrop { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Border */ border: 2px solid #d1d5db; border-radius: 0px 50% 50% 50%; /* Angle at the top */ transform: rotate(45deg); /* Size */ height: 4rem; width: 4rem; } .teardrop__content { transform: rotate(-45deg); } ``` ```html index.html hidden
```
================================================ FILE: contents/three-dimensions-card.mdx ================================================ --- category: Display created: '2021-04-04' description: Create a 3D card with CSS keywords: css 3D card thumbnail: /assets/css-layout/thumbnails/three-dimensions-card.png title: Three dimensions card --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css :root { --three-dimensions-card-left-side-width: 1rem; } .three-dimensions-card { position: relative; } /* The left side */ .three-dimensions-card::before { background: #d1d5db; content: ''; /* Position */ top: var(--three-dimensions-card-left-side-width); left: 0px; position: absolute; transform: translate(-100%, 0) skewY(-45deg); transform-origin: left top; /* Size */ height: 100%; width: var(--three-dimensions-card-left-side-width); } /* The bottom side */ .three-dimensions-card::after { background: #d1d5db; content: ''; /* Position */ bottom: 0px; left: 0px; position: absolute; transform: translate(0, 100%) skewX(-45deg); transform-origin: left top; /* Size */ height: var(--three-dimensions-card-left-side-width); width: 100%; } ``` ```css styles.css hidden :root { --three-dimensions-card-left-side-width: 1rem; } body { align-items: center; display: flex; justify-content: center; } .three-dimensions-card { position: relative; /* Demo */ border: 1px solid #d1d5db; height: 6rem; width: 6rem; } /* The left side */ .three-dimensions-card::before { background: #d1d5db; content: ''; /* Position */ top: var(--three-dimensions-card-left-side-width); left: 0px; position: absolute; transform: translate(-100%, 0) skewY(-45deg); transform-origin: left top; /* Size */ height: 100%; width: var(--three-dimensions-card-left-side-width); } /* The bottom side */ .three-dimensions-card::after { background: #d1d5db; content: ''; /* Position */ bottom: 0px; left: 0px; position: absolute; transform: translate(0, 100%) skewX(-45deg); transform-origin: left top; /* Size */ height: var(--three-dimensions-card-left-side-width); width: 100%; } ``` ```html index.html hidden
```
================================================ FILE: contents/timeline.mdx ================================================ --- category: Display created: '2019-12-12' description: Create a timeline with CSS flexbox keywords: css flexbox, css timeline thumbnail: /assets/css-layout/thumbnails/timeline.png title: Timeline --- ## HTML ```html index.html
...
...
...
``` ## CSS ```css styles.css .timeline { /* Used to position the left vertical line */ position: relative; } .timeline__line { /* Border */ border-right: 2px solid #d1d5db; /* Positioned at the left */ left: 0.75rem; position: absolute; top: 0px; /* Take full height */ height: 100%; } .timeline__items { /* Reset styles */ list-style-type: none; margin: 0px; padding: 0px; } .timeline__item { margin-bottom: 8px; } .timeline__top { /* Center the content horizontally */ align-items: center; display: flex; } .timeline__circle { /* Rounded border */ background-color: #d1d5db; border-radius: 9999px; /* Size */ height: 1.5rem; width: 1.5rem; } .timeline__title { /* Take available width */ flex: 1; margin-left: 0.5rem; } .timeline__desc { /* Make it align with the title */ margin-left: 2rem; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } .rectangle { background: #d1d5db; border-radius: 0.25rem; height: var(--rectangle-height); width: var(--rectangle-width); } .rectangle--hor.rectangle--20 { --rectangle-width: 20%; } .rectangle--hor.rectangle--40 { --rectangle-width: 40%; } .rectangle--hor.rectangle--60 { --rectangle-width: 60%; } .rectangle--hor.rectangle--80 { --rectangle-width: 80%; } .rectangle--hor.rectangle--100 { --rectangle-width: 100%; } .rectangle--hor.rectangle--sm { --rectangle-height: 0.5rem; } .rectangle--hor.rectangle--md { --rectangle-height: 2rem; } .rectangle--hor.rectangle--lg { --rectangle-height: 4rem; } .rectangle--ver.rectangle--20 { --rectangle-height: 20%; } .rectangle--ver.rectangle--40 { --rectangle-height: 40%; } .rectangle--ver.rectangle--60 { --rectangle-height: 60%; } .rectangle--ver.rectangle--80 { --rectangle-height: 80%; } .rectangle--ver.rectangle--100 { --rectangle-height: 100%; } .rectangle--ver.rectangle--sm { --rectangle-width: 0.5rem; } .rectangle--ver.rectangle--md { --rectangle-width: 2rem; } .rectangle--ver.rectangle--lg { --rectangle-width: 4rem; } ``` ```css styles.css hidden .timeline { /* Used to position the left vertical line */ position: relative; /* Demo */ height: 100%; width: 100%; } .timeline__line { /* Border */ border-right: 2px solid #d1d5db; /* Positioned at the left */ left: 0.75rem; position: absolute; top: 0px; /* Take full height */ height: 100%; } .timeline__items { /* Reset styles */ list-style-type: none; margin: 0px; padding: 0px; } .timeline__item { margin-bottom: 8px; } .timeline__top { /* Center the content horizontally */ align-items: center; display: flex; } .timeline__circle { /* Rounded border */ background-color: #d1d5db; border-radius: 9999px; /* Size */ height: 1.5rem; width: 1.5rem; } .timeline__title { /* Take available width */ flex: 1; margin-left: 0.5rem; } .timeline__desc { /* Make it align with the title */ margin-left: 2rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/toggle-password-visibility.mdx ================================================ --- category: Input created: '2019-11-23' description: Create a toggle password visibility with CSS flexbox keywords: css flexbox, toggle password visibility thumbnail: /assets/css-layout/thumbnails/toggle-password-visibility.png title: Toggle password visibility --- ## HTML ```html index.html
``` ## CSS ```css styles.css .toggle-password-visibility { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem; } .toggle-password-visibility__input { border-color: transparent; /* Take available width */ flex: 1; } .toggle-password-visibility__toggle { /* Reset */ background: #fff; border-color: transparent; /* Center the content */ display: flex; align-items: center; justify-content: center; } ``` In reality, the `click` event handler of the button needs to update the `type` attribute of the input to `text` or `password`: ```js document.querySelector('.toggle-password-visibility__toggle').addEventListener('click', (e) => { const input = e.target.previousElementSibling; const type = input.getAttribute('type'); input.setAttribute('type', type === 'text' ? 'password' : 'text'); }); ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .toggle-password-visibility { display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem; /* Demo */ height: 2.5rem; } .toggle-password-visibility__input { border-color: transparent; /* Take available width */ flex: 1; /* Demo */ width: 16rem; } .toggle-password-visibility__toggle { /* Reset */ background: #fff; border-color: transparent; /* Center the content */ display: flex; align-items: center; justify-content: center; } .toggle-password-visibility__svg { fill: none; height: 1.5rem; stroke: #d1d5db; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1; width: 1.5rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/tooltip.mdx ================================================ --- category: Feedback contributors: - arthur322 created: '2019-12-18' description: Create a tooltip with CSS keywords: css tooltip thumbnail: /assets/css-layout/thumbnails/tooltip.png title: Tooltip updated: '2021-10-01' --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .tooltip { /* Used to position the arrow */ position: relative; } /* Show the arrow and content and restore pointer events when hovering the trigger element */ .tooltip:hover .tooltip__arrow, .tooltip:hover .tooltip__content { opacity: 1; pointer-events: initial; } .tooltip__arrow { /* Invisible by default */ opacity: 0; /* To prevent accidental interactions with other elements */ pointer-events: none; /* Border */ border: 0.5rem solid transparent; border-top-color: #111827; /* Position */ bottom: 100%; left: 50%; position: absolute; transform: translate(-50%, 8px); /* Zero size */ height: 0; width: 0; /* Displayed on top of other element */ z-index: 10; } .tooltip__content { /* Invisible by default */ opacity: 0; /* To prevent accidental interactions with other elements */ pointer-events: none; /* Background color, must be the same as the border color of arrow */ background-color: #111827; border-radius: 0.25rem; /* Position */ bottom: 100%; left: 50%; position: absolute; transform: translate(-50%, -8px); /* Displayed on top of other element */ z-index: 10; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .tooltip { /* Used to position the arrow */ position: relative; /* Demo */ width: 8rem; height: 2rem; border-radius: 0.25rem; background: #d1d5db; } /* Show the arrow and content and restore pointer events when hovering the trigger element */ .tooltip:hover .tooltip__arrow, .tooltip:hover .tooltip__content { opacity: 1; pointer-events: initial; } .tooltip__arrow { /* Invisible by default */ opacity: 1; /* To prevent accidental interactions with other elements */ pointer-events: none; /* Border */ border: 0.5rem solid transparent; border-top-color: #111827; /* Position */ bottom: 100%; left: 50%; position: absolute; transform: translate(-50%, 8px); /* Zero size */ height: 0; width: 0; /* Displayed on top of other element */ z-index: 10; } .tooltip__content { /* Invisible by default */ opacity: 1; /* To prevent accidental interactions with other elements */ pointer-events: none; /* Background color, must be the same as the border color of arrow */ background-color: #111827; border-radius: 0.25rem; /* Position */ bottom: 100%; left: 50%; position: absolute; transform: translate(-50%, -8px); /* Displayed on top of other element */ z-index: 10; /* Demo */ width: 6rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/tree-diagram.mdx ================================================ --- category: Display created: '2021-04-03' description: Create a tree diagram with CSS keywords: css sitemap, css tree diagram thumbnail: /assets/css-layout/thumbnails/tree-diagram.png title: Tree diagram --- ## HTML ```html index.html
``` ## CSS ```css styles.css .tree-diagram ul { display: flex; position: relative; /* Reset */ list-style-type: none; margin: 0; padding: 1rem 0.5rem 0rem 0.5rem; } .tree-diagram ul ul::before { border-right: 1px solid #d1d5db; content: ''; /* Position */ position: absolute; top: 0; right: 50%; /* Size */ height: 1rem; width: 50%; } .tree-diagram li { padding: 1rem 0.5rem 0rem 0.5rem; position: relative; /* Center the content */ align-items: center; display: flex; flex-direction: column; } .tree-diagram li::before { border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; content: ''; /* Position */ position: absolute; top: 0; right: 50%; /* Size */ height: 1rem; width: 50%; } .tree-diagram li::after { border-top: 1px solid #d1d5db; content: ''; /* Position */ position: absolute; top: 0; right: 0; /* Size */ width: 50%; } .tree-diagram li:first-child::before, .tree-diagram li:last-child::after { /* Remove the top of border from the first and last items */ border-top: none; } /* Add a root item if you want */ li.tree-diagram__root::before { border-right: none; } ``` You can add a root item to the tree: ```html
``` ```css placeholders.css hidden .square { background: #d1d5db; height: var(--square-size); width: var(--square-size); } .square--sm { --square-size: 0.5rem; } .square--md { --square-size: 2rem; } .square--lg { --square-size: 4rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .tree-diagram ul { display: flex; position: relative; /* Reset */ list-style-type: none; margin: 0; padding: 1rem 0.5rem 0rem 0.5rem; } .tree-diagram ul ul::before { border-right: 1px solid #d1d5db; content: ''; /* Position */ position: absolute; top: 0; right: 50%; /* Size */ height: 1rem; width: 50%; } .tree-diagram li { padding: 1rem 0.5rem 0rem 0.5rem; position: relative; /* Center the content */ align-items: center; display: flex; flex-direction: column; } .tree-diagram li::before { border-right: 1px solid #d1d5db; border-top: 1px solid #d1d5db; content: ''; /* Position */ position: absolute; top: 0; right: 50%; /* Size */ height: 1rem; width: 50%; } .tree-diagram li::after { border-top: 1px solid #d1d5db; content: ''; /* Position */ position: absolute; top: 0; right: 0; /* Size */ width: 50%; } .tree-diagram li:first-child::before, .tree-diagram li:last-child::after { /* Remove the top of border from the first and last items */ border-top: none; } /* Add a root item if you want */ li.tree-diagram__root::before { border-right: none; } ``` ```html index.html hidden
```
================================================ FILE: contents/triangle-buttons.mdx ================================================ --- category: Display created: '2020-01-21' description: Create triangle buttons with CSS keywords: css triangle buttons thumbnail: /assets/css-layout/thumbnails/triangle-buttons.png title: Triangle buttons --- ## HTML ```html index.html ``` ## CSS ```css styles.css .triangle-buttons { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Spacing */ padding: 0.5rem; } .triangle-buttons__triangle { border-style: solid; /* Size */ height: 0px; width: 0px; } .triangle-buttons__triangle--t { border-color: transparent transparent #d1d5db; border-width: 0 0.5rem 0.5rem; } .triangle-buttons__triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: 0.5rem 0 0.5rem 0.5rem; } .triangle-buttons__triangle--b { border-color: #d1d5db transparent transparent; border-width: 0.5rem 0.5rem 0; } .triangle-buttons__triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: 0.5rem 0.5rem 0.5rem 0; } ``` ```css styles.css hidden body { height: 24rem; } .triangle-buttons__triangle { border-style: solid; /* Size */ height: 0; width: 0; } .triangle-buttons__triangle--t { border-color: transparent transparent #d1d5db; border-width: 0 0.5rem 0.5rem; } .triangle-buttons__triangle--r { border-color: transparent transparent transparent #d1d5db; border-width: 0.5rem 0 0.5rem 0.5rem; } .triangle-buttons__triangle--b { border-color: #d1d5db transparent transparent; border-width: 0.5rem 0.5rem 0; } .triangle-buttons__triangle--l { border-color: transparent #d1d5db transparent transparent; border-width: 0.5rem 0.5rem 0.5rem 0; } /* Demo */ .triangle-buttons { position: relative; height: 100%; width: 100%; } .triangle-buttons__corner { position: absolute; } .triangle-buttons__corner--t { left: 50%; top: 0; transform: translate(-50%, 0%); } .triangle-buttons__corner--r { right: 0; top: 50%; transform: translate(0%, -50%); } .triangle-buttons__corner--b { bottom: 0; left: 50%; transform: translate(-50%, 0%); } .triangle-buttons__corner--l { left: 0; top: 50%; transform: translate(0%, -50%); } ``` ```html index.html hidden
```
## See also - [Carousel slider](https://phuoc.ng/collection/css-layout/carousel-slider/) - [Popover arrow](https://phuoc.ng/collection/css-layout/popover-arrow/) - [Scroll down indicator](https://phuoc.ng/collection/css-animation/scroll-down-indicator/) - [Speech bubble](https://phuoc.ng/collection/css-layout/speech-bubble/) ================================================ FILE: contents/upload-button.mdx ================================================ --- category: Input created: '2019-11-29' description: Create an upload button with CSS flexbox keywords: css file input, css flexbox, css upload button thumbnail: /assets/css-layout/thumbnails/upload-button.png title: Upload button --- ## HTML ```html index.html
...
...
``` ## CSS ```css styles.css .upload-button { /* Used to position the input */ position: relative; /* Center the content */ align-items: center; display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem 0.5rem; } .upload-button__input { /* Take the full size */ height: 100%; left: 0; position: absolute; top: 0; width: 100%; /* Make it transparent */ opacity: 0; } .upload-button__icon { margin-right: 0.5rem; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .upload-button { /* Used to position the input */ position: relative; /* Center the content */ align-items: center; display: flex; /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; padding: 0.25rem 0.5rem; /* Demo */ width: 8rem; } .upload-button__input { /* Take the full size */ height: 100%; left: 0; position: absolute; top: 0; width: 100%; /* Make it transparent */ opacity: 0; } .upload-button__icon { margin-right: 0.5rem; } .upload-button__svg { fill: none; height: 1.5rem; stroke: #d1d5db; stroke-linecap: round; stroke-linejoin: round; stroke-width: 1; width: 1.5rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/validation-icon.mdx ================================================ --- category: Feedback created: '2019-12-12' description: Add validation icons to input with CSS keywords: css validation icon thumbnail: /assets/css-layout/thumbnails/validation-icon.png title: Validation icon --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .validation-icon { /* Used to position the validation icon */ position: relative; } .validation-icon__input { /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; /* Take the full width */ width: 100%; height: 2rem; /* Don't overlap the icon */ padding-right: 1.5rem; } .validation-icon__icon { /* Positioned at the right side */ position: absolute; right: 0.5rem; top: 50%; transform: translate(0, -50%); z-index: 10; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .validation-icon { /* Used to position the validation icon */ position: relative; /* Demo */ width: 16rem; } .validation-icon__input { /* Border */ border: 1px solid #d1d5db; border-radius: 0.25rem; /* Take the full width */ width: 100%; height: 2rem; /* Don't overlap the icon */ padding-right: 1.5rem; } .validation-icon__icon { /* Positioned at the right side */ position: absolute; right: 0.5rem; top: 50%; transform: translate(0, -50%); z-index: 10; } .validation-icon__svg { fill: none; height: 1rem; width: 1rem; stroke: #22c55e; stroke-linecap: round; stroke-linejoin: round; stroke-width: 2; } ``` ```html index.html hidden
```
================================================ FILE: contents/video-background.mdx ================================================ --- category: Display created: '2019-12-16' description: Add video background with CSS flexbox keywords: css flexbox, object fit cover thumbnail: /assets/css-layout/thumbnails/video-background.png title: Video background --- In this pattern, the video is displayed in the background. ## HTML ```html index.html
...
``` ## CSS ```css styles.css .video-background { /* Used to position the video and content */ position: relative; } .video-background__inner { /* Positioned at the top left corner */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Hide the scrollbar */ overflow: hidden; } .video-background__video { object-fit: cover; /* Take full width */ height: 100%; max-width: 100%; } .video-background__content { /* Positioned at the top left corner */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Center the content */ align-items: center; display: flex; flex-direction: column; justify-content: center; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .video-background { /* Used to position the video and content */ position: relative; height: 100%; width: 100%; } .video-background__inner { /* Positioned at the top left corner */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Hide the scrollbar */ overflow: hidden; } .video-background__video { object-fit: cover; /* Take full width */ height: 100%; max-width: 100%; } .video-background__content { /* Positioned at the top left corner */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; /* Center the content */ align-items: center; display: flex; flex-direction: column; justify-content: center; } ``` ```html index.html hidden
```
================================================ FILE: contents/voting.mdx ================================================ --- category: Display created: '2021-04-01' description: Create a voting control with CSS flexbox keywords: css flexbox, css triangle buttons, css voting control thumbnail: /assets/css-layout/thumbnails/voting.png title: Voting --- ## HTML ```html index.html
...
``` ## CSS ```css styles.css .voting { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; flex-direction: column; height: 8rem; } .voting__button { /* Reset */ background: none; border: none; cursor: pointer; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 1rem; /* Position the triangle */ position: relative; } .voting__triangle { border-style: solid; /* Size */ height: 0; width: 0; } .voting__triangle--up { border-color: transparent transparent #d1d5db; border-width: 0 0.5rem 0.5rem; } .voting__triangle--down { border-color: #d1d5db transparent transparent; border-width: 0.5rem 0.5rem 0px; } .voting__number { /* Take the available height */ flex: 1; /* Center the number */ align-items: center; display: flex; justify-content: center; /* Spacing */ padding: 0.25rem; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .voting { border: 1px solid #d1d5db; border-radius: 0.25rem; display: flex; flex-direction: column; height: 8rem; } .voting__button { /* Reset */ background: none; border: none; cursor: pointer; /* Center the content */ align-items: center; display: flex; justify-content: center; /* Size */ height: 1rem; /* Position the triangle */ position: relative; } .voting__triangle { border-style: solid; /* Size */ height: 0; width: 0; } .voting__triangle--up { border-color: transparent transparent #d1d5db; border-width: 0 0.5rem 0.5rem; } .voting__triangle--down { border-color: #d1d5db transparent transparent; border-width: 0.5rem 0.5rem 0px; } .voting__number { /* Take the available height */ flex: 1; /* Center the number */ align-items: center; display: flex; justify-content: center; /* Spacing */ padding: 0.25rem; } ``` ```html index.html hidden
999
```
================================================ FILE: contents/watermark.mdx ================================================ --- category: Display created: '2020-01-18' description: Create a watermark with CSS keywords: css watermark thumbnail: /assets/css-layout/thumbnails/watermark.png title: Watermark --- ## HTML ```html index.html
Draft
...
``` ## CSS ```css styles.css .watermark { /* Used to position the watermark */ position: relative; } .watermark__inner { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Absolute position */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; } .watermark__body { /* Text color */ color: rgba(0, 0, 0, 0.2); /* Text styles */ font-size: 3rem; font-weight: bold; text-transform: uppercase; /* Rotate the text */ transform: rotate(-45deg); /* Disable the selection */ user-select: none; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { height: 24rem; } .watermark { position: relative; /* Demo */ height: 100%; width: 100%; align-items: center; display: flex; flex-direction: column; justify-content: center; } .watermark__inner { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Absolute position */ left: 0px; position: absolute; top: 0px; /* Take full size */ height: 100%; width: 100%; } .watermark__body { /* Text color */ color: rgba(0, 0, 0, 0.2); /* Text styles */ font-size: 2rem; font-weight: bold; text-transform: uppercase; /* Rotate the text */ transform: rotate(-45deg); /* Disable the selection */ user-select: none; } ``` ```html index.html hidden
Draft
```
================================================ FILE: contents/wizard.mdx ================================================ --- category: Navigation created: '2019-11-22' description: Create a wizard with CSS flexbox keywords: css flexbox, css stepper, css wizard thumbnail: /assets/css-layout/thumbnails/wizard.png title: Wizard --- ## HTML ```html index.html
...
...
...
``` ## CSS ```css styles.css .wizard { display: flex; } .wizard__step { /* Make all steps have the same width */ flex: 1; } .wizard__dot { /* Center the content */ align-items: center; display: flex; justify-content: center; } .wizard__connector { flex: 1; height: 1px; background-color: #d1d5db; } .wizard__step:first-child .wizard__connector:first-child, .wizard__step:last-child .wizard__connector:last-child { background-color: transparent; } .wizard__number { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Rounded border */ background-color: #d1d5db; border-radius: 9999px; height: 2rem; width: 2rem; /* OPTIONAL: Spacing between it and connectors */ margin-left: 0.25rem; margin-right: 0.25rem; } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { align-items: center; display: flex; justify-content: center; } .wizard { align-items: center; display: flex; justify-content: center; width: 16rem; } .wizard__step { /* Make all steps have the same width */ flex: 1; } .wizard__dot { /* Center the content */ align-items: center; display: flex; justify-content: center; } .wizard__connector { flex: 1; height: 1px; background-color: #d1d5db; } .wizard__step:first-child .wizard__connector:first-child, .wizard__step:last-child .wizard__connector:last-child { background-color: transparent; } .wizard__number { /* Center the content */ align-items: center; display: flex; justify-content: center; /* Rounded border */ background-color: #d1d5db; border-radius: 9999px; height: 1rem; width: 1rem; } ``` ```html index.html hidden
```
================================================ FILE: contents/zebra-like-background.mdx ================================================ --- category: Display created: '2023-09-30' description: Create a zebra-like background with CSS openGraphCover: /og/css-layout/zebra-like-background.png thumbnail: /assets/css-layout/thumbnails/zebra-like-background.png title: Zebra-like background --- Using a zebra-like or striped design is a popular technique in web design to add visual interest and organization to data. This design involves alternating colors or shades in a horizontal pattern, like the stripes on a zebra. The zebra-like effect is commonly applied to tables, making it easier for users to read and compare data across rows. It can also be used in lists, forms, and other elements that contain multiple items. To apply a zebra-like background to a table, we use CSS to style the odd and even rows differently. By setting the `background-color` property of the odd rows to one color and the even rows to another color, we can create a striped effect that helps readers distinguish between rows. This technique is particularly useful for tables with lots of data, making it easier to scan through information. Here's a sample CSS code that can be used to create a zebra-like background for a table. ```css tr:nth-child(even) { background-color: #f2f2f2; } tr:nth-child(odd) { background-color: #ffffff; } ``` The `nth-child` selector is used to target every other row, and the `background-color` property is set to alternate between two colors. In this example, the even rows have a light gray color (`#f2f2f2`) while the odd rows are white (`#ffffff`). You can customize this code by changing the colors or adjusting the value of `nth-child` to achieve different effects. However, it's important to note that the `even` and `odd` selectors cannot be used for elements that don't have children, such as the `textarea` tag. In this post, we'll explore how to add a zebra-like background to any element. ## Creating a zebra-like background We can use the `repeating-linear-gradient` function to create a cool zebra-like background for any element. This function generates a linear gradient that repeats at defined intervals, allowing us to create a striped effect. Here's an example of how we can do it: ```css .container { --odd-background: rgb(203 213 225); --even-background: #fff; --line-height: 1.5rem; line-height: var(--line-height); background: repeating-linear-gradient( var(--odd-background), var(--odd-background) var(--line-height), var(--even-background) var(--line-height), var(--even-background) calc(2 * var(--line-height)) ); } ``` In this example, we used this technique to create a zebra-like background for a container element. We defined the CSS variables `--odd-background` and `--even-background` to set the colors for odd and even rows, respectively. We also set the `--line-height` variable to define the height of each row. It's important to make sure that the height of each row is the same as the `line-height` property of the element so that the rows align horizontally with each line of the element. The `repeating-linear-gradient` function is then used with these variables to generate a gradient that alternates between the two colors at every other line. The first argument specifies the direction of the gradient (in this case, it's vertical), while subsequent arguments define the color stops for each line. We can easily customize the background by adjusting these variables or adding additional color stops. Here's how it looks in action: ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } .container { border: 1px solid rgb(203 213 225); border-radius: 0.25rem; height: 12rem; width: 16rem; overflow: auto; padding: 0.5rem; } ``` ```css styles.css .container { --odd-background: rgb(203 213 225); --even-background: #fff; --line-height: 1.5rem; line-height: var(--line-height); background: repeating-linear-gradient( var(--odd-background), var(--odd-background) var(--line-height), var(--even-background) var(--line-height), var(--even-background) calc(2 * var(--line-height)) ); } ``` ```html index.html
```
It seems to work fine without any content, but let's add some content to our element. In reality, an element often has some space between its content and the sides, so let's add some padding to the element as well: ```css .container { padding: 0.5rem; } ``` Uh-oh, now we have an issue. The background areas are no longer aligned with each line of text. As you scroll up and down, the background stays in the same place and doesn't move along with the element. But don't worry, we'll fix these issues in the next section. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } .container { border: 1px solid rgb(203 213 225); border-radius: 0.25rem; height: 12rem; width: 16rem; overflow: auto; padding: 0.5rem; } ``` ```css styles.css hidden .container { --odd-background: rgb(203 213 225); --even-background: #fff; --line-height: 1.5rem; line-height: var(--line-height); background: repeating-linear-gradient( var(--odd-background), var(--odd-background) var(--line-height), var(--even-background) var(--line-height), var(--even-background) calc(2 * var(--line-height)) ); } ``` ```html index.html hidden
Very night his itself won't him morning dominion behold abundantly them above night. Good one whose moved over firmament. Seed heaven itself face. His living, which darkness and subdue fourth living good over, without made a moveth seas. To spirit very bring was it every seed. Behold blessed greater. Won't let earth very saying evening seas night subdue his you're spirit saying. Creepeth she'd had kind set place make. After behold fruitful open female. For without multiply itself you're. Meat creeping years after us unto grass over said itself light she'd, living. Void grass, yielding. Whose appear it i, darkness.
```
## Aligning the background with lines In the demo above, you may have noticed that the background of the element doesn't always align perfectly with each line. This can be frustrating, but don't worry! There's a simple solution using the `background-origin` property. By default, this property is set to `padding-box`, which means that the background starts at the edge of an element's padding. However, we can change this value to `content-box`, which will make the background start at the edge of an element's content. To fix this issue, simply add `background-origin: content-box;` to your CSS code for the `.container` class. This will ensure that the zebra-like background aligns perfectly with each line of text, giving your design a more polished and professional look. ```css .container { background-origin: content-box; } ``` ## Keeping the background in place while scrolling Let's make sure our zebra-like background doesn't move around as users scroll through our content. We can do this by using the `background-attachment` property. By default, this property is set to `scroll`, which means the background moves along with the content. However, if we change the value to `local`, the background will stay in place relative to its container element. Here's the sample code: ```css .container { background-attachment: local; } ``` Now, when we add `background-attachment: local;` to our `.container` class, the background will stay put as users scroll through the element's contents. This creates a smoother scrolling experience and helps maintain a consistent visual layout throughout. Let's take a look at the last example. ```css demo.css hidden body { align-items: center; display: flex; justify-content: center; } .container { border: 1px solid rgb(203 213 225); border-radius: 0.25rem; height: 12rem; width: 16rem; overflow: auto; padding: 0 0.5rem; } ``` ```css styles.css .container { --odd-background: rgb(203 213 225); --even-background: #fff; --line-height: 1.5rem; line-height: var(--line-height); background: repeating-linear-gradient( var(--odd-background), var(--odd-background) var(--line-height), var(--even-background) var(--line-height), var(--even-background) calc(2 * var(--line-height)) ); background-attachment: local; background-origin: content-box; } ``` ```html index.html
Very night his itself won't him morning dominion behold abundantly them above night. Good one whose moved over firmament. Seed heaven itself face. His living, which darkness and subdue fourth living good over, without made a moveth seas. To spirit very bring was it every seed. Behold blessed greater. Won't let earth very saying evening seas night subdue his you're spirit saying. Creepeth she'd had kind set place make. After behold fruitful open female. For without multiply itself you're. Meat creeping years after us unto grass over said itself light she'd, living. Void grass, yielding. Whose appear it i, darkness.
```
================================================ FILE: contents/zigzag-timeline.mdx ================================================ --- category: Display created: '2021-04-18' description: Create a zigzag timeline keywords: css timeline, css zigzag timeline thumbnail: /assets/css-layout/thumbnails/zigzag-timeline.png title: Zigzag timeline --- ## HTML ```html index.html
...
...
... ``` ## CSS ```css styles.css .zigzag-timeline__item { /* Used to position the milestone */ position: relative; /* Border */ border-bottom: 1px solid #9ca3af; /* Take full width */ width: 100%; } .zigzag-timeline__milestone { /* Absolute position */ position: absolute; top: 50%; /* Circle it */ border-radius: 50%; height: 1rem; width: 1rem; /* Misc */ background: #9ca3af; } /* Styles for even items */ .zigzag-timeline__item:nth-child(2n) { border-left: 1px solid #9ca3af; } .zigzag-timeline__item:nth-child(2n) .zigzag-timeline__milestone { left: 0; transform: translate(-50%, -50%); } /* Styles for odd items */ .zigzag-timeline__item:nth-child(2n + 1) { border-right: 1px solid #9ca3af; } .zigzag-timeline__item:nth-child(2n + 1) .zigzag-timeline__milestone { right: 0; transform: translate(50%, -50%); } ``` ```css placeholders.css hidden .lines { padding: 0.25rem 0; width: 100%; align-items: center; display: flex; justify-content: center; flex-direction: column; } .line { background: #d1d5db; height: 1px; margin-bottom: 0.25rem; } .line.line--20 { width: 20%; } .line.line--40 { width: 40%; } .line.line--60 { width: 60%; } .line.line--80 { width: 80%; } .line.line--100 { width: 100%; } ``` ```css styles.css hidden body { display: flex; align-items: center; justify-content: center; } .zigzag-timeline { width: 16rem; } .zigzag-timeline__item { /* Used to position the milestone */ position: relative; /* Border */ border-bottom: 1px solid #9ca3af; /* Take full width */ width: 100%; } .zigzag-timeline__milestone { /* Absolute position */ position: absolute; top: 50%; /* Circle it */ border-radius: 50%; height: 1rem; width: 1rem; /* Misc */ background: #9ca3af; } /* Styles for even items */ .zigzag-timeline__item:nth-child(2n) { border-left: 1px solid #9ca3af; } .zigzag-timeline__item:nth-child(2n) .zigzag-timeline__milestone { left: 0; transform: translate(-50%, -50%); } /* Styles for odd items */ .zigzag-timeline__item:nth-child(2n + 1) { border-right: 1px solid #9ca3af; } .zigzag-timeline__item:nth-child(2n + 1) .zigzag-timeline__milestone { right: 0; transform: translate(50%, -50%); } ``` ```html index.html hidden
```