diff --git a/README.md b/README.md index 561f3fb972..504921ce1a 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,16 @@ with. ## My JavaScript Demos - I Love JavaScript! +* [Parsing Plus-Minus Ranges In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/plus-minus-range) +* [Exploring Event.isTrusted In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/event-is-trusted) +* [Table Row Linker Directive In Alpine.js](https://bennadel.github.io/JavaScript-Demos/demos/row-linker) +* [Sending Messages Across Documents With The Broadcast Channel API](https://bennadel.github.io/JavaScript-Demos/demos/broadcast-api) +* [Animating DOM Rectangles Over Focused Elements In JavaScript](https://bennadel.github.io/JavaScript-Demos/demos/focus-box) +* [Linking To A Disclosure (Details) Element](https://bennadel.github.io/JavaScript-Demos/demos/scroll-to-details) +* [Opening The Dialog Element As A Fly-out Sidebar](https://bennadel.github.io/JavaScript-Demos/demos/dialog-element-sidebar) +* [Exploring The Dialog Element In HTML](https://bennadel.github.io/JavaScript-Demos/demos/dialog-element) +* [Storing Metadata On Select Option Elements](https://bennadel.github.io/JavaScript-Demos/demos/select-option-dataset) +* [Exploring Prev/Next Mechanics In HTMX](https://bennadel.github.io/JavaScript-Demos/demos/htmx-prev-next) * [Pixel Art With Alpine.js](https://bennadel.github.io/JavaScript-Demos/demos/pixel-art-alpine) * [Movie Ranking With Sortable.js And Kendall Tau Distance](https://bennadel.github.io/JavaScript-Demos/demos/movie-rank) * [Using :scope To Identify The Host Element In A CSS Selector](https://bennadel.github.io/JavaScript-Demos/demos/scope-pseudo-class) @@ -704,5 +714,5 @@ with. Want more JavaScript goodness? Check out the [JavaScript blog entries][javascript-blog] on my website. -[bennadel]: http://www.bennadel.com -[javascript-blog]: http://www.bennadel.com/blog/tags/6-javascript-dhtml-blog-entries.htm +[bennadel]: https://www.bennadel.com +[javascript-blog]: https://www.bennadel.com/blog/tags/6-javascript-dhtml-blog-entries.htm diff --git a/demos/broadcast-api/frame.htm b/demos/broadcast-api/frame.htm new file mode 100644 index 0000000000..6e26e34a8d --- /dev/null +++ b/demos/broadcast-api/frame.htm @@ -0,0 +1,75 @@ + + + + + + Broadcast Channel API Frame + + + + + + + + + + + + + + diff --git a/demos/broadcast-api/index.htm b/demos/broadcast-api/index.htm new file mode 100644 index 0000000000..9b0d7694af --- /dev/null +++ b/demos/broadcast-api/index.htm @@ -0,0 +1,30 @@ + + + + + + Sending Messages Across Documents With The Broadcast Channel API + + + + + +

+ Sending Messages Across Documents With The Broadcast Channel API +

+ +

+ These are all <iframe> elements to the same URL: +

