CSS Tricks
CSS line with text in the middle
h4 {
display: flex;
flex-direction: row;
color: #c8cfce;
}
h4:before, h4:after{
content: "";
flex: 1 1;
border-bottom: 1px solid;
margin: auto;
}
h4:before {
margin-right: 10px
}
h4:after {
margin-left: 10px
}
<h4>or</h4>
CSS no draggable or select
<img
class="no-select"
draggable="false"/>
.noselect {
user-select: none; /* Standard syntax */
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
}
Disable Button with CSS
<div class="visible-form">
<input type="email"
value="{{ .LoginForm.Email }}"
required
placeholder="Email"
class="form-control"
autofocus="autofocus"
name="email"
id="email">
<label for="email">Email</label>
{{ if .LoginForm.PasswordFieldEnabled }}
<input required
autocomplete="off"
placeholder="Password"
class="form-control"
type="password"
name="password"
id="password">
<label for="password">Password</label>
{{ end }}
<br>
<input type="submit"
hx-post="/login"
hx-target="{{ if .LoginForm.PasswordFieldEnabled }}#toast-container{{ else }}.form-container{{ end }}"
hx-swap="outerHTML"
name="commit"
value="Log in"
class="button btn-login"
id="submit-button"
target="_parent"
data-disable-with="Log in">
</div>
input:invalid ~ #submit-button {
background-color: #d7d7d7;
color: #a9a9a9;
cursor: not-allowed;
pointer-events: none;
box-sizing: border-box;
}
Turn two icons into a checkbox
<label for="password-visible">
{{ if .LoginForm.PasswordVisible }}
<img
id="eye"
class="fa-eye"
alt="hide password icon"
src="/static/images/eye_close_v1.svg"
/>
{{ else }}
<img
id="eye"
class="fa-eye"
alt="hide password icon"
src="/static/images/eye_open_v1.svg"
/>
{{ end }}
</label>
<input name="password-visible"
id="password-visible"
type="checkbox"
hx-put="/login"
hx-target=".form-container"
hx-swap="morph:outerHTML"
hx-trigger="change"
{{ if .LoginForm.PasswordVisible }}checked{{ end }}>
{{ end }}
#password-visible {
display: none;
}
Using REM and EM effectively
When working on an element, you can set everything in that element with EM.
Then by setting the element font size with REM you can scale the whole element with just that value without messing up proportions.
Why hidden attribute fails sometimes
Reference
Flexbox inside table cells
Problem: Using display: flex (or inline-block, block, etc.) directly on a <td> breaks table layout.
Why: A <td> is display: table-cell by default. The table layout algorithm relies on cells having that role to compute column widths, row heights, and alignment. Changing the cell’s display makes it no longer a table cell, which can cause:
Incorrect column width (e.g. the “Actions” column not staying narrow)
Wrong row height or vertical alignment
Odd spacing or overflow
Solution: Keep the <td> as a table cell and put a wrapper inside it. Make the wrapper the flex container.
Example (see dashboard.tmpl):
<!-- ❌ Bad: flex on the cell -->
<td class="actions" style="display: flex; gap: 0.5rem;">
<button>Edit</button>
<button>Delete</button>
</td>
<!-- ✅ Good: flex on an inner wrapper -->
<td class="actions">
<div class="actions-inner" style="display: flex; gap: 0.5rem;">
<button>Edit</button>
<button>Delete</button>
</div>
</td>
The <td> stays display: table-cell; only the inner <div> is a flex container, so the table lays out correctly and the buttons still line up horizontally with a gap.
Apply red astrix with only css
label:has(+ input:required)::after,
label:has(+ select:required)::after {
content: " *";
color: red;
font-weight: bold;
}
Disable multiple form fields at once
Disabling Form Fields via
To disable all form inputs and buttons simultaneously using a boolean flag (e.g., .IsDisabled), wrap your form content in a element. This is the most efficient method as it automatically propagates the disabled state to all nested interactive elements.
Implementation Snippet
Why use this?
DRY (Don't Repeat Yourself): You only need one {{ if .IsDisabled }}disabled{{ end }} check instead of adding it to every single input, select, and button.
Native Browser Support: Browsers automatically prevent interaction and styling (graying out) for all elements inside a disabled fieldset.
Maintenance: Adding new fields to the form automatically inherits the disabled logic without extra code.
Note: Fields inside a disabled fieldset are not submitted with the form. If you need the data to be sent but not editable, consider using readonly for text inputs (though this does not work for or checkbox elements).
Masking so you can edit svg colors
<style>
.mask-icon {
width: 1.5rem;
height: 1.5rem;
background-color: green;
-webkit-mask-image: url("/static/check_circle_black_24dp.svg");
mask-image: url("/static/check_circle_black_24dp.svg");
mask-size: contain;
mask-repeat: no-repeat;
}
</style>
<div class="status-icon"></div>
Also works for anchor tags:
<a href="/status"><div class="status-icon"></div></a>
Also works for buttons:
<button class="status-icon"></button>
Make accordions auto-close when another is selected
The Modern CSS Way (The name attribute)
As of late 2023/early 2024, most modern browsers (Chrome 120+, Edge 120+, Safari 17.2+) support the name attribute on the element. This works exactly like radio buttons: giving multiple details elements the same name creates an "exclusive accordion."
Section 1
Content for section 1...
Section 2
Content for section 2...
Section 3
Content for section 3...
Setting perfect body min height so footer is placed correctly when not enough content to fill entire page
main {
min-height: calc(100% - (var(--nav-height) + (var(--footer-height))));
}
Page Clamping full width clamping
<style>
/* using main here assuming nav and footer element are not in main so they stay stretched across screen
main {
/* START SMALL, GROW TO 90% OF VIEW, STOP AT 80rem (1280px) */
width: clamp(20rem, 90%, 80rem);
margin-inline: auto;
}
</style>
Mobile scaling
Mandatory header needed to enable media queries on mobile. This is needed due to backward compatability reasons:
<meta name="viewport" content="width=device-width, initial-scale=1">
Media Queries
<script>
@media (max-width: 600px) {
.phone {
font-size: 1rem;
}
}
</script>
CSS-Only Modal (Method 1: :target)
This guide demonstrates how to create a functional modal window using only HTML and CSS, leveraging the :target pseudo-class.
How it Works
The :target pseudo-class represents a unique element (the target element) with an id matching the URL's fragment (the part of the URL starting with #).
Trigger : An <a> tag with href="#modal-id".
Modal Container : A <div> with id="modal-id".
CSS : The modal is hidden by default. When the URL contains #modal-id, the selector #modal-id:target is applied, making the modal visible.
Implementation
HTML
<!-- 1. The Trigger Button -->
<a href="#modal-demo" class="open-btn">Open Modal</a>
<!-- 2. The Modal Structure -->
<div id="modal-demo" class="modal-overlay">
<div class="modal-content">
<!-- 3. The Close Button (points to # to clear the target) -->
<a href="#" class="modal-overlay-close" aria-label="Close modal"></a>
<a href="#" class="close-btn">×</a>
<h2>CSS-Only Modal</h2>
<p>This modal is toggled using the :target pseudo-class. No JavaScript required!</p>
</div>
</div>
CSS
/* The Overlay (Hidden by default) */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
/* Hidden state */
display: none;
/* Centering the content */
align-items: center;
justify-content: center;
z-index: 1000;
}
.modal-overlay-close {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
/* THE MAGIC: Show the modal when its ID is in the URL fragment */
.modal-overlay:target {
display: flex;
}
/* Modal Box Styles */
.modal-content {
background: white;
padding: 2rem;
border-radius: 8px;
position: relative;
max-width: 500px;
width: 90%;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.2);
}
/* Close Button Styles */
.close-btn {
position: absolute;
top: 10px;
right: 15px;
text-decoration: none;
font-size: 1.5rem;
color: #333;
line-height: 1;
}
.close-btn:hover {
color: #ff0000;
}
/* Trigger Button Styles (Optional) */
.open-btn {
display: inline-block;
padding: 10px 20px;
background-color: #007bff;
color: white;
text-decoration: none;
border-radius: 5px;
}
Pros and Cons
Pros
Zero JavaScript : Works even if JS is disabled.
Linkable : You can share a URL (e.g., example.com/#modal-demo) and the modal will be open on page load.
Simple : Very little code to maintain.
Cons
Browser History : Every time you open/close the modal, it adds an entry to the browser's back/forward history.
Accessibility : Does not support "Escape to close" or "Focus trapping" out of the box.
Page Jump : If the page is long, clicking the close button (href="#") might jump the user back to the top of the page.
Add Text Content with Just css
<style>
.new::before {
content: "+";
}
</style>
<button type="button" class="new"></button>
Preload assets to warm cache
Keep in mind that you still need to reference the asset with the normal tag, the prefetch is just instructions to warm the cache
<!-- font -->
<link rel="prefetch" href="/fonts/inter.woff2">
<style>
@font-face {
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
}
</style>
<!-- css -->
<link rel="prefetch" href="/css/app.css">
<link rel="stylesheet" href="/css/app.css">
<!-- js -->
<link rel="prefetch" href="/js/app.js">
<script src="/js/app.js"></script>
<!-- image -->
<link rel="prefetch" href="/img/hero.webp">
<img src="/img/hero.webp" alt="">