#cssChallenge2025 How would you code this with:

✨ 1 HTML element, no JS, no SVG
✨ inner border interrupted by text box shape
✨ responsive
✨ text wraps depending on space
✨ contenteditable
✨ 1 image = the background one

(if you're Cheetah+ on Ko-fi/ Patreon, you know where to find the answer)

#CSS #cssLayout #code #coding #frontend #web #dev #webDev #webDevelopment

Text that can wrap depending on available space in the bottom left corner of a card with padding. At the limit between the card's padding area and content area, there's an inner border interrupted in the bottom left corner by the text box. The text is contenteditable.
Text that can wrap depending on available space in the bottom left corner of a card with padding. At the limit between the card's padding area and content area, there's an inner border interrupted in the bottom left corner by the text box. The text is contenteditable.
#cssChallenge2025 How would you code this with:

✨ 1 HTML element, no JS, no SVG
✨ inner border interrupted by text box shape
✨ responsive
✨ text wraps depending on space
✨ contenteditable
✨ 1 image = the background one

(if you're Cheetah+ on Ko-fi/ Patreon, you know where to find the answer)

#CSS #cssLayout #code #coding #frontend #web #dev #webDev #webDevelopment

Text that can wrap depending on available space in the bottom left corner of a card with padding. At the limit between the card's padding area and content area, there's an inner border interrupted in the bottom left corner by the text box. The text is contenteditable.
Text that can wrap depending on available space in the bottom left corner of a card with padding. At the limit between the card's padding area and content area, there's an inner border interrupted in the bottom left corner by the text box. The text is contenteditable.

Here‘s a little tip if you’re using (the latest version of) Helix Editor:

Add the following keybinding to your config (if you don’t use Ctrl+b for page up, that is; otherwise, change the key):

[keys.normal]
C-b = ":echo %sh{git blame -L %{cursor_line},+1 %{buffer_name}}"

Now, when you press Crtl+b in the editor, you’ll see the git blame for the line you’re on. Very useful for seeing which commit the line last changed in and, for teams, who committed the change.

For more, see the highlights post for the latest release:
helix-editor.com/news/release-

Here‘s a little tip if you’re using (the latest version of) Helix Editor:

Add the following keybinding to your config (if you don’t use Ctrl+b for page up, that is; otherwise, change the key):

[keys.normal]
C-b = ":echo %sh{git blame -L %{cursor_line},+1 %{buffer_name}}"

Now, when you press Crtl+b in the editor, you’ll see the git blame for the line you’re on. Very useful for seeing which commit the line last changed in and, for teams, who committed the change.

For more, see the highlights post for the latest release:
helix-editor.com/news/release-

🥳 All tests passing!

(And real-world projects seem to be rendering perfectly – and faster than before to boot.) :)

If further testing doesn’t bring out any issues, expect a new Kitten release this week with the new (and far improved) Markdown parser.

kitten💕

#Kitten #SmallWeb #web #dev#Markdown

Coming soon (likely this afternoon, I’m writing tests and docs and updating examples as we speak)…

This is the sort of thing you’ll be able to do with Markdown pages. Just pop any arbitrary JavaScript you want in the new script block in the front matter and then import and use components as well as plain old JavaScript tagged template variable interpolation (not shown in this example) inside your Markdown.

The screen has all the code (sans the end of the last line of CSS and the closing tags for the

Screenshot: three windows: left side: Source of index.page.md, top-right browser showing running web app, bottom-right, source of Button and Reactions components.

Contents of windows:

index.page.md:

---
title: An interactive markdown page
script: |
  import Reaction from './Reaction.fragment.js'

  // Initialise database if necessary.
  kitten.db.reactions ??= {}
  kitten.db.reactions.Heart ??= 0
  kitten.db.reactions.Confetti ??= 0
  kitten.db.reactions.Smiley ??= 0

  let page

  export function onConnect (data) {
    page = data.page
  }

  export function onReaction (data) {
    kitten.db.reactions[data.type]++
    page.send(kitten.html`<${Reaction} />`)
  }
---
<page css>

# Hello!

While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block.

## Reactions{id=your-reactions}

<${Reaction} />

Browser (output):

Hello!
While this is a markdown page, I can easily layer interactivity by adding a simple component in a script block.

Reactions

Heart button: 5
Confetti button: 4
Smiley button: 3
Screenshot: three windows: left side: Source of index.page.md, top-right browser showing running web app, bottom-right, source of Button and Reactions components. Contents of windows: index.page.md: --- title: An interactive markdown page script: | import Reaction from './Reaction.fragment.js' // Initialise database if necessary. kitten.db.reactions ??= {} kitten.db.reactions.Heart ??= 0 kitten.db.reactions.Confetti ??= 0 kitten.db.reactions.Smiley ??= 0 let page export function onConnect (data) { page = data.page } export function onReaction (data) { kitten.db.reactions[data.type]++ page.send(kitten.html`<${Reaction} />`) } --- <page css> # Hello! While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block. ## Reactions{id=your-reactions} <${Reaction} /> Browser (output): Hello! While this is a markdown page, I can easily layer interactivity by adding a simple component in a script block. Reactions Heart button: 5 Confetti button: 4 Smiley button: 3

OK, so here’s likely the simplest possible example demonstrating:

• The same route, implemented as both a Kitten JavaScript Page (.page.js) and as a Kitten Markdown Page (.page.md)

• How to persist to the default Kitten JSDB¹ database.

(That first line with the nullish coalescing operator creates a “table” on the database with a default value for the count if it doesn’t already exist.)

kitten.small-web.org

¹ kitten.small-web.org/tutorials

Coming soon (likely this afternoon, I’m writing tests and docs and updating examples as we speak)…

This is the sort of thing you’ll be able to do with Markdown pages. Just pop any arbitrary JavaScript you want in the new script block in the front matter and then import and use components as well as plain old JavaScript tagged template variable interpolation (not shown in this example) inside your Markdown.

The screen has all the code (sans the end of the last line of CSS and the closing tags for the

Screenshot: three windows: left side: Source of index.page.md, top-right browser showing running web app, bottom-right, source of Button and Reactions components.

Contents of windows:

index.page.md:

---
title: An interactive markdown page
script: |
  import Reaction from './Reaction.fragment.js'

  // Initialise database if necessary.
  kitten.db.reactions ??= {}
  kitten.db.reactions.Heart ??= 0
  kitten.db.reactions.Confetti ??= 0
  kitten.db.reactions.Smiley ??= 0

  let page

  export function onConnect (data) {
    page = data.page
  }

  export function onReaction (data) {
    kitten.db.reactions[data.type]++
    page.send(kitten.html`<${Reaction} />`)
  }
---
<page css>

# Hello!

While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block.

## Reactions{id=your-reactions}

<${Reaction} />

Browser (output):

Hello!
While this is a markdown page, I can easily layer interactivity by adding a simple component in a script block.

Reactions

Heart button: 5
Confetti button: 4
Smiley button: 3
Screenshot: three windows: left side: Source of index.page.md, top-right browser showing running web app, bottom-right, source of Button and Reactions components. Contents of windows: index.page.md: --- title: An interactive markdown page script: | import Reaction from './Reaction.fragment.js' // Initialise database if necessary. kitten.db.reactions ??= {} kitten.db.reactions.Heart ??= 0 kitten.db.reactions.Confetti ??= 0 kitten.db.reactions.Smiley ??= 0 let page export function onConnect (data) { page = data.page } export function onReaction (data) { kitten.db.reactions[data.type]++ page.send(kitten.html`<${Reaction} />`) } --- <page css> # Hello! While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block. ## Reactions{id=your-reactions} <${Reaction} /> Browser (output): Hello! While this is a markdown page, I can easily layer interactivity by adding a simple component in a script block. Reactions Heart button: 5 Confetti button: 4 Smiley button: 3

The new integrated Markdown parser I’ve been implementing in Kitten has been kicking my ass for the past few weeks but I think I finally have it fully working and seamlessly so. Expect a new release this/next week that brings the parsing of Markdown pages (.page.md files) in your apps up to the standard of the recently-improved runtime Markdown parsing in Kitten HTML tagged-template strings (within &lt;markdown&gt;…&lt;/markdown&gt; blocks).

The coolest thing is I was able to implement this without introducing any new syntax. In fact, I was able to simplify things so that you can now add arbitrary JavaScript to your Markdown pages within a multi-line script block in the YAML front matter (script: |) and use JavaScript string interpolation syntax in your Markdown (and, of course, Kitten components and conditionals, which, themselves, rely on string interpolation).

The only place where you have to deviate from standard Markdown in your Markdown pages is if you have JavaScript string interpolations or Kitten components/conditionals in code fences within your Markdown. In that case, you’ll have to escape them (e.g., &lt;\${Component} /&gt;, \&lt;if \${something}&gt;something\&lt;/if&gt;, etc.). And, to be fair, the person most impacted by this is likely me as the Kitten documentation at https://kitten.small-web.org is written in Kitten so I had a lot of escaping to do. But for any other use case, it means that things should just work and work exactly as they do in JavaScript pages (page.js files).

Anyway, so this is going to be a breaking change so I thought I’d give you (the three of you playing with Kitten right now?) a heads up. Of course, I’ll be updating the documentation to reflect all this.

(Remember, Kitten is in pre-release and it’s the framework I’m building/using to create Catalyst – the Small Web hosting solution – and Yarn – a small web – peer to peer – personal site app. So Kitten isn’t the means, not the end. And, at least until the Version 1 API freeze, things can and will break. That said, there’s nothing stopping you from playing with it now and, to be fair, at this point, such breaking changes should become rarer and rarer).

kitten💕

#Kitten #SmallWeb#SmallTech #web #dev#Markdown#JavaScript#HTML#CSS#JavaScript#NodeJS

Bloody hell, finally, I think I’m done with the Markdown support rewrite in Kitten.

The Markdown rule for interpreting four spaces as code fences has been the biggest pain in my neck during this whole ordeal but, bitching aside, it means the parser is now more accurate and thus stronger for it.

If all goes well, expect a Monday release :)

https://kitten.small-web.org

kitten💕

#Kitten #SmallWeb#SmallTech #web #dev#Markdown#HTML#CSS#JavaScript#NodeJS