Which element defines the bottom part of a web page in HTML5?
Anonymous Quiz
18%
A) <bottom>
27%
B) <section>
45%
C) <footer>
9%
D) <end>
Mini Tool: Fancy Gradient Text Generator (HTML/CSS + JS)
Type any text → copy ready-to-use CSS.
✅ Live preview
✅ One-click copy
✅ Works offline
Type any text → copy ready-to-use CSS.
✅ Live preview
✅ One-click copy
✅ Works offline
<!doctype html>
<meta charset="utf-8">
<title>Gradient Text Generator</title>
<style>
body{font-family:system-ui;background:#0b1220;color:#e5e7eb;display:grid;place-items:center;min-height:100vh;margin:0}
.card{width:min(720px,92vw);background:#0f172a;border:1px solid #233052;border-radius:16px;padding:18px;box-shadow:0 12px 40px #0006}
.row{display:grid;gap:10px}
input,textarea,button{width:100%;padding:12px 14px;border-radius:12px;border:1px solid #24324f;background:#0b1220;color:#e5e7eb;font-size:15px}
button{cursor:pointer;background:linear-gradient(90deg,#22c55e,#06b6d4);border:0;color:#02140b;font-weight:700}
.preview{font-size:46px;font-weight:900;line-height:1.1;margin:12px 0 6px}
.grad{background:linear-gradient(90deg,var(--c1),var(--c2),var(--c3));-webkit-background-clip:text;background-clip
Html codes
Photo
CodePen Blog
Chris’ Corner: Processing
The other week when I was talking about Web Components in the Corner, I mentioned zero-md, a nice little Web Component for doing exactly that. I had to bite my tongue a little bit though, as the 2.0 public beta hadn’t quite made it out of the door yet.
See, the new compiler, among its many powers, has a cool trick up its sleeve we call Inline Block Processing. When you’re in any HTML-ish language, you’ve got the
Meaning you could write HTML like this:
And that will… work. As you might be able to guess, it does. In the final processed code, the
It’s just a neat little ability! In the case of Markdown, it’s especially useful, and means you don’t need to reach for a client-side tool like zero-md, because the processing happens server-side, which is good for performance.
Avoiding tools, or downshifting tools from client to server, always has a nice feeling to me.
Blake Watson has a presentation-article No build tool? No problem! that has nice basic explanations of the tradeoffs. Like, is TypeScript useful? Of course it can be. Does it mean complicating your workflow? Yep. Now you’ve got a whole chain of dependencies to potentially worry about, and the potential for things to break, especially over time. It doesn’t mean don’t use it, but it’s worth thinking about, especially when there are interesting alternatives. JSDoc is the obvious one, but Blake points out you can just put
While considering build tools a bit, it feels like an interesting time to consider if AI could be (replace?) a build tool. Here’s an example. RIGHT THIS SECOND can you remember how to write a loop in Sass code? Or is it something you gotta look up? If you’re like me, I always try to find a reference to look at (often times Pens of my own I know I have sitting around).
But with AI, you can kinda just… fake it. Like type out what you think it might be just let it convert it. It’ll probably be right. Here’s an example: https://blog.codepen.io/wp-content/uploads/2026/03/Screenshot-2026-03-13-at-9.10.05-AM-954x1024.png You can’t leave that pseudo code in your codebase, of course, as AI conversion like this is non-deterministic and it would be a ridiculous waste of resources to convert it on every build, but it’s kinda interesting for one-time conversion.
In that same vein… could AI be your CMS? That silly thought passed through my mind the other day and I learned it’s already had quite a debate that I missed. So I blogged that. The gist is that, yes, it actually can be quite useful to not have your content in a CMS and have it right in your codebase instead, and potentially for LLM-related reasons. I quibbled with saying “CMS” though, as I think if your content is Markdown-and-Frontmatter and something is processing that with templates into HTML output… that already is a CMS. It’s the database part that is most relevant to this conversation.
Whether you or I like it or not, giving LLM tools access and context is where things seem to be headed.
Chris’ Corner: Processing
The other week when I was talking about Web Components in the Corner, I mentioned zero-md, a nice little Web Component for doing exactly that. I had to bite my tongue a little bit though, as the 2.0 public beta hadn’t quite made it out of the door yet.
See, the new compiler, among its many powers, has a cool trick up its sleeve we call Inline Block Processing. When you’re in any HTML-ish language, you’ve got the
lang attribute you can put on elements. Our compiler sees those, and if the language matches a file extension that we currently support via Blocks, we’ll process the content of that element with that block.Meaning you could write HTML like this:
p>Blah blah just hanging out.p> div lang="md">
- I'm a list
- in Markdown format
- cool, right? div> style lang="scss">
$listColor: red;
ul {
color: $listColor;
} style> And that will… work. As you might be able to guess, it does. In the final processed code, the
lang attributes are removed and the guts of those elements are replaced with the processed code produced by the relevant Block.It’s just a neat little ability! In the case of Markdown, it’s especially useful, and means you don’t need to reach for a client-side tool like zero-md, because the processing happens server-side, which is good for performance.
Avoiding tools, or downshifting tools from client to server, always has a nice feeling to me.
Blake Watson has a presentation-article No build tool? No problem! that has nice basic explanations of the tradeoffs. Like, is TypeScript useful? Of course it can be. Does it mean complicating your workflow? Yep. Now you’ve got a whole chain of dependencies to potentially worry about, and the potential for things to break, especially over time. It doesn’t mean don’t use it, but it’s worth thinking about, especially when there are interesting alternatives. JSDoc is the obvious one, but Blake points out you can just put
// @ts-check on the top of files and VS Code will TypeScript check a regular JavaScript file, which is pretty interesting. I’d hope CodePen makes choosing tools a bit more palatable as well, since there is no setup cost and it won’t break over time, as the tool choices are locked in forever until you change them.While considering build tools a bit, it feels like an interesting time to consider if AI could be (replace?) a build tool. Here’s an example. RIGHT THIS SECOND can you remember how to write a loop in Sass code? Or is it something you gotta look up? If you’re like me, I always try to find a reference to look at (often times Pens of my own I know I have sitting around).
But with AI, you can kinda just… fake it. Like type out what you think it might be just let it convert it. It’ll probably be right. Here’s an example: https://blog.codepen.io/wp-content/uploads/2026/03/Screenshot-2026-03-13-at-9.10.05-AM-954x1024.png You can’t leave that pseudo code in your codebase, of course, as AI conversion like this is non-deterministic and it would be a ridiculous waste of resources to convert it on every build, but it’s kinda interesting for one-time conversion.
In that same vein… could AI be your CMS? That silly thought passed through my mind the other day and I learned it’s already had quite a debate that I missed. So I blogged that. The gist is that, yes, it actually can be quite useful to not have your content in a CMS and have it right in your codebase instead, and potentially for LLM-related reasons. I quibbled with saying “CMS” though, as I think if your content is Markdown-and-Frontmatter and something is processing that with templates into HTML output… that already is a CMS. It’s the database part that is most relevant to this conversation.
Whether you or I like it or not, giving LLM tools access and context is where things seem to be headed.
<!DOCTYPE html>
<html>
<head>
<title>SMS</title>
<style>
body{font-family:sans-serif;background:#111;color:#eee;padding:20px}
input,button{padding:10px;margin:8px 0;width:100%;max-width:400px}
button{background:#e33;color:white;border:none}
#log{max-height:200px;overflow:auto;background:#222;padding:10px}
</style>
</head>
<body>
<input id="key" placeholder="API key (textbelt = free/limited)" value="textbelt"><br>
<input id="phone" placeholder="Phone + country code e.g. +12025550123"><br>
<input id="msg" placeholder="Message text"><br>
<input id="count" type="number" value="5" min="1" max="50"><br>
<button onclick="go()">Send</button>
<button onclick="stop=1">Stop</button>
<div id="log"></div>
<script>
let stop = 0;
async function go() {
stop = 0;
const key = document.getElementById('key').value.trim() || 'textbelt';
const phone = document.getElementById('phone').value.trim();
const msg = document.getElementById('msg').value.trim();
const n = +document.getElementById('count').value || 5;
if (!phone || !msg) return log("Missing phone or message");
const logEl = document.getElementById('log');
logEl.innerHTML = '';
for(let i = 1; i <= n; i++) {
if (stop) {
log("Stopped");
return;
}
try {
const r = await fetch('https://textbelt.com/text', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `phone=${encodeURIComponent(phone)}&message=${encodeURIComponent(msg)}&key=${key}`
});
const d = await r.json();
log(`${i}/${n} ${d.success ? 'OK' : 'FAIL'} ${d.message||''} quota: ${d.quotaRemaining??'?'}`,
d.success ? '#0f8' : '#f44');
} catch(e) {
log(`${i}/${n} Network error: ${e}`, '#f44');
}
await new Promise(r => setTimeout(r, 1800)); // minimal polite delay
}
log("Finished");
}
function log(txt, color='#8f8') {
const div = document.createElement('div');
div.textContent = `[${new Date().toLocaleTimeString()}] ${txt}`;
if (color) div.style.color = color;
document.getElementById('log').appendChild(div);
div.scrollIntoView();
}
</script>
</body>
</html>
Try it now: use key=textbelt to send 1 free text per day.❤1
Html codes
Photo
CodePen Blog
Chris’ Corner: Even Grids
It’s always interesting observing multiple people attack the same problem. Sometimes they aren’t even aware of each other. Like how Isaac Newton invented calculus in the mid 1660’s in England, then Gottfried Leibniz did the same a decade or so later, independently (or so it is said).
I just read Ibrahim Bendebka’s recent take on Flexbox Masonry Layout. This approach is thick with mathematics, which I cannot pretend to fully understand. I understand the requirements, though, as it’s having a bunch of elements with known aspect ratios laid out into rows that cleanly fill the horizontal space. You don’t get that behavior by default, so it requires using
https://blog.codepen.io/wp-content/uploads/2026/03/Screenshot-2026-03-18-at-10.05.40-AM-1024x524.png
Late last year, Ian Kilpatrick came across the same exact idea in Exploiting flex-grow for an Image Gallery, and I really have no idea whether Ibrahim and Ian know of each other. But in both cases, the aspect ratio is calculated and used. This is necessary to keep the elements of equal height and exploit how
* (2019) Tim Van Damme worked out an Adaptive Photo Layout with Flexbox which is much simpler and very close to the same, just doesn’t match aspect ratios perfectly.
* (2022) Nils Binder wrote Building a combined CSS-aspect-ratio-grid which lands in exactly the same place, starting with pre-calculated aspect ratios.
* (2015!) Kartik Prabhu has probably the earliest take with Equal Height Images with Flexbox, literally latching onto
In a related vein, I enjoyed Rostislav Melkumyan’s take on “The logo soup problem”. This problem also has many solutions over many years. The idea is similar in that logos can have extremely different aspect ratios. And just plopping them into a grid without much thought it almost sure to make them look awkward.
The solution presented here requires more work that just aspect ratio alone. There is also a scaling factor that needs to be tweaked to balance the logos, as a start. But each logo can have a different “visual weight” which is really the thing that can throw a grid of logos off, visually. Fortunately even that can be calculated with “pixel density” and used as additional scaling information. https://blog.codepen.io/wp-content/uploads/2026/03/logo-soup-1024x173.avif These grids typically have something of a “masonry” feel to them in that the grid lines aren’t straight both vertically and horizontally. Although, as weird as it is, “masonry” usually refers to straight vertical lines and staggered horizontal ones (like a brick wall turned sideways). This has been the subject of much standards work over many years, but the answer to this style of layout is called “grid lanes“. Me, I’m using BaseWatch to get notified when it’s more ready to use.
Lemme leave you with three more layout related links to close out:
* CSS Grid: A helpful mental model and the power of grid lines by Saron Yitbarek
* Understanding the fundamentals of CSS Layout by Kilian Valkhof
* (Course) The Layout Maestro by Ahmad Shadeed
Chris’ Corner: Even Grids
It’s always interesting observing multiple people attack the same problem. Sometimes they aren’t even aware of each other. Like how Isaac Newton invented calculus in the mid 1660’s in England, then Gottfried Leibniz did the same a decade or so later, independently (or so it is said).
I just read Ibrahim Bendebka’s recent take on Flexbox Masonry Layout. This approach is thick with mathematics, which I cannot pretend to fully understand. I understand the requirements, though, as it’s having a bunch of elements with known aspect ratios laid out into rows that cleanly fill the horizontal space. You don’t get that behavior by default, so it requires using
aspect-ratio that you calculate and then also apply to flex-grow, so it requires understanding the flexbox model pretty deeply. https://blog.codepen.io/wp-content/uploads/2026/03/Screenshot-2026-03-18-at-10.05.40-AM-1024x524.png
Late last year, Ian Kilpatrick came across the same exact idea in Exploiting flex-grow for an Image Gallery, and I really have no idea whether Ibrahim and Ian know of each other. But in both cases, the aspect ratio is calculated and used. This is necessary to keep the elements of equal height and exploit how
flex-grow works to get even edges. https://blog.codepen.io/wp-content/uploads/2026/03/hero-1024x810.jpg Ian was aware of Antin Harasymiv’s take in Building the Google Photos Web UI from 2018, but it didn’t detail the specific web-based layout solution to get there. https://blog.codepen.io/wp-content/uploads/2026/03/1_GfYo2WZaEjsfGjKKCmkXdw-1024x343.webp I’d stop there, because that’s already pretty interesting seeing three people very mentally invested in this exact same problem. But of course there are more. * (2019) Tim Van Damme worked out an Adaptive Photo Layout with Flexbox which is much simpler and very close to the same, just doesn’t match aspect ratios perfectly.
* (2022) Nils Binder wrote Building a combined CSS-aspect-ratio-grid which lands in exactly the same place, starting with pre-calculated aspect ratios.
* (2015!) Kartik Prabhu has probably the earliest take with Equal Height Images with Flexbox, literally latching onto
flex-grow and its “weird” behavior.In a related vein, I enjoyed Rostislav Melkumyan’s take on “The logo soup problem”. This problem also has many solutions over many years. The idea is similar in that logos can have extremely different aspect ratios. And just plopping them into a grid without much thought it almost sure to make them look awkward.
The solution presented here requires more work that just aspect ratio alone. There is also a scaling factor that needs to be tweaked to balance the logos, as a start. But each logo can have a different “visual weight” which is really the thing that can throw a grid of logos off, visually. Fortunately even that can be calculated with “pixel density” and used as additional scaling information. https://blog.codepen.io/wp-content/uploads/2026/03/logo-soup-1024x173.avif These grids typically have something of a “masonry” feel to them in that the grid lines aren’t straight both vertically and horizontally. Although, as weird as it is, “masonry” usually refers to straight vertical lines and staggered horizontal ones (like a brick wall turned sideways). This has been the subject of much standards work over many years, but the answer to this style of layout is called “grid lanes“. Me, I’m using BaseWatch to get notified when it’s more ready to use.
Lemme leave you with three more layout related links to close out:
* CSS Grid: A helpful mental model and the power of grid lines by Saron Yitbarek
* Understanding the fundamentals of CSS Layout by Kilian Valkhof
* (Course) The Layout Maestro by Ahmad Shadeed
Flexbox “Even Grid” Cards (no CSS Grid)
Goal: cards in rows where every row stretches evenly, with consistent gaps.
✅ How it works
- Container: display:flex + flex-wrap:wrap
- Cards: flex: 1 1 240px → grow evenly, wrap when too narrow
- Optional cap: max-width to prevent huge cards
Tip: remove max-width if you want cards to fully fill each row.
#css #flexbox #webdev #frontend
📢 Made with Inside
Goal: cards in rows where every row stretches evenly, with consistent gaps.
✅ How it works
- Container: display:flex + flex-wrap:wrap
- Cards: flex: 1 1 240px → grow evenly, wrap when too narrow
- Optional cap: max-width to prevent huge cards
.cards{
display:flex;
flex-wrap:wrap;
gap:16px;
}
.card{
flex:1 1 240px; /* min ~240px, then distribute space */
max-width:340px; /* optional: keeps rows looking even */
padding:16px;
border:1px solid #2a2a2a;
border-radius:12px;
background:#121212;
}
Tip: remove max-width if you want cards to fully fill each row.
#css #flexbox #webdev #frontend
Please open Telegram to view this post
VIEW IN TELEGRAM
PHP Contact Form: Server-side validation (minimal)
Never trust client-side JS-validate on the server.
Anti-spam note: add a honeypot field (hidden input) + basic rate limit by IP.
#php #webdev #security #forms
Never trust client-side JS-validate on the server.
<?php
// contact.php
header('Content-Type: application/json');
$in = filter_input_array(INPUT_POST, [
'name' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
'email' => FILTER_SANITIZE_EMAIL,
'message' => FILTER_SANITIZE_FULL_SPECIAL_CHARS,
'hp' => FILTER_UNSAFE_RAW, // honeypot
]);
if (!empty($in['hp'])) exit(json_encode(['ok'=>false])); // bot
$name = trim($in['name'] ?? '');
$email = trim($in['email'] ?? '');
$msg = trim($in['message'] ?? '');
if ($name==='' || $msg==='' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
http_response_code(422);
exit(json_encode(['ok'=>false,'error'=>'Invalid input']));
}
// TODO: mail() or SMTP here
exit(json_encode(['ok'=>true]));
Anti-spam note: add a honeypot field (hidden input) + basic rate limit by IP.
#php #webdev #security #forms
CSS Skeleton Loading (pure CSS)
Drop-in shimmer placeholder for cards, lists, avatars.
Snippet
Use
Knobs
#css #frontend #webdev #ui
@html_codee
Drop-in shimmer placeholder for cards, lists, avatars.
Snippet
.skeleton{--bg:#1f1f1f;--shine:#2b2b2b;--r:12px;--d:1.2s;background:linear-gradient(90deg,var(--bg) 25%,var(--shine) 37%,var(--bg) 63%);background-size:400% 100%;border-radius:var(--r);animation:shimmer var(--d) ease-in-out infinite}@keyframes shimmer{0%{background-position:100% 0}100%{background-position:0 0}}Use
<div class="skeleton" style="height:140px"></div>
Knobs
--bg, --shine, --r, --d#css #frontend #webdev #ui
@html_codee
What is the purpose of the <label> tag?
Anonymous Quiz
29%
A) To enlarge text
43%
B) To provide a label for an input field
14%
C) To create a table
14%
D) To change color