diff options
author | Bradley Taunt <bt@btxx.org> | 2024-07-05 16:39:27 -0400 |
---|---|---|
committer | Bradley Taunt <bt@btxx.org> | 2024-07-05 16:39:27 -0400 |
commit | b3bf04932880e9f984675cff5d70da58167316cc (patch) | |
tree | db30313e5cd51988af36e480077e6456b8590b62 | |
parent | cc72ef25c6de2b0004c163d06486d949acf3c78c (diff) |
Start converting code samples into cleaner markdown chunks
33 files changed, 867 insertions, 821 deletions
diff --git a/posts/Building_rbenv_on_OpenBSD_7.5.md b/posts/Building_rbenv_on_OpenBSD_7.5.md index 90f5479..3da1fad 100644 --- a/posts/Building_rbenv_on_OpenBSD_7.5.md +++ b/posts/Building_rbenv_on_OpenBSD_7.5.md @@ -8,40 +8,54 @@ I use Ruby (specifically with Jekyll) for a lot of my clubs/projects while using First, be sure to install the required packages in order to build from source, and then clone the core `rbenv` repo: - pkg_add git gcc gmake libffi libyaml openssl - git clone https://github.com/rbenv/rbenv.git ~/.rbenv +~~~sh +pkg_add git gcc gmake libffi libyaml openssl +git clone https://github.com/rbenv/rbenv.git ~/.rbenv +~~~ ## Building `rbenv` Add `rbenv` to your PATH and initialize it (place this inside your `.bashrc` or `.zshrc` etc): - export PATH="$HOME/.rbenv/bin:$PATH" - export PATH="$HOME/.rbenv/shims:$PATH" - export RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local" - eval "$(rbenv init -)" +~~~sh +export PATH="$HOME/.rbenv/bin:$PATH" +export PATH="$HOME/.rbenv/shims:$PATH" +export RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local" +eval "$(rbenv init -)" +~~~ Then reload your shell (zsh in this example): - source ~/.zshrc +~~~sh +source ~/.zshrc +~~~ Next we will need to install `ruby-build` as a `rbenv` plugin. Clone the ruby-build repository into the rbenv plugins directory: - git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build +~~~sh +git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build +~~~ ## Installing Ruby and Setting Our Version Now use `rbenv` to install the desired version of Ruby (we will get an older version for this example): - rbenv install 3.3.0 +~~~sh +rbenv install 3.3.0 +~~~ If you run into issues, you may need to specify your openssl directory: - RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local" rbenv install 3.3.0 +~~~sh +RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local" rbenv install 3.3.0 +~~~ If you're on a slower machine (like mine) this might take a little bit. Just grab a coffee or a snack while you wait! Then navigate to your project of choice and set the `local` Ruby version: - rbenv local 3.3.0 +~~~sh +rbenv local 3.3.0 +~~~ That's it! If you'd prefer to set this version of Ruby for all projects going forward, simply replace `local` with `global`. diff --git a/posts/adguard.md b/posts/adguard.md index f896f6f..5cd1e5a 100644 --- a/posts/adguard.md +++ b/posts/adguard.md @@ -26,31 +26,31 @@ Don't flash anything just yet! Be sure to use the gear icon and edit the setting Put the SD card into your Pi, connect power and ethernet. Give it a bit of time to boot up. Once you see a nice solid green LED, go back to your local computer's terminal and enter the following command: -``` +~~~sh ssh piguard@piguard.local -``` +~~~ If everything was set up properly you will be asked to trust this device. Next, you will be prompted to enter the device password you setup. Once you are connected directly to the Pi, it's best to check for updates: - - sudo apt update - +~~~sh +sudo apt update +~~~ ...and if updates are in fact available, install them via: - - sudo apt upgrade - +~~~sh +sudo apt upgrade +~~~ ## Installing AdGuard Home Simply run the automated installer: - - curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v - +~~~sh +curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v +~~~ Follow the instructions and you'll be setup in no time! To view your AdGuard dashboard at any time, you can now simply navigate to `piguard.local`. diff --git a/posts/alpine.md b/posts/alpine.md index a1c860b..78b2329 100644 --- a/posts/alpine.md +++ b/posts/alpine.md @@ -67,34 +67,36 @@ I'll save you both the headache and large amount of time I wasted on this silly I put the following in my `/etc/xdg/mimeapps.list` (which is included by default with the installer) - [Default Applications] - x-scheme-handler/http=org.qutebrowser.qutebrowser.desktop - x-scheme-handler/https=org.qutebrowser.qutebrowser.desktop - x-scheme-handler/ftp=org.qutebrowser.qutebrowser.desktop - x-scheme-handler/chrome=org.qutebrowser.qutebrowser.desktop - text/html=org.qutebrowser.qutebrowser.desktop - application/x-extension-htm=org.qutebrowser.qutebrowser.desktop - application/x-extension-html=org.qutebrowser.qutebrowser.desktop - application/x-extension-shtml=org.qutebrowser.qutebrowser.desktop - application/xhtml+xml=org.qutebrowser.qutebrowser.desktop - application/x-extension-xhtml=org.qutebrowser.qutebrowser.desktop - application/x-extension-xht=org.qutebrowser.qutebrowser.desktop - image/bmp=feh.desktop - image/gif=feh.desktop - image/jpeg=feh.desktop - image/jpg=feh.desktop - image/png=feh.desktop - image/tiff=feh.desktop - image/x-bmp=feh.desktop - image/x-pcx=feh.desktop - image/x-tga=feh.desktop - image/x-portable-pixmap=feh.desktop - image/x-portable-bitmap=feh.desktop - image/x-targa=feh.desktop - image/x-portable-greymap=feh.desktop - application/pcx=feh.desktop - image/svg+xml=feh.desktop - image/svg-xml=feh.desktop +~~~sh +[Default Applications] +x-scheme-handler/http=org.qutebrowser.qutebrowser.desktop +x-scheme-handler/https=org.qutebrowser.qutebrowser.desktop +x-scheme-handler/ftp=org.qutebrowser.qutebrowser.desktop +x-scheme-handler/chrome=org.qutebrowser.qutebrowser.desktop +text/html=org.qutebrowser.qutebrowser.desktop +application/x-extension-htm=org.qutebrowser.qutebrowser.desktop +application/x-extension-html=org.qutebrowser.qutebrowser.desktop +application/x-extension-shtml=org.qutebrowser.qutebrowser.desktop +application/xhtml+xml=org.qutebrowser.qutebrowser.desktop +application/x-extension-xhtml=org.qutebrowser.qutebrowser.desktop +application/x-extension-xht=org.qutebrowser.qutebrowser.desktop +image/bmp=feh.desktop +image/gif=feh.desktop +image/jpeg=feh.desktop +image/jpg=feh.desktop +image/png=feh.desktop +image/tiff=feh.desktop +image/x-bmp=feh.desktop +image/x-pcx=feh.desktop +image/x-tga=feh.desktop +image/x-portable-pixmap=feh.desktop +image/x-portable-bitmap=feh.desktop +image/x-targa=feh.desktop +image/x-portable-greymap=feh.desktop +application/pcx=feh.desktop +image/svg+xml=feh.desktop +image/svg-xml=feh.desktop +~~~ You might have also noticed that I use `feh` as my default image viewer as well. That's just my personal preference, feel free to switch that out as you see fit. @@ -114,19 +116,25 @@ Some of these "hacks" or tweaks I had to implement might help others who run int It is important to install `gawk` since `awk` isn't "real" on Alpine. Once you have that on you system `aerc` will render emails out-of-the-box.[^1] - apk add gawk +~~~sh +apk add gawk +~~~ ### Sublime Text Sublime Text requires flatpak, so if that isn't your *thing* then you're better off snagging a different editor. I've tried multiple times throughout my career to use an alternate editor (preferably 100% open source) but keep finding myself returning to Sublime. Maybe one day... - apk add flatpak - flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +~~~sh +apk add flatpak +flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo +~~~ Then reboot your machine for the changes to take. Login again and run: - flatpak install flathub com.sublimetext.three +~~~sh +flatpak install flathub com.sublimetext.three +~~~ FYI: You *might* need to run the above commands under `sudo` if your current user lacks proper permissions. diff --git a/posts/animated-card-tiles.md b/posts/animated-card-tiles.md index 318583a..486ec2f 100644 --- a/posts/animated-card-tiles.md +++ b/posts/animated-card-tiles.md @@ -21,16 +21,16 @@ For the base skeleton of these cards we only need: - the inner child element that will display on `:hover` - proper `h4` and `p` tags inside that child element - - <div class="card-tiles-container"> - <div class="card-tile"> - <div class="text-content"> - <h4>Card Title</h4> - <p>Inner card content text</p> - </div> - </div> +~~~html +<div class="card-tiles-container"> + <div class="card-tile"> + <div class="text-content"> + <h4>Card Title</h4> + <p>Inner card content text</p> </div> - + </div> +</div> +~~~ That's all that is needed - for now. We will be returning to this code shortly to add some extra classes to make our lives easier. diff --git a/posts/animated-toggle-tabs.md b/posts/animated-toggle-tabs.md index dcbcfea..5404cfc 100644 --- a/posts/animated-toggle-tabs.md +++ b/posts/animated-toggle-tabs.md @@ -18,88 +18,89 @@ Let’s get started with the base skeleton. <p>There isn't anything special happening here. We just contain all our <code>labels</code> and <code>inputs</code> into a <code>.radio-toggles</code> wrapper, make sure those <code>labels</code> are each properly connected to their corresponding <code>inputs</code>, and then add an empty <code>.slide-item</code> element (more on that later).</p> - - <div class="radio-toggles"> - <input type="radio" id="option-1" name="radio-options"> - <label for="option-1">One-Time</label> - <input type="radio" id="option-2" name="radio-options" checked> - <label for="option-2">Recurring</label> - <input type="radio" id="option-3" name="radio-options"> - <label for="option-3">Free</label> - <div class="slide-item"></div> - </div> +~~~html +<div class="radio-toggles"> + <input type="radio" id="option-1" name="radio-options"> + <label for="option-1">One-Time</label> + <input type="radio" id="option-2" name="radio-options" checked> + <label for="option-2">Recurring</label> + <input type="radio" id="option-3" name="radio-options"> + <label for="option-3">Free</label> + <div class="slide-item"></div> +</div> +~~~ ## The CSS Now for the main event – the CSS. First we want to style the wrapper that holds all of our pieces together. You can tweak this to your liking, but I prefer a simple and clean style: - - .radio-toggles { - align-items: center; - background: #eee; - border: 1px solid lightgrey; - border-radius: 9999px; - display: flex; - justify-content: center; - margin: 20px auto; - max-width: 400px; - overflow: hidden; - padding: 4px; - position: relative; - } - +~~~css +.radio-toggles { + align-items: center; + background: #eee; + border: 1px solid lightgrey; + border-radius: 9999px; + display: flex; + justify-content: center; + margin: 20px auto; + max-width: 400px; + overflow: hidden; + padding: 4px; + position: relative; +} +~~~ Next, we “hide” (only visually) the default `radio` inputs: - - input[type="radio"] { - left: -9999px; - position: absolute; - z-index: -1; - } - +~~~css +input[type="radio"] { + left: -9999px; + position: absolute; + z-index: -1; +} +~~~ Then we give the corresponding `label` elements a little spacing and breathing room: - - label { - cursor: pointer; - padding: 10px 20px; - text-align: center; - width: 33.33%; - z-index: 2; - } - +~~~css +label { + cursor: pointer; + padding: 10px 20px; + text-align: center; + width: 33.33%; + z-index: 2; +} +~~~ Remember that `.slide-item` I referenced earlier? That element will be the visual “slider” that animates between the individual radio options. We style that like so: - - .slide-item { - background: white; - border-radius: 9999px; - box-shadow: 0 2px 4px rgba(0,0,0,0.15); - height: calc(100% - 8px); - left: calc(33.33% + 4px); - position: absolute; - width: calc(33.33% - 8px); - transition: left .4s; - z-index: 0; - } - +~~~sh +.slide-item { + background: white; + border-radius: 9999px; + box-shadow: 0 2px 4px rgba(0,0,0,0.15); + height: calc(100% - 8px); + left: calc(33.33% + 4px); + position: absolute; + width: calc(33.33% - 8px); + transition: left .4s; + z-index: 0; +} +~~~ You'll notice the `left`, `height`, and `width` properties utilize the CSS `calc` attributes – this just gives some much needed padding and visual clean-up to the whole tabbed interface. For the finishing touches, we just need to tell the `.slide-item` where to position itself based on which `radio` input is currently selected: - - input[type="radio"]:nth-of-type(1):checked ~ .slide-item { - left: 4px; - } - input[type="radio"]:nth-of-type(3):checked ~ .slide-item { - left: calc(66.66% + 4px); - } - +~~~css +input[type="radio"]:nth-of-type(1):checked ~ .slide-item { + left: 4px; +} +input[type="radio"]:nth-of-type(3):checked ~ .slide-item { + left: calc(66.66% + 4px); +} +~~~ That's pretty much it! You now have a fully functional, animated toggle slider with just a set of simple `radio` inputs and pure CSS. diff --git a/posts/audio-hotkeys-on-linux-mint.md b/posts/audio-hotkeys-on-linux-mint.md index 09aaf5e..1037e91 100644 --- a/posts/audio-hotkeys-on-linux-mint.md +++ b/posts/audio-hotkeys-on-linux-mint.md @@ -8,13 +8,14 @@ Setting up all my go-to applications (Sublime, LocalWP, Riot, Evolution, etc) wa For my own personal reference, I'm also going to include those code snippets here since you never know when you might need it again! And who knows, maybe this will help someone else stumbling around the internet. +~~~sh +// Volume Up +pactl set-sink-volume @DEFAULT_SINK@ +5% - // Volume Up - pactl set-sink-volume @DEFAULT_SINK@ +5% +// Volume Down +pactl set-sink-volume @DEFAULT_SINK@ -5% - // Volume Down - pactl set-sink-volume @DEFAULT_SINK@ -5% - - // Toggle Mute - pactl set-sink-mute @DEFAULT_SINK@ toggle +// Toggle Mute +pactl set-sink-mute @DEFAULT_SINK@ toggle +~~~ diff --git a/posts/aui.md b/posts/aui.md index fa6786b..37cbd2f 100644 --- a/posts/aui.md +++ b/posts/aui.md @@ -14,50 +14,58 @@ Since I've been wanting to dip my toes into more tutorial-based articles (maybe Since this project consists of only two buttons elements, the HTML or <i>skeleton</i> of this project is very straightforward: - <button class="cancel">Cancel</button> - <button class="confirm">Confirm</button> +~~~html +<button class="cancel">Cancel</button> +<button class="confirm">Confirm</button> +~~~ ### Styling the buttons The first step is to remove the browser's default button styling by using the `appearance` property. This will help avoid having to fight against the browser and minimize our CSS code. - button { - -webkit-appearance: none; - -moz-appearance: none; - } +~~~css +button { + -webkit-appearance: none; + -moz-appearance: none; +} +~~~ Next, we apply a fairly simple set of CSS that will be shared across both the confirm and cancel buttons: (Pay attention to the `transition` property as we will be returning to that shortly) - button { - -webkit-appearance: none; - -moz-appearance: none; - border: 1px solid #ccc; - border-radius: 125px; - box-shadow: inset 0 13px 25px rgba(255,255,255,0.5), 0 3px 5px rgba(0,0,0,0.2), 0 10px 13px rgba(0,0,0,0.1); - cursor: pointer; - font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; - font-size: 2rem; - margin: 5rem 1rem; - padding: 1.2rem 4rem; - position: relative; - transition: all ease .3s; - } +~~~css +button { + -webkit-appearance: none; + -moz-appearance: none; + border: 1px solid #ccc; + border-radius: 125px; + box-shadow: inset 0 13px 25px rgba(255,255,255,0.5), 0 3px 5px rgba(0,0,0,0.2), 0 10px 13px rgba(0,0,0,0.1); + cursor: pointer; + font-family: 'Lucida Grande', Helvetica, Arial, sans-serif; + font-size: 2rem; + margin: 5rem 1rem; + padding: 1.2rem 4rem; + position: relative; + transition: all ease .3s; +} +~~~ Then we separate the specific confirm and cancel button styles into their own class selectors: - button.confirm { - background: #4A90E2; - border-color: #3672B6; - color: #fff; - } +~~~css +button.confirm { + background: #4A90E2; + border-color: #3672B6; + color: #fff; +} - button.cancel { - background: #D0D0D0; - border-color: #B8B8B8; - color: #6F6F6F; - } +button.cancel { + background: #D0D0D0; + border-color: #B8B8B8; + color: #6F6F6F; +} +~~~ ### Playing with pseudo elements @@ -65,26 +73,30 @@ Now that the button is styled and structured with basic formatting, it's time to The cleanest way to do this is by using the `:before` pseudo element paired with a linear-gradient background. - button:before { - background: linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); - border-radius: 125px; - content:''; - height: 50px; - left: 4%; - position: absolute; - top: 1px; - transition: all ease .3s; - width: 92%; - } +~~~css +button:before { + background: linear-gradient(rgba(255,255,255,1) 0%, rgba(255,255,255,0) 100%); + border-radius: 125px; + content:''; + height: 50px; + left: 4%; + position: absolute; + top: 1px; + transition: all ease .3s; + width: 92%; +} +~~~ ### Adding interaction The final step is adding the user hover interaction: (Remember that `transition` property?) - button:hover { - box-shadow: inset 0 13px 25px rgba(255,255,255,0.8), 0 3px 5px rgba(0,0,0,0.2), 0 10px 13px rgba(0,0,0,0.2); - transform: scale(1.02); - } +~~~css +button:hover { + box-shadow: inset 0 13px 25px rgba(255,255,255,0.8), 0 3px 5px rgba(0,0,0,0.2), 0 10px 13px rgba(0,0,0,0.2); + transform: scale(1.02); +} +~~~ That's it! diff --git a/posts/base64-all-the-things.md b/posts/base64-all-the-things.md index c061aef..36b3e4b 100644 --- a/posts/base64-all-the-things.md +++ b/posts/base64-all-the-things.md @@ -12,15 +12,15 @@ It might be common knowledge, but I think breaking down exactly what base64 enco In simpler terms: it is a encoded format that can change an element like this: -```html +~~~html <img src="/path/to/image.webp" alt="Cool image"> -``` +~~~ Into this: -```html +~~~html <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABkAAAASwCAYAA...PnyMAAAAASUVORK5CYII=" alt="Cool image"> -``` +~~~ ## See it in action diff --git a/posts/basic-gulp-build-for-sass.md b/posts/basic-gulp-build-for-sass.md index 48fa014..dae8960 100644 --- a/posts/basic-gulp-build-for-sass.md +++ b/posts/basic-gulp-build-for-sass.md @@ -6,34 +6,34 @@ Some designers might shy away from build tools when first starting out and I can Here is the final `gulp.js` file in all it's glory: +~~~js +var gulp = require('gulp'); +var shell = require('gulp-shell'); +var sass = require('gulp-sass'); - var gulp = require('gulp'); - var shell = require('gulp-shell'); - var sass = require('gulp-sass'); - - /* Build and watch Jekyll (change this task to whatever you need) */ - gulp.task('generate', shell.task('jekyll serve')); - - /* Compile SCSS files to CSS */ - gulp.task('styles', function () { - return gulp.src('_includes/assets/sass/styles.scss') - .pipe(sass({ - outputStyle: 'compressed' - }).on('error', sass.logError)) - .pipe(gulp.dest('_includes/assets/css/')); - }); - - /* Compile the assets */ - gulp.task('assets', gulp.parallel( - 'styles' - )); - - /* Build */ - gulp.task('build', gulp.series( - 'assets', - 'generate' - )); +/* Build and watch Jekyll (change this task to whatever you need) */ +gulp.task('generate', shell.task('jekyll serve')); +/* Compile SCSS files to CSS */ +gulp.task('styles', function () { + return gulp.src('_includes/assets/sass/styles.scss') + .pipe(sass({ + outputStyle: 'compressed' + }).on('error', sass.logError)) + .pipe(gulp.dest('_includes/assets/css/')); +}); + +/* Compile the assets */ +gulp.task('assets', gulp.parallel( + 'styles' +)); + +/* Build */ +gulp.task('build', gulp.series( + 'assets', + generate' +)); +~~~ Trust me, it's not complicated at all. @@ -41,11 +41,11 @@ Trust me, it's not complicated at all. For our basic build file we are going to need only three modules: `gulp`, `gulp-shell` and `gulp-sass`. - - var gulp = require('gulp'); - var shell = require('gulp-shell'); - var sass = require('gulp-sass'); - +~~~js +var gulp = require('gulp'); +var shell = require('gulp-shell'); +var sass = require('gulp-sass'); +~~~ #### gulp This is the streaming build system, without it we can't do anything else. @@ -66,8 +66,9 @@ Required for gulp to compile Sass into vanilla CSS. Our first step is to create the default task that will generate our build. In this example we are making the assumption that we're building a Jekyll website (but you can place any build command here): - - gulp.task('generate', shell.task('jekyll serve')); +~~~sh +gulp.task('generate', shell.task('jekyll serve')); +~~~ Don't worry if this `generate` isn't clear, we come back to that later. @@ -76,48 +77,49 @@ Don't worry if this `generate` isn't clear, we come back to that later. We will name this next task `styles` since that's what it outputs - our styling. We start by telling gulp where our main `scss` directory is: - - /* Change this directory to match yours */ - return gulp.src('_includes/assets/sass/styles.scss') +~~~js +/* Change this directory to match yours */ +return gulp.src('_includes/assets/sass/styles.scss') +~~~ This next piece tells the plugin to compress our final compiled CSS, log any errors if there are issues with the build and then export it to our destination directory: +~~~js +.pipe(sass({ + outputStyle: 'compressed' +}).on('error', sass.logError)) - .pipe(sass({ - outputStyle: 'compressed' - }).on('error', sass.logError)) - - /* Change this to your destination directory */ - .pipe(gulp.dest('_includes/assets/css/')); - +/* Change this to your destination directory */ +.pipe(gulp.dest('_includes/assets/css/')); +~~~ ## Building our assets This step isn't 100% needed, but I like to include it for when more assets need to be added (minifying JavaScript, compressing images, etc) - - /* - Compile the assets - */ - gulp.task('assets', gulp.parallel( - 'styles' - )); - +~~~js +/* +Compile the assets +*/ +gulp.task('assets', gulp.parallel( + 'styles' +)); +~~~ ## Altogether now! Now we add a task that runs all other tasks in our gulp file (in this case it will run both `assets` and `generate`) - - /* - Build - */ - gulp.task('build', gulp.series( - 'assets', - 'generate' - )); - +~~~js +/* +Build +*/ +gulp.task('build', gulp.series( + 'assets', + 'generate' +)); +~~~ And that's it - we're done! A very basic `gulp` build for compiling Sass. diff --git a/posts/batch-webp-conversion.md b/posts/batch-webp-conversion.md index 4bf930e..9befa46 100644 --- a/posts/batch-webp-conversion.md +++ b/posts/batch-webp-conversion.md @@ -36,12 +36,12 @@ You *could* download one of the many native apps from the Mac App Store to do th 8) Enter the following code below as your script and type `⌘-S` to save (name it something like "Convert to webp") -``` +~~~sh for f in "$@" do /usr/local/bin/cwebp -q 85 "$f" -o "${f%.*}.webp" done -``` +~~~ For visual reference, it should look something like this: @@ -67,9 +67,9 @@ Simple as that! I was contacted by the very helpful [Kev Quirk](https://kevq.uk) about a minor problem he encountered while following this tutorial. When trying to run `cwebp` he received the following error message: -``` +~~~sh cwebp cannot be opened because it's from an unverified developer -``` +~~~ Doing the next steps seemed to have fixed this issue for him: diff --git a/posts/battery.md b/posts/battery.md index 4147ce8..dca86c4 100644 --- a/posts/battery.md +++ b/posts/battery.md @@ -8,21 +8,21 @@ It is no secret that OpenBSD has poor battery performance on laptops. Although n I won't go into great detail about `ampd` here - that's what the incredible [documentation is for](https://man.openbsd.org/apmd). You'll want to make sure to start it before trying to configure it: -``` +~~~sh doas rcctl start apmd -``` +~~~ If already running in a live session, you can default to `-A` (auto) but I suggest setting cpu performance to low: -``` +~~~sh apm -L -``` +~~~ To make these changes permanent on boot: -``` +~~~sh doas rcctl set apmd flags -L -``` +~~~ Optimizating battery life via `ampd` will have the most noticable impact but you can improve things even further by implementing some extra "small" performance wins. diff --git a/posts/berg.md b/posts/berg.md index 44caded..d87cea3 100644 --- a/posts/berg.md +++ b/posts/berg.md @@ -18,23 +18,25 @@ The first step is to create the main repo that would house the core files of `pb Once your two repos are created, you will need to make some minor edits to the `_config.sh` in the core `pblog` project to tell the build script where the generated files should go (in this case the `pages` repo): - - OUTPUT="_output/pages/" +~~~sh +OUTPUT="_output/pages/" +~~~ ## The Submodule Using terminal, navigate to the `_output/` directory in your core `pblog` project. Run the following, remembering to replace the USERNAME parameter with your own: - - git submodule add git@codeberg.org:USERNAME/pages.git - +~~~sh +git submodule add git@codeberg.org:USERNAME/pages.git +~~~ If everything worked correctly you should now have a `.gitmodules` file in your main `pblog` project. If you get any errors, you might need to include the name of the directory at the end of the command: - git submodule add git@codeberg.org:USERNAME/pages.git pages - +~~~sh +git submodule add git@codeberg.org:USERNAME/pages.git pages +~~~ ## The Workflow @@ -42,9 +44,9 @@ Now you can make changes, add new posts and pages in the main `pblog` project an Now you can navigate to the standard Codeberg Pages URL to see it in action: - - USERNAME.codeberg.page - +~~~sh +USERNAME.codeberg.page +~~~ If you want to use your own custom domain (who doesn't?) then continue reading. @@ -52,18 +54,18 @@ If you want to use your own custom domain (who doesn't?) then continue reading. The first thing you will need to do is add a `.domains` file to your `pages` root directory. In this file you will want to list your custom domain on the first line, followed by the standard Codeberg pages URL below it. Like so: - - yourcustomdomain.com - USERNAME.codeberg.page - +~~~sh +yourcustomdomain.com +USERNAME.codeberg.page +~~~ I'm keeping this very basic, but I suggest you look further into the [official documentation](https://docs.codeberg.org/codeberg-pages/#custom-domains) if there are any extra settings you'd like to tinker with. The final step is configuring a `CNAME` DNS setting through your registrar: - - @ -> USERNAME.codeberg.page - +~~~sh +@ -> USERNAME.codeberg.page +~~~ Give the DNS settings a bit of time to take (24-48 hours) and you'll have your custom domain working just fine. diff --git a/posts/better-box-shadows.md b/posts/better-box-shadows.md index 76d62cd..c268a34 100644 --- a/posts/better-box-shadows.md +++ b/posts/better-box-shadows.md @@ -39,32 +39,33 @@ Box shadow on <abbr title="hypertext markup language">HTML</abbr> elements has b Let's take a look at a default configuration of `box-shadow`: - - .box-container { - box-shadow: 0 4px 8px rgba(0,0,0,0.3); - } - +~~~css +.box-container { + box-shadow: 0 4px 8px rgba(0,0,0,0.3); +} +~~~ In the example above the first property number is the origin of the *x-axis*, the second number is the origin of the *y-axis* and the third is the amount of *blur*. We should also add some minimal styling to cleanup the `.box-container` a little bit for our example: - - <div class="box-container"></div> - - - .box-container { - box-shadow: 0 4px 8px rgba(0,0,0,0.3); - /* Styles to make it less ugly */ - background: white; - border-radius: 10px; - border: 1px solid #eee; - height: 200px; - padding: 10px; - position: relative; - width: 250px; - } - +~~~html +<div class="box-container"></div> +~~~ + +~~~css +.box-container { + box-shadow: 0 4px 8px rgba(0,0,0,0.3); + /* Styles to make it less ugly */ + background: white; + border-radius: 10px; + border: 1px solid #eee; + height: 200px; + padding: 10px; + position: relative; + width: 250px; +} +~~~ Which would render as this: @@ -78,89 +79,87 @@ Not bad - but we can do a lot better than this. We just need to add a simple child `div` (or use a `pseudo` element if you prefer) inside our main element we want to apply the shadow to: - - <div class="box-container"> - <div class="box-container-inner"></div> - </div> - +~~~html +<div class="box-container"> + <div class="box-container-inner"></div> +</div> +~~~ Now we make our inner child element `absolute` and set it's `height` and `width` dynamically to be slightly smaller than it's parent (percentages work best for this). Remember to set this child element behind it's parent by adding `z-index: -1`. - - .box-container { - /* No box-shadow needed on this element anymore */ - /* Styles to make it less ugly */ - background: white; - border-radius: 10px; - border: 1px solid #eee; - height: 200px; - padding: 10px; - position: relative; - width: 250px; - } - +~~~css +.box-container { + /* No box-shadow needed on this element anymore */ + /* Styles to make it less ugly */ + background: white; + border-radius: 10px; + border: 1px solid #eee; + height: 200px; + padding: 10px; + position: relative; + width: 250px; +} +~~~ ## Inner Containers We also need to target the `box-container-inner` element set inside the current parent to reflect our custom shadow styling: - - .box-container-inner { - bottom: 0; - /* The box-shadow is added here now */ - box-shadow: 0 4px 12px rgba(0,0,0,0.3); - height: 94%; - left: 3%; - position: absolute; - width: 94%; - z-index: -1; - } - +~~~sh +.box-container-inner { + bottom: 0; + /* The box-shadow is added here now */ + box-shadow: 0 4px 12px rgba(0,0,0,0.3); + height: 94%; + left: 3%; + position: absolute; + width: 94%; + z-index: -1; +} +~~~ Which will make the drop-shadow render with a little more realistic depth: <div class="box-container-depth"><span class="box-container-depth-inner"></span></div> - - ## But wait - there's more! We could stop now and have a decent drop-shadow that is certainly easier on the eyes - but we can make this even better with one extra property - `filter:blur();`. So your final code would look like this: - - .box-container { - /* Styles to make it less ugly */ - background: white; - border-radius: 10px; - border: 1px solid #eee; - height: 200px; - padding: 10px; - position: relative; - width: 250px; - } - - .box-container-inner { - bottom: 0; - box-shadow: 0 4px 12px rgba(0,0,0,0.3); - filter: blur(6px); - height: 94%; - left: 3%; - position: absolute; - width: 94%; - z-index: -1; - } - +~~~css +.box-container { + /* Styles to make it less ugly */ + background: white; + border-radius: 10px; + border: 1px solid #eee; + height: 200px; + padding: 10px; + position: relative; + width: 250px; +} + +.box-container-inner { + bottom: 0; + box-shadow: 0 4px 12px rgba(0,0,0,0.3); + filter: blur(6px); + height: 94%; + left: 3%; + position: absolute; + width: 94%; + z-index: -1; +} +~~~ Which renders out into a much smoother blend of a drop-shadow, creating a more realistic illusion of depth: <div class="box-container-depth"> - <span class="box-container-depth-inner blur"></span> + <span class="box-container-depth-inner blur"></span> </div> diff --git a/posts/character-unit.md b/posts/character-unit.md index b88ad45..58b200b 100644 --- a/posts/character-unit.md +++ b/posts/character-unit.md @@ -12,28 +12,28 @@ By setting your main containers or text elements with the CSS character unit (`c Let's say you have an article which will fill the entire length of the screen. Something like this: - - <div class="container"> - <p>Reprehenderit aliqua in quis eiusmod ea culpa aliquip. Velit duis est irure voluptate occaecat labore laborum ut pariatur ex veniam deserunt esse est. Esse sunt exercitation id reprehenderit deserunt elit commodo sit ullamco amet commodo magna consequat. Excepteur voluptate tempor consectetur eu aliqua aliquip laboris aliquip veniam excepteur labore.</p> - <p>Voluptate excepteur sint magna ipsum occaecat irure sit. In occaecat excepteur in id ullamco id est incididunt irure et. Consectetur veniam exercitation occaecat exercitation labore nulla excepteur irure ex anim. Commodo sint anim non ad excepteur exercitation eiusmod Lorem nisi. Tempor ut ipsum do adipisicing dolore.</p> - </div> - +~~~html +<div class="container"> + <p>Reprehenderit aliqua in quis eiusmod ea culpa aliquip. Velit duis est irure voluptate occaecat labore laborum ut pariatur ex veniam deserunt esse est. Esse sunt exercitation id reprehenderit deserunt elit commodo sit ullamco amet commodo magna consequat. Excepteur voluptate tempor consectetur eu aliqua aliquip laboris aliquip veniam excepteur labore.</p> + <p>Voluptate excepteur sint magna ipsum occaecat irure sit. In occaecat excepteur in id ullamco id est incididunt irure et. Consectetur veniam exercitation occaecat exercitation labore nulla excepteur irure ex anim. Commodo sint anim non ad excepteur exercitation eiusmod Lorem nisi. Tempor ut ipsum do adipisicing dolore.</p> +</div> +~~~ With this structure, you might normally set the default `max-width` property with your desired maximum width (whatever you believe is the best reading length): - - .container { - max-width: 38em; - } - +~~~css +.container { + max-width: 38em; +} +~~~ This works - but it isn't ideal. Time for character units to save the day! You will still target the `max-width` property but this time we set it to use the `ch` value like so: - - .container { - max-width: 66ch; - } - +~~~css +.container { + max-width: 66ch; +} +~~~ This setting makes sure content will not exceed more than 66 characters per line, making for a better reading experience with little effort. diff --git a/posts/chasing-performance.md b/posts/chasing-performance.md index 0171f11..775456c 100644 --- a/posts/chasing-performance.md +++ b/posts/chasing-performance.md @@ -147,11 +147,11 @@ Webfonts I'm not using any webfonts but instead defaulting to the user's OS System Fonts. I love custom typefaces but performance takes just too much of a hit on my personal site to bother with them. - - body { - font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif,"Sans Serif",Icons; - } - +~~~css +body { +font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Open Sans","Helvetica Neue",sans-serif,"Sans Serif",Icons; +} +~~~ For reference, there are some things you should to look out for when using custom typefaces: @@ -170,8 +170,9 @@ On top of that, I decided to also implement Filament Group's <a href="https://gi My personal site only uses a small amount of JavaScript on the article post Jekyll template pages. By using the <code>defer</code> property I can be sure to load the <code>IntersectionObserver</code> API polyfill after the rest of the DOM as finished loading. - - <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver" defer> +~~~html +<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=IntersectionObserver" defer> +~~~ I could probably optimize this further by only calling these scripts if an image is actually present in the article post, but this fits my needs nicely as is. @@ -182,49 +183,50 @@ The only images I use are those included in supported blog posts, so the first s <span class="sidenote">I've also included responsive image sizes for further optimization based on screen size and loading speeds.</span> - - <figure> - <picture - <source type="image/webp" - data-srcset=" - /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_200.webp 200w, - /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_1400.webp 1400w" - class="lazyload"/> - <img - sizes="(max-width: 1400px) 100vw, 1400px" - data-srcset=" - /images/articles/flat-design-toggles_qfre51_c_scale,w_200.webp 200w, - /images/articles/flat-design-toggles_qfre51_c_scale,w_727.webp 727w, - /images/articles/flat-design-toggles_qfre51_c_scale,w_1065.webp 1065w, - /images/articles/flat-design-toggles_qfre51_c_scale,w_1400.webp 1400w" - src="/images/placeholder.webp" - alt="Toggles Comparison" - class="lazyload"/> - </picture> - </figure> +~~~html +<figure> +<picture> + <source type="image/webp" + data-srcset=" + /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_200.webp 200w, + /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_1400.webp 1400w" + class="lazyload"/> + <img + sizes="(max-width: 1400px) 100vw, 1400px" + data-srcset=" + /images/articles/flat-design-toggles_qfre51_c_scale,w_200.webp 200w, + /images/articles/flat-design-toggles_qfre51_c_scale,w_727.webp 727w, + /images/articles/flat-design-toggles_qfre51_c_scale,w_1065.webp 1065w, + /images/articles/flat-design-toggles_qfre51_c_scale,w_1400.webp 1400w" + src="/images/placeholder.webp" + alt="Toggles Comparison" + class="lazyload"/> +</picture> +</figure> +~~~ What about users with JavaScript disabled I hear you ask? It's time for <code>noscript</code> to save the day: - - <noscript> - <picture> - <source type="image/webp" - srcset=" - /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_200.webp 200w, - /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_1400.webp 1400w"> - <img - sizes="(max-width: 1400px) 100vw, 1400px" - srcset=" - /images/articles/flat-design-toggles_qfre51_c_scale,w_200.webp 200w, - /images/articles/flat-design-toggles_qfre51_c_scale,w_727.webp 727w, - /images/articles/flat-design-toggles_qfre51_c_scale,w_1065.webp 1065w, - /images/articles/flat-design-toggles_qfre51_c_scale,w_1400.webp 1400w" - src="/images/articles/flat-design-toggles_qfre51_c_scale,w_1400.webp" - alt="Toggles Comparison"/> - </picture> - </noscript> - +~~~html +<noscript> + <picture> + <source type="image/webp" + srcset=" + /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_200.webp 200w, + /images/articles/webp/flat-design-toggles_p0v2hv_c_scale,w_1400.webp 1400w"> + <img + sizes="(max-width: 1400px) 100vw, 1400px" + srcset=" + /images/articles/flat-design-toggles_qfre51_c_scale,w_200.webp 200w, + /images/articles/flat-design-toggles_qfre51_c_scale,w_727.webp 727w, + /images/articles/flat-design-toggles_qfre51_c_scale,w_1065.webp 1065w, + /images/articles/flat-design-toggles_qfre51_c_scale,w_1400.webp 1400w" + src="/images/articles/flat-design-toggles_qfre51_c_scale,w_1400.webp" + alt="Toggles Comparison"/> + </picture> +</noscript> +~~~ ### HTTPS & Caching diff --git a/posts/cheap-portable-pi.md b/posts/cheap-portable-pi.md index d571e0d..d77c110 100644 --- a/posts/cheap-portable-pi.md +++ b/posts/cheap-portable-pi.md @@ -96,16 +96,17 @@ I will be setting up this "portable pi" via [headless installation](https://www. - Next add an empty file named `wpa_supplicant.conf` - Open the `wpa_supplicant.conf` file in a code / text editor and paste the following (be sure to change `country` to your proper country code, as well as properly setting your network name / password): +~~~sh +ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev +update_config=1 +country=US - ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev - update_config=1 - country=US - - network={ - ssid="Your network name/SSID" - psk="Your WPA/WPA2 security key" - key_mgmt=WPA-PSK - } +network={ + ssid="Your network name/SSID" + psk="Your WPA/WPA2 security key" + key_mgmt=WPA-PSK +} +~~~ - Unmount the microSD device, then place the microSD card in your RPi Zero @@ -118,9 +119,9 @@ I will be setting up this "portable pi" via [headless installation](https://www. Open the terminal on your Raspberry Pi desktop and enter the following command: - - ssh pi@raspberrypi.local - +~~~sh +ssh pi@raspberrypi.local +~~~ You will then be asked if you wish to trust this device (say yes), then prompted for the `pi` user's password - which is `raspberry`. After a moment you will be directly connected to your Raspberry Pi Zero. Hooray! @@ -138,17 +139,19 @@ That's it! Next we will need to download and run the drivers needed for our 3.5-inch display to play nicely with our Pi Zero (just a blank white screen doesn't help us much). While connected to our RPi Zero via SSH, run the following commands: - wget http://kedei.net/raspberry/v6_1/LCD_show_v6_1_3.tar.gz +~~~sh +wget http://kedei.net/raspberry/v6_1/LCD_show_v6_1_3.tar.gz +~~~ If you have snail-paced rural internet like I do, now is a good time to go and grab a coffee while this download completes. Once the download has finished, extract the contents and navigate to the new directory and install the driver: - - sudo tar xzf LCD_show_v6_1_3.tar.gz - cd LCD_show_v6_1_3 - sudo ./LCD35_v - +~~~sh +sudo tar xzf LCD_show_v6_1_3.tar.gz +cd LCD_show_v6_1_3 +sudo ./LCD35_v +~~~ Once completed, the RPi Zero will reboot and everything should work as expected! diff --git a/posts/css-slope-graphs.md b/posts/css-slope-graphs.md index 8c3ce3a..b694933 100644 --- a/posts/css-slope-graphs.md +++ b/posts/css-slope-graphs.md @@ -16,45 +16,45 @@ For this concept we will actually be building this graph out of `tables` - crazy (But more on that in the CSS section) - - <p>Sales of the leading frozen pizza brands of the United States from 2011 to 2017 (in million US dollars) <br><em>Source: Statisa 2018</em></p> - <table> - <thead> - <tr> - <th>Pizza Brand</th> - <th>2011</th> - <th>2017</th> - </tr> - </thead> - <tbody> - <tr> - <td data-set="677.0">DiGiorno</td> - <td><span>677.0</span></td> - <td data-name="DiGiorno">1014.6</td> - </tr> - <tr> - <td data-set="294.8">Private Label</td> - <td><span>294.8</span></td> - <td data-name="Private Label">524.8</td> - </tr> - <tr> - <td data-set="286.1">Red Baron</td> - <td><span>286.1</span></td> - <td data-name="Red Baron">572.3</td> - </tr> - <tr> - <td data-set="257.9">Tombstone</td> - <td><span>257.9</span></td> - <td data-name="Tombstone">270.6</td> - </tr> - <tr> - <td data-set="164.5">Totino's Party Pizza</td> - <td><span>164.5</span></td> - <td data-name="Totino's Party Pizza">347.2</td> - </tr> - </tbody> - </table> - +~~~html +<p>Sales of the leading frozen pizza brands of the United States from 2011 to 2017 (in million US dollars) <br><em>Source: Statisa 2018</em></p> +<table> + <thead> + <tr> + <th>Pizza Brand</th> + <th>2011</th> + <th>2017</th> + </tr> + </thead> + <tbody> + <tr> + <td data-set="677.0">DiGiorno</td> + <td><span>677.0</span></td> + <td data-name="DiGiorno">1014.6</td> + </tr> + <tr> + <td data-set="294.8">Private Label</td> + <td><span>294.8</span></td> + <td data-name="Private Label">524.8</td> + </tr> + <tr> + <td data-set="286.1">Red Baron</td> + <td><span>286.1</span></td> + <td data-name="Red Baron">572.3</td> + </tr> + <tr> + <td data-set="257.9">Tombstone</td> + <td><span>257.9</span></td> + <td data-name="Tombstone">270.6</td> + </tr> + <tr> + <td data-set="164.5">Totino's Party Pizza</td> + <td><span>164.5</span></td> + <td data-name="Totino's Party Pizza">347.2</td> + </tr> + </tbody> +</table> +~~~ As you can see, nothing too fancy is happpening here. Pay close attention to the `data-set` and `data-name` variables though - those will be important for the CSS portion of this design, mainly the rendering of the line elements. @@ -64,36 +64,36 @@ As you can see, nothing too fancy is happpening here. Pay close attention to the To avoid overwhelming your brain all-at-once, let's break the CSS down into bite-sized chunks, starting with the base styling: - - @import url('https://opentype.netlify.com/et-book/index.css'); - * { - box-sizing: border-box; - } - - html { - height: 100%; - } - - body { - background: #fffff8; - font-family: "et-book", serif; - height: 100%; - margin: 0 auto; - max-width: 800px; - padding: 0 0.5rem; - } - - p { - font-size: 18px; - margin: 4rem 0 6rem; - } - - table { - border-collapse: collapse; - text-align: left; - width: 100%; - } - +~~~css +@import url('https://opentype.netlify.com/et-book/index.css'); +* { + box-sizing: border-box; +} + +html { + height: 100%; +} + +body { + background: #fffff8; + font-family: "et-book", serif; + height: 100%; + margin: 0 auto; + max-width: 800px; + padding: 0 0.5rem; +} + +p { + font-size: 18px; + margin: 4rem 0 6rem; +} + +table { + border-collapse: collapse; + text-align: left; + width: 100%; +} +~~~ Pretty basic stuff. @@ -106,122 +106,122 @@ Now we need to design how our slope graph will look on larger screens / desktops 5. Remember that `data-name` variable? We now use that for our `:before` pseudo element for `table tbody tr td:nth-of-type(3)` 6. After that, you can see the simple customization we include to render the angle / position of the slope lines and the corresponding labels - - @media(min-width:800px) { - table { - display: block; - position: relative; - margin-bottom: 25rem; - } - - table thead th { - border-bottom: 1px solid lightgrey; - font-size: 24px; - position: absolute; - top: -50px; - width: 45%; - } - table thead th:nth-child(1){ display: none; } - table thead th:nth-child(2){ left: 0; } - table thead th:nth-child(3){ right: 0; text-align: right; } - - table tbody tr td:nth-of-type(1), - table tbody tr td:nth-of-type(2) { position: absolute;} - - table tbody tr td:nth-of-type(2) span { display: none; } - table tbody tr td:nth-of-type(1):before { - content: attr(data-set); - margin-right: 10px; - position: relative; - } - - table tbody tr td:nth-of-type(2) { padding-left: 10px; } - - table tbody tr td:nth-of-type(3) { - position: absolute; - right: 0; - } - table tbody tr td:nth-of-type(3):before { - content: attr(data-name); - margin-right: 10px; - position: relative; - } - - /* Custom individual slopes -- Left */ - tbody tr:nth-child(1) td:nth-child(1), - tbody tr:nth-child(1) td:nth-child(2) { top: 60px; } - tbody tr:nth-child(2) td:nth-child(1), - tbody tr:nth-child(2) td:nth-child(2) { top: 140px; } - tbody tr:nth-child(3) td:nth-child(1), - tbody tr:nth-child(3) td:nth-child(2) { top: 165px; } - tbody tr:nth-child(4) td:nth-child(1), - tbody tr:nth-child(4) td:nth-child(2) { top: 220px; } - tbody tr:nth-child(5) td:nth-child(1), - tbody tr:nth-child(5) td:nth-child(2) { top: 270px; } - - /* Custom individual slopes -- Right */ - [data-name="DiGiorno"] { top: 0; } - [data-name="Red Baron"] { top: 65px; } - [data-name="Private Label"] { top: 100px; } - [data-name="Tombstone"] { top: 180px; } - [data-name="Totino's Party Pizza"] { top: 150px; } - - /* The custom visual lines */ - tbody tr:after { - background: black; - content: ''; - height: 1px; - left: 14.5%; - position: absolute; - width: 70%; - } - tbody tr:nth-child(1):after { - top: 40px; - transform: rotate(-6deg); - } - tbody tr:nth-child(2):after { - left: 17.5%; - top: 130px; - transform: rotate(-4deg); - width: 65%; - } - tbody tr:nth-child(3):after { - left: 15%; - top: 125px; - transform: rotate(-10.25deg); - width: 70%; - } - tbody tr:nth-child(4):after { - left: 16%; - top: 210px; - transform: rotate(-4deg); - width: 68%; - } - tbody tr:nth-child(5):after { - left: 22%; - top: 222px; - transform: rotate(-16deg); - width: 56%; - } - } - +~~~css +@media(min-width:800px) { + table { + display: block; + position: relative; + margin-bottom: 25rem; + } + + table thead th { + border-bottom: 1px solid lightgrey; + font-size: 24px; + position: absolute; + top: -50px; + width: 45%; + } + table thead th:nth-child(1){ display: none; } + table thead th:nth-child(2){ left: 0; } + table thead th:nth-child(3){ right: 0; text-align: right; } + + table tbody tr td:nth-of-type(1), + table tbody tr td:nth-of-type(2) { position: absolute;} + + table tbody tr td:nth-of-type(2) span { display: none; } + table tbody tr td:nth-of-type(1):before { + content: attr(data-set); + margin-right: 10px; + position: relative; + } + + table tbody tr td:nth-of-type(2) { padding-left: 10px; } + + table tbody tr td:nth-of-type(3) { + position: absolute; + right: 0; + } + table tbody tr td:nth-of-type(3):before { + content: attr(data-name); + margin-right: 10px; + position: relative; + } + + /* Custom individual slopes -- Left */ + tbody tr:nth-child(1) td:nth-child(1), + tbody tr:nth-child(1) td:nth-child(2) { top: 60px; } + tbody tr:nth-child(2) td:nth-child(1), + tbody tr:nth-child(2) td:nth-child(2) { top: 140px; } + tbody tr:nth-child(3) td:nth-child(1), + tbody tr:nth-child(3) td:nth-child(2) { top: 165px; } + tbody tr:nth-child(4) td:nth-child(1), + tbody tr:nth-child(4) td:nth-child(2) { top: 220px; } + tbody tr:nth-child(5) td:nth-child(1), + tbody tr:nth-child(5) td:nth-child(2) { top: 270px; } + + /* Custom individual slopes -- Right */ + [data-name="DiGiorno"] { top: 0; } + [data-name="Red Baron"] { top: 65px; } + [data-name="Private Label"] { top: 100px; } + [data-name="Tombstone"] { top: 180px; } + [data-name="Totino's Party Pizza"] { top: 150px; } + + /* The custom visual lines */ + tbody tr:after { + background: black; + content: ''; + height: 1px; + left: 14.5%; + position: absolute; + width: 70%; + } + tbody tr:nth-child(1):after { + top: 40px; + transform: rotate(-6deg); + } + tbody tr:nth-child(2):after { + left: 17.5%; + top: 130px; + transform: rotate(-4deg); + width: 65%; + } + tbody tr:nth-child(3):after { + left: 15%; + top: 125px; + transform: rotate(-10.25deg); + width: 70%; + } + tbody tr:nth-child(4):after { + left: 16%; + top: 210px; + transform: rotate(-4deg); + width: 68%; + } + tbody tr:nth-child(5):after { + left: 22%; + top: 222px; + transform: rotate(-16deg); + width: 56%; + } +} +~~~ All that's left are some minor styles to make everything look nice on mobile: - - @media(max-width:800px) { - p { - margin: 2rem 0; - } - table td, table th { - border-bottom: 1px solid grey; - padding: 10px; - } - table td:last-of-type, table th:last-of-type { - text-align: right; - } - } - +~~~css +@media(max-width:800px) { + p { + margin: 2rem 0; + } + table td, table th { + border-bottom: 1px solid grey; + padding: 10px; + } + table td:last-of-type, table th:last-of-type { + text-align: right; + } +} +~~~ ## Not the most practical This slope graph concept is far from perfect for use in real-world situations. The fact that you need to manually render each point of data yourself makes this implementation quite annoying for more in-depth projects. diff --git a/posts/css-variables.md b/posts/css-variables.md index dff8f13..17df49f 100644 --- a/posts/css-variables.md +++ b/posts/css-variables.md @@ -8,12 +8,12 @@ The CSS language is becoming even more awesome and powerful everyday. In this qu Let's just jump right in - this is how you create variables in vanilla CSS: - - :root { - --base-color: #e0e0e0; - --text-color: #111; - } - +~~~css +:root { + --base-color: #e0e0e0; + --text-color: #111; +} +~~~ We are using the `:root` selector at the very top of our CSS file in order to call these variables into any elements in the rest of our document. This is normally the safest way to include variables. @@ -21,16 +21,16 @@ As for the variables themselves, you declare that they are variables using the ` Now let's use those variables: +~~~css +.header { + border: 1px solid var(--base-color); +} - .header { - border: 1px solid var(--base-color); - } - - .main-container { - background-color: var(--base-color); - color: var(--text-color); - } - +.main-container { + background-color: var(--base-color); + color: var(--text-color); +} +~~~ That's it! It's also good to know that CSS variables have pretty decent [browser support](https://caniuse.com/#feat=css-variables) (who likes IE11 anyway). diff --git a/posts/current-color.md b/posts/current-color.md index bb9fe99..1e82067 100644 --- a/posts/current-color.md +++ b/posts/current-color.md @@ -10,27 +10,27 @@ Let's assume with have a single div with the following properties: - - div { - color: dodgerblue; - } - +~~~css +div { + color: dodgerblue; +} +~~~ If we wanted to use that same color for other properties on elements inside that initial `div`, it's simple - we just need to call `currentColor` like so: +~~~css +div { + color: dodgerblue; +} - div { - color: dodgerblue; - } - - div header { - background-color: currentColor; - } - - div a { - border-bottom: 1px solid currentColor; - } +div header { + background-color: currentColor; +} +div a { + border-bottom: 1px solid currentColor; +} +~~~ **Sidenote**: If you re-declare the default `color` property further along in your CSS, the `currentColor` value will update according to the last color set. diff --git a/posts/default-brower-forms.md b/posts/default-brower-forms.md index 804e656..ffe928a 100644 --- a/posts/default-brower-forms.md +++ b/posts/default-brower-forms.md @@ -16,61 +16,62 @@ This form isn't going to win any design awards or blow anyone away with its crea Let's take a look at the HTML of the entire form: - - <form action=""> - <fieldset> - <legend>Personal Details</legend> - <label for="username">Desired Username:</label> - <input type="text" id="username"> - <label for="name">Full Name:</label> - <input type="text" id="name"> - <label for="email">Email Address:</label> - <input type="email" id="email"> - <label for="date">Date of Birth:</label> - <input type="date" id="date"> - </fieldset> - <br> - <fieldset> - <legend>Contact Details</legend> - <label for="address">Home Address:</label> - <input type="text" id="address"> - <label for="postal">Postal Code:</label> - <input type="text" id="postal"> - <label for="phone">Phone Number:</label> - <input type="tel" id="phone"> - </fieldset> - <br> - <fieldset> - <legend>Select an Option</legend> - <label for="radio-1"> - <input type="radio" id="radio-1" name="radio-choice"> - The option is pretty nice - </label> - <label for="radio-2"> - <input type="radio" id="radio-2" name="radio-choice"> - This option is a little bit better - </label> - <label for="radio-3"> - <input type="radio" id="radio-3" name="radio-choice"> - This option is the best - </label> - </fieldset> - <br> - <fieldset> - <legend>Notifications</legend> - <label for="checkbox-1"> - <input type="checkbox" id="checkbox-1"> - I would like to receive email notifications - </label> - <label for="checkbox-2"> - <input type="checkbox" id="checkbox-2"> - I would like to subscribe to the weekly newsletter - </label> - </fieldset> - <br> - <input type="reset" value="Reset"> - <input type="submit" value="Submit"> - </form> +~~~html +<form action=""> + <fieldset> + <legend>Personal Details</legend> + <label for="username">Desired Username:</label> + <input type="text" id="username"> + <label for="name">Full Name:</label> + <input type="text" id="name"> + <label for="email">Email Address:</label> + <input type="email" id="email"> + <label for="date">Date of Birth:</label> + <input type="date" id="date"> + </fieldset> + <br> + <fieldset> + <legend>Contact Details</legend> + <label for="address">Home Address:</label> + <input type="text" id="address"> + <label for="postal">Postal Code:</label> + <input type="text" id="postal"> + <label for="phone">Phone Number:</label> + <input type="tel" id="phone"> + </fieldset> + <br> + <fieldset> + <legend>Select an Option</legend> + <label for="radio-1"> + <input type="radio" id="radio-1" name="radio-choice"> + The option is pretty nice + </label> + <label for="radio-2"> + <input type="radio" id="radio-2" name="radio-choice"> + This option is a little bit better + </label> + <label for="radio-3"> + <input type="radio" id="radio-3" name="radio-choice"> + This option is the best + </label> + </fieldset> + <br> + <fieldset> + <legend>Notifications</legend> + <label for="checkbox-1"> + <input type="checkbox" id="checkbox-1"> + I would like to receive email notifications + </label> + <label for="checkbox-2"> + <input type="checkbox" id="checkbox-2"> + I would like to subscribe to the weekly newsletter + </label> + </fieldset> + <br> + <input type="reset" value="Reset"> + <input type="submit" value="Submit"> +</form> +~~~ Notice the `fieldset` and `legend` elements? I bet you don't see or hear about those HTML items very often. By default, `fieldset` allows sibling or related inputs to be semantically grouped together. The `legend` elements give the user great visual cues about which items are grouped together, helping to focus on each section individually as they complete the form. Use these grouping elements as much as possible (when it makes sense of course) for a better guided experience for your users. @@ -80,23 +81,23 @@ Avoid making your own custom sections and instead use these existing HTML semant Now it's time to style this form with only 6 property declarations: - - form label { - display: block; - } - form input { - display: inline-block; - margin-bottom: 10px; - padding: 10px; - width: 100%; - } - form input[type="radio"], - form input[type="checkbox"], - form input[type="reset"], - form input[type="submit"] { - width: auto; - } - +~~~css +form label { + display: block; +} +form input { + display: inline-block; + margin-bottom: 10px; + padding: 10px; + width: 100%; +} +form input[type="radio"], +form input[type="checkbox"], +form input[type="reset"], +form input[type="submit"] { + width: auto; +} +~~~ Of course, you can always add minor adjustments (like in my demo example above) diff --git a/posts/default-html-style-updates.md b/posts/default-html-style-updates.md index a8dad93..85a807b 100644 --- a/posts/default-html-style-updates.md +++ b/posts/default-html-style-updates.md @@ -10,48 +10,48 @@ But that doesn't mean some minor, modern improvements couldn't be made... A little extra breathing room for a website's content never hurts. Browser defaults set the inner content too close to the main window borders, creating mild eye strain to focus on the far edges of the screen when reading. Pair this with a typeface set too small and you've got a recipe for disaster (in terms of user experience and accessibility). Luckily for us, adding two basic CSS properties fixes all of our readability woes. All that is required is a simple boost to the existing `margin` property set on the `body` element (I personally lean towards a very specific `1.5em`) and overriding the default `font-size` to `18px`[^1]: - - body { - font-size:18px; - margin:1.5em; - } - +~~~css +body { + font-size:18px; + margin:1.5em; +} +~~~ There is one *small* caveat with setting the `font-size` across the whole `body` element: code elements set in `monospace`. They will stand out larger than the other fonts found in the document (due to variations in different typeface heights, spacing etc.) so we will need to target these elements specifically: - - code { - font-size:14px; - /* Word wrap is optional if you plan to have long inline code snippets */ - word-wrap:break-word; - } - +~~~css +code { + font-size:14px; + /* Word wrap is optional if you plan to have long inline code snippets */ + word-wrap:break-word; +} +~~~ ## Code & Pre Tags Since we've mentioned `code` elements, let's fix those as well. The existing styling for inline code snippets and larger pre-formatted text sections leave a lot to be desired. They don't provide any means to wrap their inner content or make use of `overflow` properties to avoid vertically scrolling on smaller device screens. Sharing code examples becomes quite a pain when your webpage's flow and layout is broken just by including them. Browsers could fix this easily enough by defaulting to: - - pre { - overflow:auto; - } - +~~~css +pre { + overflow:auto; +} +~~~ ## Basic Dark Mode Support Barebones styling in current web browsers have no sane defaults[^2] for system-level dark mode. What a huge letdown. This is where the most "drastic" changes will be implemented with our browser default updates. We will need the browser to change the main `background-color`, along with resetting both the text and anchor link `color` for improved accessibility. Browser defaults for anchor link color in "light mode" are blue/purple - so I've opted towards using gold, orange and orangered in dark mode respectively: - - /* Dark mode */ - @media (prefers-color-scheme: dark) { - @media not print { - html {background:#0e0e0e;color:#e1e1e1; } - a {color: gold;} - a:visited {color: orange;} - a:hover,a:focus{color: orangered;} - } - } - +~~~css +/* Dark mode */ +@media (prefers-color-scheme: dark) { + @media not print { + html {background:#0e0e0e;color:#e1e1e1; } + a {color: gold;} + a:visited {color: orange;} + a:hover,a:focus{color: orangered;} + } +} +~~~ That is probably the most streamlined dark mode on the web... @@ -65,26 +65,26 @@ Do you want to know an incredible feature built into browsers? *Window resizing* There isn't much else to say, really. I think these tiny tweaks would greatly improve the default browser experience and maybe even convince others to just *use* these defaults instead of falling down the CSS rabbit hole (as fun as that might be sometimes). For easier convenience, I'll leave the full set of CSS changes below: - - body { - font-size:18px; - margin:1.5em; - } - code { - font-size:14px; - } - pre { - overflow:auto; - } - @media (prefers-color-scheme: dark) { - @media not print { - html {background:#0e0e0e;color:#e1e1e1; } - a {color: gold;} - a:visited {color: orange;} - a:hover,a:focus{color: orangered;} - } - } - +~~~css +body { + font-size:18px; + margin:1.5em; +} +code { + font-size:14px; +} +pre { + overflow:auto; +} +@media (prefers-color-scheme: dark) { + @media not print { + html {background:#0e0e0e;color:#e1e1e1; } + a {color: gold;} + a:visited {color: orange;} + a:hover,a:focus{color: orangered;} + } +} +~~~ [^1]: `18px` seems to be the perfect sweet spot between "almost too large, yet not small enough to strain my eyes" [^2]: At the time of this article's publish date diff --git a/posts/dv.md b/posts/dv.md index 476cdf9..c243eca 100644 --- a/posts/dv.md +++ b/posts/dv.md @@ -6,18 +6,19 @@ I think it's safe to assume most web designers and developers are familiar with If I want my `.box` element to take up the entire height of a device's screen: - - .box { - height: 100vh; - } - +~~~css +.box { + height: 100vh; +} +~~~ Or I want my `.box` element to take up the entire width of a device's screen: - - .box { - width: 100vw; - } +~~~css +.box { + width: 100vw; +} +~~~ These are wonderful options to have - specifically for those of us designing web applications. But there are some *minor* issues with `vh` and `vw`. @@ -33,12 +34,12 @@ Lucky for us there exists an awesome *new-ish* CSS API called dynamic viewport-p So our examples above would translate into: - - .box { - height: 100dvh; - width: 100dvw; - } - +~~~css +.box { + height: 100dvh; + width: 100dvw; +} +~~~ ### What About Browser Support? diff --git a/posts/git-patches.md b/posts/git-patches.md index 2618e6f..5b5d951 100644 --- a/posts/git-patches.md +++ b/posts/git-patches.md @@ -16,9 +16,9 @@ Next, locate the email patch in Evolution and right-click on it. Select "Save as Now simply open your terminal, navigate to your project and run: -``` +~~~sh git am <path-to-patches-folder>/<patch-filename>.mbox -``` +~~~ This should apply the patch directly to your project without issue. You are now free to test these changes locally. If everything looks good, you're able to instantly push these changes remotely. diff --git a/posts/heif.md b/posts/heif.md index f0d645a..32a8166 100644 --- a/posts/heif.md +++ b/posts/heif.md @@ -24,12 +24,12 @@ For this example script we are going to convert the image to JPG format. You can 7. Set the area "Pass input" to `as arguments` 8. Enter the following code below as your script and type `⌘-S` to save (name it something like "Convert HEIC/HEIF to JPG") -``` +~~~sh for f in "$@" do /opt/homebrew/bin/heif-convert "$f" "${f%.*}.jpg" done -``` +~~~ ## Making Edits diff --git a/posts/html-dark-mode.md b/posts/html-dark-mode.md index 224699f..0d94def 100644 --- a/posts/html-dark-mode.md +++ b/posts/html-dark-mode.md @@ -11,9 +11,9 @@ this created by *jacksonchen666*: [These 3 Lines of CSS Will Give You Dark Mode But today I wanted to show how to add dark mode functionality to a website without *any CSS at all*. -``` +~~~sh <meta name="color-scheme" content="dark light"> -``` +~~~ Add that line inside the `head` tags on your HTML files and you're good to go. diff --git a/posts/mail.md b/posts/mail.md index d50e5a5..96950e6 100644 --- a/posts/mail.md +++ b/posts/mail.md @@ -26,15 +26,15 @@ Inside this folder you should see something similar to the following structure: Once saved, open your terminal, navigate to the project you wish to apply this new patch to: -``` +~~~sh cd my-path/very-cool-project -``` +~~~ and then run: -``` +~~~sh git apply ~/Patches/<saved-patches-mailbox-folder>/mbox -``` +~~~ Congrats! You've successfully applied a git email patch through Apple Mail! Well, kind of. The terminal did most of the *real* work. Just be sure to periodically *purge* your local *Patches* folder to keep things clean! diff --git a/posts/mongodb-arch.md b/posts/mongodb-arch.md index 45babac..1b74463 100644 --- a/posts/mongodb-arch.md +++ b/posts/mongodb-arch.md @@ -12,16 +12,16 @@ So I thought I would share my process of setting up an older version of MongoDB You will need to target the specific version of MongoDB using the very awesome AUR packages: -``` +~~~sh yay -S mongodb34-bin -``` +~~~ Follow the instructions and you'll be good to go. Don't forget to create the `/data/db` directory and give it proper permissions: -``` +~~~sh mkdir -p /data/db/ chmod -R 777 /date/db -``` +~~~ ## What About My "Tools"? @@ -29,16 +29,16 @@ If you plan to use MongoDB, then you most likely want to utilize the core databa So, you'll have to build from source locally: -``` +~~~sh git clone https://github.com/mongodb/mongo-tools cd mongodb-tools ./make build -``` +~~~ Then you'll need to copy the built executables into the proper directory in order to use them from the terminal: -``` +~~~sh cp bin/* /usr/local/bin/ -``` +~~~ And that's it! Now you can run `mongod` directly or use `systemctl` to enable it by default. Hopefully this helps anyone else curious about running older (or even outdated!) versions of MongoDB. diff --git a/posts/my-pi-desktop.md b/posts/my-pi-desktop.md index e5daee0..083d578 100644 --- a/posts/my-pi-desktop.md +++ b/posts/my-pi-desktop.md @@ -81,9 +81,9 @@ Since *actual* data speaks louder than anecdotal chit-chat, I performed a very s First, clear the cache to avoid conflicting data: -``` +~~~sh sync; echo 3 | sudo tee /proc/sys/vm/drop_caches -``` +~~~ ### Write diff --git a/posts/obvious-js-injection-fallback.md b/posts/obvious-js-injection-fallback.md index 78d7df9..366fcfe 100644 --- a/posts/obvious-js-injection-fallback.md +++ b/posts/obvious-js-injection-fallback.md @@ -12,17 +12,17 @@ Let's pretend that we have a total tally that pulls in the number of current use Here we create an empty `h2` tag that will update with the current number of users via js: -```html +~~~html <main> <h2 class="total-tally"></h2> </main> -``` +~~~ ### Javascript You'll have to use your imagination here and assume that the `totalTally` variable pulls in the numbers dynamically via API: -~~~js +~~~html var totalTally = "273,677" /* This would pull something dynamically in prod */ document.getElementsByClassName("total-tally")[0].innerHTML=totalTally; ~~~ diff --git a/posts/openring.md b/posts/openring.md index 42ac0d8..cbb6c3e 100644 --- a/posts/openring.md +++ b/posts/openring.md @@ -12,9 +12,9 @@ So, I thought others might be interested in how I've implemented openring throug You can pull the project [directly via SourceHut](https://sr.ht/~sircmpwn/openring/) if you wish, but I would recommend installing through your default package manager. I'm running Arch, so for me it was as simple as running: -``` +~~~sh yay -S openring -``` +~~~ That's it. I now have full local access to openring! diff --git a/posts/rvm.md b/posts/rvm.md index 50610fb..fb78025 100644 --- a/posts/rvm.md +++ b/posts/rvm.md @@ -10,31 +10,31 @@ So this post is more or less a helpful document for my future self. If it happen Make sure you have the basic packages first: -``` +~~~sh apk update apk add curl gcc gnupg gpg dirmngr procps musl-dev linux-headers zlib zlib-dev openssl openssl-dev libssl1.1 -``` +~~~ Next download the latest `stable` version of `rvm` from Github, unpack it, place it in the proper user directory (~/.rvm) and install any required libs: -``` +~~~sh curl -sSL https://github.com/rvm/rvm/tarball/stable -o rvm-stable.tar.gz echo 'export rvm_prefix="$HOME"' > ~/.rvmrc echo 'export rvm_path="$HOME/.rvm"' >> ~/.rvmrc mkdir rvm && cd rvm tar --strip-components=1 -xzf ../rvm-stable.tar.gz ./install --auto-dotfiles --autolibs=0 -``` +~~~ Now we can remove everything and properly link to `rvm`: -``` +~~~sh cd ../ && rm -rf rvm-stable stable.tar.gz rvm source ~/.rvm/scripts/rvm -``` +~~~ Now you can freely install any version of Ruby that you desire! -``` +~~~sh rvm install ruby-X.X.X -``` +~~~ diff --git a/posts/sublime.md b/posts/sublime.md index 2cfedd4..4a203cb 100644 --- a/posts/sublime.md +++ b/posts/sublime.md @@ -20,31 +20,31 @@ You'll need to install flatpak, give your current user permission to install fla (The following snippets assume you are using `doas`. If you are using `sudo`, be sure to swap accordingly) -``` +~~~sh apk add flatpak adduser <YourUsername> flatpak flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo -``` +~~~ Congrats. You now have setup `flatpak` on your machine! Next we install Sublime Text: -``` +~~~sh flatpak install flathub com.sublimetext.three -``` +~~~ You could stop now and simply open Sublime anytime by running the following command in your terminal: -``` +~~~sh flatpak run com.sublimetext.three -``` +~~~ This works perfectly fine but I find it a little cumbersome. I would much rather open my programs directly through dmenu. Let's set that up. ## Creating System Links -``` +~~~sh doas ln -s ~/.local/share/flatpak/exports/bin/com.sublimetext.three /usr/bin/sublimetext -``` +~~~ Now that those directories are linked, simply open dmenu and start typing `sublimetext`. Done and done. No more terminal commands needed to open Sublime! diff --git a/posts/vscode.md b/posts/vscode.md index 289d8ce..9b3d0bb 100644 --- a/posts/vscode.md +++ b/posts/vscode.md @@ -14,20 +14,20 @@ Getting things to work seamlessly proved a little more challenging. I found the First we need to disable [unveil](https://man.openbsd.org/unveil.2) for Chromium. This will allow us to access our system files through [vscode.dev](https://vscode.dev) using the "Open folder..." or "Open file..." commands without issue: -``` +~~~sh chrome --disable-unveil -``` +~~~ Everything should work pretty solid right out the box now - except it doesn't. Syntax highlighting does not work without enabling WASM/WebAssembly. Your experience might be different, but I had to include the following when launching Chromium from the terminal: -``` +~~~sh ENABLE_WASM=1 chrome --enable-wasm -``` +~~~ Success! We can avoid typing out these complex commands everytime we want to launch our editor by setting up an `alias` (in my case via `.zshrc`): -``` +~~~sh alias vscode="ENABLE_WASM=1 chrome --enable-wasm --disable-unveil" -``` +~~~ That's it! Now I can just pop open VSCode on OpenBSD by simply running `vscode` in my terminal. Hopefully this can help others slowly transition over to OpenBSD - which you should do because it is amazing!
\ No newline at end of file |