+ +
+ + + + + + +
+ + + diff --git a/demos/broadcast-api/main.css b/demos/broadcast-api/main.css new file mode 100644 index 0000000000..74c4b740f5 --- /dev/null +++ b/demos/broadcast-api/main.css @@ -0,0 +1,107 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-visible { + animation-duration: 200ms ; + animation-fill-mode: forwards ; + animation-iteration-count: 1 ; + animation-name: outlineEnter ; + animation-timing-function: ease-out ; + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +@keyframes outlineEnter { + from { + outline-offset: 8px ; + } + to { + outline-offset: 4px ; + } +} + +.textBlock * { + &:focus, + &:focus-visible { + animation-name: none ; + outline: none ; + } +} + + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +a { + color: red ; +} + +.frame-list { + display: flex ; + gap: 10px ; + flex-wrap: wrap ; + + & iframe { + border: 1px solid #333333 ; + flex: 0 0 auto ; + height: 200px ; + width: 220px ; + } +} + +.frame-body { + margin: 0 ; + min-height: 100vh ; + + &:hover .laser { + --color: 0, 155, 0 ; + --size: 20px ; + } +} + +.laser { + --color: 255, 0, 0 ; + --size: 8px ; + position: fixed ; + + &:before { + background: rgb( var( --color ) ) ; + border-radius: 100% ; + box-shadow: 0 0 8px 0 rgba( var( --color ), 0.8 ) ; + content: "" ; + height: var( --size ) ; + position: absolute ; + translate: -50% -50% ; + width: var( --size ) ; + } +} diff --git a/demos/dialog-element-sidebar/index.htm b/demos/dialog-element-sidebar/index.htm new file mode 100644 index 0000000000..19835437c3 --- /dev/null +++ b/demos/dialog-element-sidebar/index.htm @@ -0,0 +1,126 @@ + + + + + + Opening The Dialog Element As A Fly-out Sidebar + + + + + +

+ Opening The Dialog Element As A Fly-out Sidebar +

+ + + + + +

+ Dialog As Sidebar +

+ +

+ Lorem ipsum dolor sit amet nuntius, inde cum cor, supero ferus difficilis + poena. Ipse intro longe incido ex pauci culpa. Tu moneo quidam, ego magnus + consul. Ego timeo quis virtus que quis numen. Idem patior forte augeo ultra + caecus poena. +

+ + + +
+ Back to Top +
+ +
+ + +

+ Back to Top +

+ + + + + + diff --git a/demos/dialog-element-sidebar/main.css b/demos/dialog-element-sidebar/main.css new file mode 100644 index 0000000000..e9a48ed8a3 --- /dev/null +++ b/demos/dialog-element-sidebar/main.css @@ -0,0 +1,45 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-within { + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +dialog h2 { + margin-block-start: 0 ; + scroll-margin-block-start: 2rem ; /* To counteract dialog padding. */ +} diff --git a/demos/dialog-element/index.htm b/demos/dialog-element/index.htm new file mode 100644 index 0000000000..a0647c5eb1 --- /dev/null +++ b/demos/dialog-element/index.htm @@ -0,0 +1,144 @@ + + + + + + Exploring The Dialog Element In HTML + + + + + +

+ Exploring The Dialog Element In HTML +

+ +

+ + +

+ + +
+ + + + +
+

+ Are you sure? +

+

+ + +

+
+
+ + + + + + diff --git a/demos/dialog-element/main.css b/demos/dialog-element/main.css new file mode 100644 index 0000000000..2fa849f347 --- /dev/null +++ b/demos/dialog-element/main.css @@ -0,0 +1,50 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-within { + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + + +form p:first-child { + margin-top: 0 ; +} +form p:last-child { + display: flex ; + gap: 12px ; + margin-bottom: 0 ; +} diff --git a/demos/event-is-trusted/index.htm b/demos/event-is-trusted/index.htm new file mode 100644 index 0000000000..497c689600 --- /dev/null +++ b/demos/event-is-trusted/index.htm @@ -0,0 +1,77 @@ + + + + + + Exploring Event.isTrusted In JavaScript + + + + + +

+ Exploring Event.isTrusted In JavaScript +

+ +

+ Form +

+ +
+ + + Cancel + +
+ +

+ Triggers on Form +

+ +

+ + + +

+ + + + + diff --git a/demos/event-is-trusted/main.css b/demos/event-is-trusted/main.css new file mode 100644 index 0000000000..208dea2172 --- /dev/null +++ b/demos/event-is-trusted/main.css @@ -0,0 +1,82 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-visible { + animation-duration: 200ms ; + animation-fill-mode: forwards ; + animation-iteration-count: 1 ; + animation-name: outlineEnter ; + animation-timing-function: ease-out ; + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +@keyframes outlineEnter { + from { + outline-offset: 8px ; + } + to { + outline-offset: 4px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +a { + color: red ; +} + +table { + border: 1px solid #333333 ; + border-collapse: collapse ; + width: 100% ; + + & :where(th, td) { + border: 1px solid #333333 ; + padding: 5px 10px ; + + &:not([align]) { + text-align: left ; + } + } +} + +tbody tr:hover { + background-color: #e7f9ff ; +} + +a.active { + background-color: #333333 ; + color: #fafafa ; +} diff --git a/demos/focus-box/index.htm b/demos/focus-box/index.htm new file mode 100644 index 0000000000..e61ee14cb5 --- /dev/null +++ b/demos/focus-box/index.htm @@ -0,0 +1,165 @@ + + + + + + Animating DOM Rectangles Over Focused Elements In JavaScript + + + + + +

+ Animating DOM Rectangles Over Focused Elements In JavaScript +

+ +

+ Before demo text block (to take focus from demo block and to contrast + the normal focus-outline behavior). +

+ +

+ + + + Lorem ipsum dolor sit amet interrogo communis flumen. + Mille iuvenis, umquam ante cohors, adhibeo citus fortis provincia. + Hic posco ego, quis frequens tenebrae. Aliquis turbo is epistula. Hic + experior quidam voluntas nam aliquis vinculum. Noster puto paulo sum post + saevus natura. Diversus ventus, quasi cum for meus, scribo dexter prior + astrum. Idem condo qua ictus quoque nemo iter. Mortalis frater, denique in + puer, tollo nullus quattuor vestigium. Iste dico ipse voluntas an sui + vitium meus desino quisquis, qua gratus ira tu opto nemo praemium gens rideo + diversus error. + +

+ + + + + + diff --git a/demos/focus-box/main.css b/demos/focus-box/main.css new file mode 100644 index 0000000000..2d6ee4756b --- /dev/null +++ b/demos/focus-box/main.css @@ -0,0 +1,67 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-visible { + animation-duration: 200ms ; + animation-fill-mode: forwards ; + animation-iteration-count: 1 ; + animation-name: outlineEnter ; + animation-timing-function: ease-out ; + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +@keyframes outlineEnter { + from { + outline-offset: 8px ; + } + to { + outline-offset: 4px ; + } +} + +.textBlock * { + &:focus, + &:focus-visible { + animation-name: none ; + outline: none ; + } +} + + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +a { + color: red ; +} diff --git a/demos/htmx-prev-next/index.htm b/demos/htmx-prev-next/index.htm new file mode 100644 index 0000000000..16b6f4693b --- /dev/null +++ b/demos/htmx-prev-next/index.htm @@ -0,0 +1,140 @@ + + + + + + + + +

+ Exploring Prev/Next Mechanics In HTMX +

+ + + +
+ + + + + diff --git a/demos/htmx-prev-next/main.css b/demos/htmx-prev-next/main.css new file mode 100644 index 0000000000..832631675f --- /dev/null +++ b/demos/htmx-prev-next/main.css @@ -0,0 +1,20 @@ + +body { + font-family: verdana, arial, sans-serif ; + font-size: 18px ; +} + +button { + border: 1px solid #999999 ; + color: inherit ; + cursor: pointer ; + font-family: inherit ; + font-size: 20px ; + padding: 5px 10px ; +} + +.selected { + font-weight: bold ; + background: gold ; +} + diff --git a/demos/plus-minus-range/index.htm b/demos/plus-minus-range/index.htm new file mode 100644 index 0000000000..5ea431c51d --- /dev/null +++ b/demos/plus-minus-range/index.htm @@ -0,0 +1,80 @@ + + + + + + Parsing Plus-Minus Ranges In JavaScript + + + + + +

+ Parsing Plus-Minus (±) Ranges In JavaScript +

+ +
+ + + +
+ + + + + diff --git a/demos/plus-minus-range/main.css b/demos/plus-minus-range/main.css new file mode 100644 index 0000000000..b3a260c6fc --- /dev/null +++ b/demos/plus-minus-range/main.css @@ -0,0 +1,95 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-visible { + animation-duration: 200ms ; + animation-fill-mode: forwards ; + animation-iteration-count: 1 ; + animation-name: outlineEnter ; + animation-timing-function: ease-out ; + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +@keyframes outlineEnter { + from { + outline-offset: 8px ; + } + to { + outline-offset: 4px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +a { + color: red ; +} + +table { + border: 1px solid #333333 ; + border-collapse: collapse ; + width: 100% ; + + & :where(th, td) { + border: 1px solid #333333 ; + padding: 5px 10px ; + + &:not([align]) { + text-align: left ; + } + } +} + +tbody tr:hover { + background-color: #e7f9ff ; +} + + +form { + display: flex ; + gap: 13px ; + max-width: 670px ; +} + +form { + & input:nth-child(1) { + flex: 1 0 auto ; + width: 250px ; + } + & input { + flex: 1 0 auto ; + width: 100px ; + } +} diff --git a/demos/row-linker/index.htm b/demos/row-linker/index.htm new file mode 100644 index 0000000000..988443058b --- /dev/null +++ b/demos/row-linker/index.htm @@ -0,0 +1,233 @@ + + + + + + Table Row Linker Directive In Alpine.js + + + + + +

+ Table Row Linker Directive In Alpine.js +

+ + + + + + + + + + + + + +
NameInfoCategoryActions
+ + + + + + diff --git a/demos/row-linker/main.css b/demos/row-linker/main.css new file mode 100644 index 0000000000..208dea2172 --- /dev/null +++ b/demos/row-linker/main.css @@ -0,0 +1,82 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-visible { + animation-duration: 200ms ; + animation-fill-mode: forwards ; + animation-iteration-count: 1 ; + animation-name: outlineEnter ; + animation-timing-function: ease-out ; + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +@keyframes outlineEnter { + from { + outline-offset: 8px ; + } + to { + outline-offset: 4px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +a { + color: red ; +} + +table { + border: 1px solid #333333 ; + border-collapse: collapse ; + width: 100% ; + + & :where(th, td) { + border: 1px solid #333333 ; + padding: 5px 10px ; + + &:not([align]) { + text-align: left ; + } + } +} + +tbody tr:hover { + background-color: #e7f9ff ; +} + +a.active { + background-color: #333333 ; + color: #fafafa ; +} diff --git a/demos/scroll-to-details/index.htm b/demos/scroll-to-details/index.htm new file mode 100644 index 0000000000..6a4925888c --- /dev/null +++ b/demos/scroll-to-details/index.htm @@ -0,0 +1,87 @@ + + + + + + Linking To A Disclosure (Details) Element + + + + + +

+ Linking To A Disclosure (Details) Element +

+ + + + +
+ + Markdown Syntax + +
+ You can use limited Markdown syntax in your content. +
+
+ +
+ + Keyboard Shortcuts + +
+ You can use the following keyboard shortcuts in the application. +
+
+ +
+ + Privacy Policy + +
+ All your data is belong to us! +
+
+ + + + + diff --git a/demos/scroll-to-details/main.css b/demos/scroll-to-details/main.css new file mode 100644 index 0000000000..6fb08f51a0 --- /dev/null +++ b/demos/scroll-to-details/main.css @@ -0,0 +1,87 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-visible { + animation-duration: 200ms ; + animation-fill-mode: forwards ; + animation-iteration-count: 1 ; + animation-name: outlineEnter ; + animation-timing-function: ease-out ; + outline-color: hotpink ; + outline-offset: 4px ; + /* outline-style: solid ; */ + outline-width: 2px ; + } +} + +@keyframes outlineEnter { + from { + outline-offset: 8px ; + } + to { + outline-offset: 4px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +} + +button { + padding: 5px 15px ; +} + +a { + color: red ; +} + +details { + border: 1px solid #cccccc ; + margin-block-start: 10rem ; + padding: 10px ; + + &[ open ] { + background-color: #f0f0f0 ; + } + + & > summary { + cursor: pointer ; + scroll-margin-block-start: 35px ; + + /* + By default, the browser doesn't appear to give an outline to the summary + element. As such, I'm explicitly giving it an outline when focused. + */ + &:focus, + &:focus-visible { + outline-style: solid ; + } + } + + & > section { + margin: 10px 0 0 0 ; + } +} diff --git a/demos/select-option-dataset/index.htm b/demos/select-option-dataset/index.htm new file mode 100644 index 0000000000..d69d7c7b54 --- /dev/null +++ b/demos/select-option-dataset/index.htm @@ -0,0 +1,65 @@ + + + + + + Storing Metadata On Select Option Elements + + + + + +

+ Storing Metadata On Select Option Elements +

+ + + + + + + diff --git a/demos/select-option-dataset/main.css b/demos/select-option-dataset/main.css new file mode 100644 index 0000000000..6dbca334cf --- /dev/null +++ b/demos/select-option-dataset/main.css @@ -0,0 +1,36 @@ + +:where( html ) { + box-sizing: border-box ; + + & *, + & *:before, + & *:after { + box-sizing: inherit ; + } +} + +:where( * ) { + &:focus, + &:focus-within { + outline-color: hotpink ; + outline-offset: 4px ; + outline-width: 2px ; + } +} + +body { + font-family: Avenir, Montserrat, Corbel, URW Gothic, source-sans-pro, sans-serif ; + font-size: 18px ; + line-height: 1.4 ; +} + +button, +input:where([type="text"]), +select, +textarea { + color: inherit ; + font-family: inherit ; + font-size: 20px ; + line-height: inherit ; + padding: 5px 10px ; +}