I learned that tailwind animations are pretty easy to add only needing a few
classes. For some reason though my brain broke, thinking that I could
dynamically change the number and you can’t cause there are only so many pre
compiled classes without using an arbitrary value with brackets.
Here are the classes that I used to transition my colors very slowly.
<div id="square"
class="transition-colors ease-in-out duration-700">
</div>
And the entire square element.
<div id="square"
class="w-16 h-16 bg-rose-500 rounded border border-4 border-rose-800 hover:bg-indigo-600 hover:border-yellow-500 transition-colors ease-in-out duration-700">
</div>
Posts tagged: dev
All posts with the tag "dev"
297 posts
latest post 2026-05-23
Publishing rhythm
I learned not to fear the arbitrary size feature of tailwind. While building
out reader.waylonwalker.com [1] I kept getting
content flowing off the screen, and struggling to keep it on the screen. I
really felt that I should be able to do this with vanilla tailwind, but after
some encouragement from Twitter I decided to lean on arbitrary values and it
worked.
Don’t fear the arbitrary values.
<li class="max-w-[100vw]">
</li>
Learn more about using-arbitrary-values from their docs
docs [2]
References:
[1]: https://reader.waylonwalker.com
[2]: https://tailwindcss.com/docs/adding-custom-styles#using-arbitrary-values
Each time I go to set up npm I am frustrated by the errors saying that I don’t
have permission to npm i -g <package>, and it’s frustrating. And I forget
what I need to do to tell npm to install packages in a directory I own, and my
shell to look there so that I can use the executables.
mkdir ~/.npm-global
export NPM_CONFIG_PREFIX=~/.npm-global
export PATH=$PATH:~/.npm-global/bin
For the fix to remain persistent you need to put these two lines in your shell
profile like ~/.bashrc or ~/.zshrc.
export NPM_CONFIG_PREFIX=~/.npm-global
export PATH=$PATH:~/.npm-global/bin
If you are designing a website in dark mode the scrollbars can be finicky to
match the theme. Here is a pretty sane default that looks nice without being
obnoxiously contrast to the rest of the site.
<style>
::-webkit-scrollbar {
height: 1rem;
width: 1rem;
}
::-webkit-scrollbar-track {
background-color: rgb(24 24 27);
}
body::-webkit-scrollbar-track {
background-color: rgb(39 39 42);
}
::-webkit-scrollbar-thumb {
background-color: rgb(82 82 91);
}
::-webkit-scrollbar-thumb:hover {
background-color: rgb(113 113 122);
}
body::-webkit-scrollbar-thumb {
background-color: rgb(82 82 91);
}
body::-webkit-scrollbar-thumb:hover {
background-color: rgb(113 113 122);
}
::-webkit-scrollbar-corner {
background-color: rgb(39 39 42);
}
</style>
Want a rounded scrollbar thumb? add these styles.
::-webkit-scrollbar-thumb {
border-radius: 0.25rem;
border-radius: 9999px;
}
body::-webkit-scrollbar-thumb {
border-radius: 0.25rem;
border-radius: 9999px;
}
This makes a very nice looking default darkmode scrollbar.
External Link
stackoverflow.com [1]
Its sad that this is not the accepted answer.
mkdir ~/.npm-global
export NPM_CONFIG_PREFIX=~/.npm-global
export PATH=$PATH:~/.npm-global/bin
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://stackoverflow.com/questions/16151018/how-to-fix-npm-throwing-error-without-sudo#answer-41395398
[2]: /thoughts/
External Link
stackoverflow.com [1]
This is how you fix the stupid corner section of a double scroll bar being white on a dark theme site.
::-webkit-scrollbar-corner {
background: rgba(0,0,0,0);
}
The question included an example image where you can see white squares everywhere there are horizontal and vertical scroll bars.
[2]
Note
This post is a thought [3]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://stackoverflow.com/questions/35968553/webkit-scrollbar-css-always-a-white-box-in-corner
[2]: https://i.stack.imgur.com/P6b7f.png
[3]: /thoughts/
-
This is an interesting problem. I want to make a solution for this on htmx [1]-patterns. I would make user specific routes with an hx-get rather than serving the whole page, serve a partial with hx-oobs to fill in user specific data with a no cache on the cdn level.
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /htmx/
[2]: /thoughts/
-
So cool to see ROX build this over the course of a day.
Note
This post is a thought [1]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /thoughts/
jinja has a loop variable that is very handy to use with htmx [1]. Whether you
want to implement a click to load more or an infinite scroll this loop variable
is very handy.
{% for person in persons %}
<li
{% if loop.last %}
hx-get="{{ url_for('infinite', page=next_page) }}"
hx-trigger="intersect once"
hx-target="#persons"
hx-swap='beforeend'
hx-indicator="#persons-loading"
{% endif %}
{{ person.name.upper() }} -
{{ person.phone_number }}
</li>
{% endfor %}
Now for every chunk of contacts that we load we will trigger the infinite
scroll by loading more once the last one has intersected the screen.
References:
[1]: /htmx/
-
Great episode covering a seemingly simple topic. What I really benefitted from was hearing all the different use cases, from logging, debugging, to a/b testing, caching, and auth. I hadn’t even thought of it being applied to a router. I thought of it being applied for an entire application. This seems very useful for things like an admin router, all routes would need to have the admin role to get in.
Note
This post is a thought [1]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /thoughts/
![[None]]
I’ve been using these decorators to modify the behavior of specific routes. It will do things like 404 admin only routes in a way that looks just like fastapi [1]’s default, or only allow certain roles into the route, or redirect unauthenticated users to login.
After listening to yesterday’s syntaxfm I’m now really thinking about middleware and the benefits it might have. middleware would make it easy to apply things like admin to an entire admin router, so you wont forget it on any one admin route. It will look cleaner as the admin checker is only applied once per router, not once per route.
import inspect
import time
from functools import wraps
from inspect import signature
from fastapi import Request
from fastapi.responses import FileResponse, JSONResponse, RedirectResponse
from starlette import status
from fokais.config import get_config
from fokais.models.user import Role
config = get_config()
admin_routes = []
authenticated_routes = []
not_cached_routes = []
cached_routes = []
def not_found(request):
hx_request_header = request.headers.get("hx-request")
user_agent = request.headers.get("user-agent", "").lower()
if "mozilla" in user_agent or "webkit" i...
External Link
X (formerly Twitter) · twitter.com [1]
Huh, so this is just built right into the chrome cli.
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--headless \
--screenshot=/tmp/shot1.png \
https://simonwillison.net
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://twitter.com/simonw/status/1772043579231445366
[2]: /thoughts/
![[None]]
jinja’s url_for in fastapi [1] does not account for https by default, there is
probably a better way, but this is a way that allows me to configure when I use
http vs https.
@pass_context
def https_url_for(context: dict, name: str, **path_params: Any) -> str:
"""
always convert http to https
"""
request = context["request"]
http_url = request.url_for(name, **path_params)
return str(http_url).replace("http", "https", 1)
def get_templates(config: BaseSettings) -> Jinja2Templates:
templates = Jinja2Templates(directory="templates")
templates.env.globals["https_url_for"] = https_url_for
## only use the default url_for for local development, for dev, qa, and prod use https
if os.environ.get("ENV") in ["dev", "qa", "prod"]:
templates.env.globals["url_for"] = https_url_for
console.print("Using HTTPS")
else:
console.print("Using HTTP")
return templates
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /fastapi/
[2]: /thoughts/
![[None]]
import logging
from typing import List
import strawberry
from fastapi import FastAPI
from strawberry.fastapi import GraphQLRouter
logger = logging.getLogger(__name__)
authors = {}
books = {}
book_authors = {}
authors_books = {}
def get_author_for_book(root) -> "Author":
return authors[book_authors[root.id]]
@strawberry.type
class Book:
id: int
title: str
author: "Author" = strawberry.field(resolver=get_author_for_book)
def get_books_for_author(root) -> List[Book]:
print(f"getting books for {root}")
return [books[i] for i in authors_books[root.id]]
@strawberry.type
class Author:
id: int
name: str
books: List[Book] = strawberry.field(resolver=get_books_for_author)
authors = {1: Author(id=1, name="Michael Crichton")}
books = {1: Book(id=1, title="Jurassic Park")}
# relationships
book_authors[1] = 1
authors_books[1] = [1]
def get_author_by_id(id: int) -> Author:
return authors.get(id)
def get_book_by_id(id: int) -> Book:
return books.get(id)
def get_authors(root) -> List[Author]:
return authors.values()
def get_books(root) -> List[Book]:
print(books)
print(authors)
print(book_authors)
print(authors_books)
return books.values()
@strawberry.typ...
605: Jim Nielsen on Subversive URLs, Blogging + AI, and Design Engineers
Jim Nielsen joins us to about URLs and linking as the new subversive way to maintain the web, paying for news in Canada, should content creators be worried about AI, the case for design engineers, …
ShopTalk · shoptalkshow.com [1]
An absolute fantastic episode about blogging, thinking about a web1.0 kind of world today, and what it means moving forward.
Web 1.0 is robust, you own your own destiny, you own your data, you can do what you want. There is no platform to tell you what you can and cannot do. But the future web is stealing your data to build AI models, spam sites are duplicating your content and stealing your SEO. You may or may not care, but at the end whether you get traffic or now you own your web 1.0 sites.
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://shoptalkshow.com/605/
[2]: /thoughts/
Placehold
Placehold is a simple, fast and free image placeholder service to generate SVG, PNG, JPEG, GIF, WebP and AVIF placeholder images for your project.
placehold.co [1]
This is a handy placeholder generator for generating placeholder items like images, and videos.
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://placehold.co/
[2]: /thoughts/
tailwind and markdown
This post is a bit of an experiment to see what I can do. Lets start with a
block of pink text. I build my blog with my own static site generator called markata [1]
Setup Tailwind for Jinja [2]
Still Loving Tailwind [3]
{.text-pink-500}
This text should be pink
This text should be not pink
---
This text should be pink
This text should be not pink
---
Now will it work with bulleted lists
{.text-pink-500}
This block will be pink
{.text-pink-500}
* Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim
* labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi
* anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est
This block will not be pink.
* Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim
* labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi
* anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est
---
- Lorem ipsum dol...
-
Great take on low code. I have definitely felt the pressure of being presented low code options, “look it does almost everything you need, and you can do it without code.” Granted there are tons of great low code environments that serve their markets well (things like zapier).
As pointed out here when they fall short rather than being hard, it goes to nearly impossible. As Theo points out here many applications follow an 80/20 rule. 80% of the app is really easy to put together, and takes about 20% of the time, probably less. What no code does is it takes that 80% that is already easy, makes it even easier ( pitches it as faster whether or not that is true ), and makes the last 20% of the project impossibly hard to create and maintain, so you just should have picked a tool that had the capability of doing the whole thing from the start anyways.
Note
This post is a thought [1]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: /thoughts/
Template Designer Documentation — Jinja Documentation (3.1.x)
jinja.palletsprojects.com [1]
html [2] code generated by my jinja templates generally look half garbage because of indents and whitespace all over the place. I just learned about these pesky Whitespace Control characters that can get rid of the whitespace added from templating.
You can also strip whitespace in templates by hand. If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed:
{% for item in seq -%}
{{ item }}
{%- endfor %}
Note
This post is a thought [3]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://jinja.palletsprojects.com/en/3.0.x/templates/#whitespace-control
[2]: /html/
[3]: /thoughts/
bunny.net - The Global Edge Platform that truly Hops
Hop on bunny.net and speed up your web presence with the next-generation Content Delivery Service (CDN), Edge Storage, and Optimization Services at any scale.
bunny.net · bunny.net [1]
bunny.net looks like an interesting cloudflare alternative.
Note
This post is a thought [2]. It’s a short note that I make
about someone else’s content online #thoughts
References:
[1]: https://bunny.net/
[2]: /thoughts/