Я думаю, всем нам иногда бывает интересно, как тот или иной человек развивался и как начинал путь. Когда объектом интереса стану я, мне бы хотелось, чтобы это было реализовано удобно для всех и с доступностью прямо с сайта.
Именно для этого и создан данный раздел на сайте. Вы можете, во-первых, по дням отследить, как и что я изучал, с самого первого дня развития в формате ленты. Во-вторых, вы можете посмотреть, как в тот или иной день выглядел сайт. На момент создания этой страницы он представлял из себя голый HTML-документ — однако кто знает, каким будет сайт в будущем? =)
Обучение по дням
День 13: легендарное возвращение!
А что случилось?
Я начал отдыхать и в итоге проотдыхал целый месяц. xDD Зато 150 подписчиков в тиктоке набрал! Как бы то ни было, возвращаться надо (рано или поздно). Сейчас буду немного как слепой котёнок, правда, но да ладно! Для начала, хотелось бы кратко обозначить, что успело произойти за время отсутствия:
Я получил аттестат и подал заявление в колледж
С получением всех результатов экзаменов мне выдали обычный синий аттестат, в котором все оценки были отличными. Синий он был в связи с тем, что я не подтвердил свои знания на ЕГЭ. Выпускной прошёл спокойно, в кафе я со всеми не ходил — пьяные лица не жалую и хорошо себя в их окружении чувствовать не могу. =) Но я прошёл медкомиссию для колледжа (бо-о-же, никому не пожелаю улицезреть эти очереди!) и подал заявление на поступление в местный агротехнический колледж через госуслуги, прикрепив справку о здоровье, СНИЛС, аттестат и фотку. Поступление будет ещё 26 дней идти, но я на данный момент первый по среднему баллу аттестата на интересующем меня направлении. Скоро нужно будет съездить и отдать им аттестат. ;)
Моя будущее фото в студенческом билете (сделал его на камеру телефона и подправил с помощью ИИ)
Я начал постить вертикальный контент
Я добавил пару друзей из реально жизни в свой тикток, и внезапно о канале узнала куча ребят из школы. Я очень рад их поддержке, но иногда неловко в связи с этим бывает. 🥲 По большей части я сейчас пощу лайфстайл, но хотелось бы перейти всё же на постинг по веб-разработке.
Мой TikTok
Я продал ПК и периферию
Я наконец-то смог продать его! За 77 000 ₽ у меня ушли ПК, монитор и мышка с клавиатурой. На полученные деньги я купил себе стол с подъёмным механизмом, штуки для кабель-менеджмента, кучу уходовой косметики и игры в стиме.
День 12: начало курса по CSS
А почему только день 12? Неужто отдыхал все остальные дни? 👀
Каюсь, друзья, отдыхал и бездельничал почти две недели! 😔✌️ Но сегодня возвращаюсь в строй с новой силой. Работать я буду с курсом по CSS на канале FreeCodeCamp от Дэйва Грэя, и идёт он (курс, не Дэйв) немногим больше 11 часов. Бо-о-оже, и что там 11 часов изучать можно?.. Как бы то ни было, разберусь, конечно, но масштаб внушительный на первый взгляд.
Выглядеть всё это будет немного странно поначалу, поэтому те правила, которые я добавляю, чтобы выполнить задачу с курса, я буду помещать в конец своего CSS-файла, а теги, на которые эти новичковские попытки в CSS, будут влиять, все будут аккуратно обёрнуты в класс experimental-css. Что ж, работаем!
Таинственный цвет проник на мой сайт вместе со странного размера текстом!
Дни 10—11: ЕГЭ, завершение работы с кнопками и формами и ещё немного лоска с помощью CSS
Дата публикации:
Так что там с ЕГЭ?
С ЕГЭ всё отлично!
Предмет
Количество баллов
Русский язык
61
Математика (профильная)
58
Информатика
20*
* На момент написания статьи официального результата не было; но я сделал только 3 задания, и 20 — это самый лучший расклад. xD **
** Апдейт от : настоящий результат был 14 баллов 👽
У некоторых может возникнуть справедливый вопрос: и как же это всё отлично, если информатика де-факто не сдана, а по другим двум предметам тоже мало баллов? Дело в том, что я иду в колледж и не иду в вуз. Мне нужен только аттестат, так что я не переживаю. В колледжах не спрашивают баллы ЕГЭ. 😝 Дальше мне нужно будет получить медицинское заключение для колледжа — 3517 ₽, на минуточку! — после чего смогу подавать документы.
Больше кнопок и форм богу кнопок и форм!
Да… возвращаемся к ВОТ ЭТИМ ВОТ. 😩
Бо-о-оже, это было ужасно! Пока запомнишь, как всё это работает, нужно будет это не один раз повторить. Впрочем, никто ничего не запоминает раз и навсегда; в пору интернета всегда есть возможность проверить и уточнить, верно? ;)
Обновление в CSS и немного в доступности
Сегодня я освоил max-width, line-height, padding и ещё некоторую красоту, которая позволила сделать сайт лучше. :> Текст больше не растягивается на всю страницу, а аккуратно располагается в центре; также он стал побольше, а межстрочный интервал приобрёл более удобочитаемый вид. 🌸
По доступности: прогнав свой сайт через Google Lighthouse, я понял, что в моментах, где я даю описание картинок и ссылки на страницы картинок в Pexels, люди со скринридерами получают набор ссылок, которые звучат абсолютно одинаково. (Они слышат что-то вроде «копирайт, [имя сделавших фотографию] на „ссылка: Pexels“». Получается какая-то каша: предлог «на» смешивается со словом «ссылка», а слово Pexels не даёт много информации.) Было придумано изящное и более корректное с точки зрения семантики решение: у тега <a> можно задавать название с помощью aria-label. Теперь человек будет слышать «копирайт, [имя сделавших фотографию]; „ссылка: Часовня тишины на Pexels“». Предлог «на» я убрал от людей без скринридеров, заменив его на длинное тире — выглядит оно даже более профессионально. B)
День 9: кнопки, формы и прочие ужасы, которые за один раз не запомнишь…
Дата публикации:
Кнопки и формы (будь они неладны!)
Всех приветствую! Хотелось бы выйти на режим ежедневных коммитов (мечтать не вредно! 😝), поэтому активно учусь дальше.
Сегодня, после наведения финального лоска в CSS — да, Джеминай мне всё предлагает и предлагает кучу симпатичного, а я всё не против и не против, — я наконец-то возвращаюсь к курсу от FreeCodeCamp по HTML! Следующая тема… о-о-ой, формы и кнопки… Я помню, как я был поражён количеству полученной информации, когда у меня была первая и менее публичная попытка в веб-разработку с курсом уже от BroCode. Надеюсь, в этот раз будет попроще. Хотя длина этого урока на таймлайне не вызывает доверия. 🥲 Попробуем?..
Важное примечание: все формы липовые и мне не приходят на данный момент!
Окей, чат, завтра мне на экзамен последний (конечно, я ничего не знаю и ничего не напишу), так что пойду уже спать. git push origin main и до завтра! 🍓
Дни 5—8: внезапная оптимизация картинок, первые шажки в CSS и ИИ
Дата публикации:
Доведения до ума раздела об истории развития сайта
Что? Да! Я решил, что такой раздел должен быть прямо на сайте с возможностью взглянуть, как всё выглядело в тот или иной день. Вы, вероятно, прямо с неё читаете данный текст. Здесь будут история по дням изучения и история в виде полноценных снапшотов — копий сайта за тот или иной день. Они находятся в самом низу. Внизу этих снапшотов была добавлена подпись о том, что это архивная версия сайта, и кнопки перехода от одного снапшота к следующему и предыдущему — Джеминай мне помог сделать это покрасивее.:>
Желание публиковаться на GitHub
Где-то 4 дня назад я решил, что было бы круто разместить свой сайт на гитхабе, потому что он позволяет опубликовать сайт бесплатно, даже не оплачивая никакого хостинга. После этого начинается самое интересное…
Во-первых, надо выбрать лицензию. ИИ предлагает как универсальный вариант лицензию от MIT, но я вспоминаю, что слышал легенды про лицензии GNU и восхищался. Погуглив, я решил, что буду брать AGPLv3. Она хороша тем, что любой человек, который решит работать с моим кодом, будет обязан опубликовать все свои изменения; иначе я буду иметь право его засудить. 🫦 Вот она: свобода кода любой ценой!
Но с такой лицензией я дважды задумался над картинками, которые были у меня на сайте, а именно шуточные скриншоты из GTA в контексте мест, которые мне бы хотелось посетить. Уж не знаю, мог бы я в будущем заинтересовать Rockstar, но, если я правильно понимаю, это одна из компаний с вредными юристами, поэтому я решил не рисковать и брать свободные для распространения фотографии с Pexels. Отлично, с интеллектуальной собственностью — будь оно проклята! — мы разобрались. Теперь можно просто вставить картинки, верно?.. Ну… не совсем.
Оптимизация размера изображений
Итак, загружать оригинал в 2 МиБ — это неприемлемо по нынешним веб-стандартам. Я поговорил об этом с Чатом — ChatGPT, — и тот предложил мне bash-скрипт для сжатия. И после этого я упал в кроличью нору… Я думал расписать подробно, как и насколько разные ИИ мне помогли в создании скрипта, но мне кажется, что это будет излишним. Больше всего мне помогли Джеминай и Клод; первую заготовку сделал Чат, Грок тоже внёс пару правок, но начал слишком быстро просить денег и ограничивая наш чат на 8 часов. Клод выглядел самым способным по коду, хотя Джеминай не отставал (по крайней мере в работе с этим конкретным bash-скриптом) и был разве что подружелюбнее. Но! С Клодом был интересный диалог:
— У меня опять горят глаза насчёт картинок. 🫦 Как это можно реализовать в нашем имеющемся скрипте? 🤔
— Нет. 😄
Серьёзно — сначала напиши хоть одну страницу. Ты не знаешь ещё какие размеры тебе нужны, как картинки будут вписаны в макет, какие брейкпоинты ты выберешь. Дописывать скрипт под размеры которые ты не знаешь — это работа вслепую.
Когда сделаешь первый макет и увидишь что картинка на мобильном занимает 480px, а на десктопе 1200px — вот тогда приходи, добавим за пять минут.
Впервые ИИ мне отказал! Дальше я всё же смог его убедить мне помочь, сказав, что у меня уже есть несколько страниц, но это было интересно. А отказ, если честно, по делу. Как бы то ни было, теперь у меня есть скрипт, который при первом запуске спрашивает, в где хранится директория img, а при втором уточняет, в какую поддиректорию загружать конкретные файлы. Дальше он спрашивает, насколько агрессивную стратегию сжатия использовать; после этого он делает своё дело, сохраняя в директорию /original оригинал изображения, а на директорию выше кидает 7 файлов (каждый меньше 250 КиБ): AVIF и WEBP для экранов смартфонов (640 px), для экранов маленьких ноутбуков и планшетов (1200 px) и для десктопа (1920 px) и JPEG (чтобы в случае чего загрузилось даже на древнейших девайсах), давая в терминале сразу вывод для HTML-файла.
Раз уж такое дело, неудобно будет не разместить прямо здесь эти картинки! (Заодно взгляну, как сделать так, чтобы картинки занимали не пол-экрана.)
Делюсь не без удовольствия кодом прямо здесь. 💫 (Надеюсь, меня не загрызут люди, которые, не знаю, стояли за созданием bash… кто знает, кто среди читателей будет? Как бы то ни было, это вайб-кодинг — не судите строго. 😝)
Открывайте и используйте на свой страх и риск! 👀
#!/bin/bash
set -euo pipefail
# Определяем, где физически лежит сам скрипт
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$SCRIPT_DIR/.img_config"
echo "=== ULTIMATE Image Optimization Script (CLI Parallel Edition) ==="
# ==================== ФУНКЦИЯ НАСТРОЙКИ ПУТИ ====================
setup_base_dir() {
echo "--- Настройка базовой директории сайта ---"
echo "Введите абсолютный путь к папке 'img' вашего сайта."
echo "Пример: /home/micu/Documents/My_site/img/"
read -r -p "Путь: " user_path
user_path="${user_path%/}"
if [ ! -d "$user_path" ]; then
echo "⚠️ Ошибка: Директория '$user_path' не существует!"
read -r -p "Всё равно сохранить этот путь? (y/n): " confirm
if [[ ! "$confirm" =~ ^[Yy]$ ]]; then
exit 1
fi
fi
echo "$user_path" < "$CONFIG_FILE"
echo "✓ Базовый путь успешно сохранен в $CONFIG_FILE"
}
# ==================== ОБРАБОТКА ФЛАГОВ (-c / --change-dir) ====================
if [ "${1:-}" = "-c" ] || [ "${1:-}" = "--change-dir" ]; then
setup_base_dir
echo "Перезапуск скрипта..."
exit 0
fi
if [ ! -f "$CONFIG_FILE" ]; then
echo "Похоже, это первый запуск скрипта!"
setup_base_dir
fi
BASE_OUT_DIR=$(cat "$CONFIG_FILE")
# ==================== ВЫБОР ПОДДИРЕКТОРИИ (Поста/Дня) ====================
echo ""
echo "Текущий базовый путь: $BASE_OUT_DIR"
echo "Введите название целевой подпапки для картинок (например: day_1):"
read -r -p "Подпапка: " sub_dir
sub_dir="${sub_dir#/}"
sub_dir="${sub_dir%/}"
FINAL_DESTINATION="$BASE_OUT_DIR/$sub_dir"
mkdir -p "$FINAL_DESTINATION"
# ==================== ВЫБОР РЕЖИМА СЖАТИЯ ====================
echo ""
echo "Выберите целевой режим сжатия:"
echo "1) Hero / LCP — очень строго (<180 KiB)"
echo "2) Content — строго (<230 KiB)"
echo "3) Banner — умеренно (<350 KiB)"
echo "4) Gallery — максимально (<110 KiB)"
read -r -p "Введите номер (1-4): " mode
case $mode in
1) TARGET_WEBP=184320; MIN_QUALITY=18 ;;
2) TARGET_WEBP=235520; MIN_QUALITY=22 ;;
3) TARGET_WEBP=358400; MIN_QUALITY=28 ;;
4) TARGET_WEBP=112640; MIN_QUALITY=15 ;;
*) echo "По умолчанию Content"; TARGET_WEBP=235520; MIN_QUALITY=22 ;;
esac
SIZES=(640 1200 1920)
shopt -s nullglob
# Экспортируем переменные, чтобы дочерние процессы их видели
export TARGET_WEBP MIN_QUALITY FINAL_DESTINATION sub_dir SCRIPT_DIR
export -a SIZES
# ==================== ФУНКЦИЯ СЖАТИЯ ОДНОГО РАЗМЕРА ====================
compress_size() {
local work="$1" local out_webp="$2" local out_avif="$3"
local target_w="$4" local target_h="$5"
local avif_target=$(( TARGET_WEBP * 70 / 100 ))
local current_w=$target_w local current_h=$target_h
# WebP
magick "$work" -resize "${target_w}x${target_h}" -quality 72 -define webp:method=6 -define webp:pass=10 "$out_webp"
# Агрессивный цикл
for pass in {1..8}; do
[ -f "$out_webp" ] || break
local current_size=$(stat -c %s "$out_webp")
[ "$current_size" -le "$TARGET_WEBP" ] && break
local quality=$(( 72 - pass * 9 ))
[ "$quality" -lt "$MIN_QUALITY" ] && quality=$MIN_QUALITY
current_w=$(( current_w * 90 / 100 ))
current_h=$(( current_h * 90 / 100 ))
if [ $(( current_w < current_h ? current_w : current_h )) -lt 320 ]; then
magick "$work" -resize "${target_w}x${target_h}" -quality "$quality" -define webp:method=6 -define webp:pass=10 -define webp:alpha-quality=30 "$out_webp"
break
fi
magick "$work" -resize "${current_w}x${current_h}" -quality "$quality" -define webp:method=6 -define webp:pass=10 -define webp:alpha-quality=30 "$out_webp"
done
# AVIF
local final_w=$(magick identify -format "%w" "$out_webp" 2</dev/null || echo "$target_w")
local final_h=$(magick identify -format "%h" "$out_webp" 2</dev/null || echo "$target_h")
magick "$work" -strip -units PixelsPerInch -density 72 -resize "${final_w}x${final_h}" -quality 60 "$out_avif"
if [ $(stat -c %s "$out_avif" 2</dev/null || echo 0) -gt "$avif_target" ]; then
magick "$work" -strip -units PixelsPerInch -density 72 -resize "${final_w}x${final_h}" -quality 40 "$out_avif"
fi
}
export -f compress_size
# ==================== ВОРКЕР: ОБРАБОТКА ОДНОГО ФАЙЛА ====================
process_single_image() {
local input="$1"
[ -e "$input" ] || return 0
local name=$(basename "$input")
local base="${name%.*}"
local ext="${name##*.}"
local clean_ext=$(echo "$ext" | tr '[:upper:]' '[:lower:]')
[ "$clean_ext" == "jpeg" ] && clean_ext="jpg"
local img_dir="$FINAL_DESTINATION/$base"
local img_originals_dir="$img_dir/original"
mkdir -p "$img_originals_dir"
# Создаем ИЗОЛИРОВАННУЮ временную папку для конкретно этого файла
local tmp_work_dir=$(mktemp -d "$SCRIPT_DIR/.tmp_work_${base}_XXXXXX")
local work="$tmp_work_dir/${base}_work.${ext}"
# Перенаправляем вывод всего процесса в переменную, чтобы логи не перемешивались в кашу
local log_output=""
log_output+="\n=== Processing: $name ===\n"
log_output+=" → Результаты полетели в: $img_dir\n"
cp "$input" "$img_originals_dir/$name"
cp "$input" "$work"
local has_alpha=0
if [[ "$clean_ext" == "png" ]]; then
if magick identify -format "%[channels]" "$work" 2</dev/null | grep -q 'a'; then
has_alpha=1
fi
fi
if [ "$has_alpha" -eq 1 ]; then
log_output+=" → Alpha PNG — предварительное сжатие...\n"
pngquant --quality=40-85 --speed=1 --force --output "${work%.png}_tmp.png" "$work" && mv "${work%.png}_tmp.png" "$work" || true
oxipng -o 6 --strip safe --quiet "$work" || true
fi
local src_w=$(magick identify -format "%w" "$work" 2</dev/null || echo 0)
local src_h=$(magick identify -format "%h" "$work" 2</dev/null || echo 0)
local max_created_w=0
local max_created_h=0
for size in "${SIZES[@]}"; do
if [ "$size" -gt "$src_w" ] && [ "$size" -gt "$src_h" ]; then continue; fi
if [ "$src_w" -ge "$src_h" ]; then
local target_w=$size; local target_h=$(( src_h * size / src_w ))
else
local target_h=$size; local target_w=$(( src_w * size / src_h ))
fi
local out_webp="$img_dir/${base}-${size}.webp"
local out_avif="$img_dir/${base}-${size}.avif"
compress_size "$work" "$out_webp" "$out_avif" "$target_w" "$target_h"
local final_w=$(magick identify -format "%w" "$out_webp" 2</dev/null || echo "$target_w")
local final_h=$(magick identify -format "%h" "$out_webp" 2</dev/null || echo "$target_h")
log_output+=" ✓ [${size}px] Созданы варианты WebP и AVIF [${final_w}x${final_h}]\n"
max_created_w=$final_w
max_created_h=$final_h
done
# Умный расчет размера фолбэка (Дубли удалены!)
local fallback_w=$max_created_w
local fallback_h=$max_created_h
if [ "$max_created_w" -gt 1200 ] || [ "$max_created_h" -gt 1200 ]; then
if [ "$src_w" -ge "$src_h" ]; then
fallback_w=1200
fallback_h=$(( src_h * 1200 / src_w ))
else
fallback_h=1200
fallback_w=$(( src_w * 1200 / src_h ))
fi
fi
local fallback_ext="jpg"
[ "$has_alpha" -eq 1 ] && fallback_ext="png"
local fallback_file="$img_dir/${base}-fallback.${fallback_ext}"
if [ "$fallback_ext" == "png" ]; then
magick "$work" -resize "${fallback_w}x${fallback_h}" "$fallback_file"
log_output+=" ↳ Оптимизируем палитру уменьшенного PNG-фолбэка...\n"
pngquant --quality=40-85 --speed=1 --force --output "${fallback_file%.png}_tmp.png" "$fallback_file" \
&& mv "${fallback_file%.png}_tmp.png" "$fallback_file" || true
oxipng -o 6 --strip safe --quiet "$fallback_file" || true
else
magick "$work" -strip -units PixelsPerInch -density 72 \
-resize "${fallback_w}x${fallback_h}" -quality 65 "$fallback_file"
fi
local fallback_final_size=$(stat -c %s "$fallback_file" 2</dev/null || echo 0)
local pretty_size=$(numfmt --to=iec "$fallback_final_size")
log_output+=" ✓ Создан дефолтный фолбэк: ${base}-fallback.${fallback_ext} [${fallback_w}x${fallback_h}] ($pretty_size)\n"
# Удаляем оригинал из входящей папки и временную рабочую директорию
rm -f "$input"
rm -rf "$tmp_work_dir"
# --- Подготовка списков существующих файлов для умного srcset ---
local valid_avif=()
local valid_webp=()
for size in "${SIZES[@]}"; do
[ -f "$img_dir/${base}-${size}.avif" ] && valid_avif+=("$size")
[ -f "$img_dir/${base}-${size}.webp" ] && valid_webp+=("$size")
done
# Общая строка sizes для обоих тегов source
local sizes_attr="sizes=\"(max-width: 640px) 100vw, (max-width: 1200px) 80vw, 1200px\""
# Генерируем HTML блок в лог
log_output+="\n → HTML для вашего файла:\n"
log_output+=" <picture>\n"
# Блок AVIF
log_output+=" <source type=\"image/avif\" srcset=\"\n"
local len_avif=${#valid_avif[@]}
for ((i=0; i<len_avif; i++)); do
local size=${valid_avif[i]}
if [ $i -eq $((len_avif - 1)) ]; then
# На последней итерации закрываем кавычку, переносим строку и пишем sizes
log_output+=" img/${sub_dir}/${base}/${base}-${size}.avif ${size}w\"\n $sizes_attr>\n"
else
log_output+=" img/${sub_dir}/${base}/${base}-${size}.avif ${size}w,\n"
fi
done
# Блок WebP
log_output+=" <source type=\"image/webp\" srcset=\"\n"
local len_webp=${#valid_webp[@]}
for ((i=0; i<len_webp; i++)); do
local size=${valid_webp[i]}
if [ $i -eq $((len_webp - 1)) ]; then
# На последней итерации закрываем кавычку, переносим строку и пишем sizes
log_output+=" img/${sub_dir}/${base}/${base}-${size}.webp ${size}w\"\n $sizes_attr>\n"
else
log_output+=" img/${sub_dir}/${base}/${base}-${size}.webp ${size}w,\n"
fi
done
# Блок IMG фолбэка
log_output+=" <img src=\"img/${sub_dir}/${base}/${base}-fallback.${fallback_ext}\" width=\"$fallback_w\" height=\"$fallback_h\" alt=\"Опиши картинку здесь\" loading=\"lazy\">\n"
log_output+=" </picture>\n"
# Выплескиваем весь лог картинки атомарно, чтобы строки не перепутались
echo -e "$log_output"
}
export -f process_single_image
# ==================== ДИСПЕТЧЕР ПОТОКОВ ====================
files=("$SCRIPT_DIR"/*.{jpg,jpeg,png,webp,avif,JPG,JPEG,PNG,WEBP,AVIF})
if [ ${#files[@]} -eq 0 ]; then
echo "❌ Ошибка: В папке '$SCRIPT_DIR' не найдено файлов картинок для обработки!"
exit 1
fi
echo "🚀 Запуск параллельной обработки (Лимит: 5 потоков)..."
MAX_JOBS=5
for input in "${files[@]}"; do
[ -e "$input" ] || continue
# Запускаем обработку одной картинки строго в фоновом режиме (&)
process_single_image "$input" &
# Считаем, сколько фоновых задач запущено прямо сейчас
# Каждый раз, когда количество фоновых задач достигает максимума,
# команда 'wait -n' приостанавливает цикл, ожидая завершения ЛЮБОЙ одной задачи.
while [ "$(jobs -r | wc -l)" -ge "$MAX_JOBS" ]; do
wait -n
done
done
# Ждем завершения последних "хвостов" в очереди
wait
echo ""
echo "=== Все картинки обработаны параллельно и разложены по полочкам! ==="
Первые шажки в CSS
Прочитав заголовок, можно подумать, что я разобрался с курсом от FreeCodeCamp по HTML, но не тут-то было! Пока я возился с ИИ со скриптом, Джеминай так и норовил мне надавать разных советов, что и как можно сделать симпатичнее; потом мне самому стало любопытно, как расстояние увеличить между ссылками в хедере, как сделать отступы у абзацев и всё-всё-всё… В итоге я теперь знаю, как отмечаются в селекторах классы, айди и теги в CSS-файле и некоторые свойства типа text-align и font-size. Не смейтесь, все с чего-то начинают! 🤓☝️
Что ж, на сегодня, кажется, всё. Пора публиковаться на гитхабе!
Так, уже этот абзац пишется после первого коммита. Выяснилось, что на Github Pages относительные пути от корня — типа /img/day_1/akihabara000/akihabara000-640.avif не работают! Это происходит потому, что гитхаб начинает рыскать не в корневой директории репозитория https://wokolai.github.io/personal-site, а в корневой директории моего сайта https://wokolai.github.io. Теперь стремительно меняю все абсолютные пути либо на голые относительные img/day_1/akihabara000/akihabara000-640.avif (идеально для сайтов в корневой папке), либо на ../../../../img/day_1/akihabara000/akihabara000-fallback.jpg (для файлов в архивной директории); выглядит последнее несуразно, по-моему, но зато работает и на реальном сервере, и на гитхабе. Также решил проверить сайт на валидаторе, как это рекомендовал делать парень с курса, который я прохожу, и нашёл у себя кучу ошибок, которые также стремительно исправил. Ну и ещё пару 💫 косметических изменений 💫 сделал, в частности убрал скругление на обводке моего диалога с Клодом — она вообще пока не нужна. Теперь, будучи более осознанным и подготовленным, делаю второй коммит!
День 4: таблицы и забота о здоровье
Дата публикации:
Таблицы
Всем привет! Я пережил экзамен по математике и только сейчас возвращаюсь к работе над сайтом и изучению HTML. В последний раз я остановился на таблицах. Не понял некоторые моменты и хочу остановиться на них поподробнее.
Покажу вам, какой ноут удалось взять на Авито за 80000 ₽. :D
ASUS TUF Gaming A15 FA507NV (модифицированный)
Процессор
AMD Ryzen 5 7535HS
Встроенная видеокарта
AMD Radeon 660M
Дискретная видеокарта
NVIDIA GeForce RTX 4060 Laptop GPU (140 Вт)
Оперативная память
DDR5 Kingston FURY Impact [KF556S40IB-16] 16 ГБ x 2
SSD
WD PC SN740 SDDPNQD-512G-1002
ADATA LEGEND 860
Ёмкость аккумулятора
90 Вт*ч
Оставшаяся ёмкость аккумулятора
87 %
Если честно, доволен покупкой, как слон!
Забота о здоровье глаз и рук
Сегодня значительную часть дня я потратил на выстраивание стратегии «безвредного» досуга за ПК. Что я имею в виду? Ни для кого не секрет, что проводить сутки перед монитором не очень полезно. Это влияет и на здоровье глаз, и на здоровье рук, и на здоровье спины. Со спиной мне ещё предстоит разбираться (пока нет возможности реализовать всё это грамотно), но с глазами и руками, особенно дома, справиться можно.
Итак, начнём с глаз. Проведя небольшой ресёрч, выяснил, что корпоративному миру было даровано несколько советов:
Правило 20-20-20
Незамысловатое предложение, данное в девяностые годы прошлого века оптометристом Джеффри Аншелом, гласит, что каждые 20 минут надо 20 секунд фокусировать взгляд на предмете, находящемся на расстоянии 20 футов (~6 метров). Чтобы его соблюдать, я из Flathub скачал Stretchly — утилиту, которая раз в заданные промежуток времени блокирует экран, чтобы человек мог сделать свои дела со глазами. Я настроил его так, чтобы раз в час также был перерыв на 5 минут — это необходимо для полноценной разминки.
Разминка для глаз
Полная разминка для глаз, которую я теперь делаю раз в час работы за ноутом, указана далее. Как раз отточу навык создания таблиц!
Моя разминка для глаз
Упражнение
Затрачиваемое время (в секундах)
Пальминг
Движения вверх-вниз
Движения вправо-влево
Круговые движения по часовой стрелке
Круговые движения против часовой стрелки
Поморгать
Вблизь-вдаль (по 3 секунды)
Закрыть глаза
Делать её немного утомительно, но я исхожу из того, что она поможет замедлить негативную динамику по моей близорукости.
Расположение монитора (в моём контексте экрана ноутбука)
Проведя также небольшой ресёрч, выяснилось, что верхняя ⅓ экрана должна быть на уровне глаз (или даже немного ниже). Немного поэкспериментировав с подставкой, получилось расположить ноутбук так, как надо.
Моргать
Тут, пожалуй, самое сложное… В процессе работы перед экраном надо не забывать моргать. У меня это получается не очень хорошо, ведь я часто фокусируюсь на том, что делаю, а не на моргании. Мне есть куда расти!
Дальше можно поговорить о здоровье рук, и тут будет полезное предоставить некоторую историю. В период с по я любил проводить время в ритм-игре osu!, где нужно было одной рукой наводиться стилусом на кружочки и другой рукой жать две кнопки (всё это под отличную музыку). Как иногда бывает, я делал это очень неаккуратно: сильно прижимал запястья к столу, неправильно держал стилус (да, бывают разные хваты, и я выбрал один из самых неэргономичных). В итоге у меня начали болеть запястья, и я оставил игру. Потом боль почти полностью исчезла и достигла едва заметного плато, которое я не хочу ухудшать. Сейчас у меня есть сплит-клавиатура со встроенным трекболом и на крайние случаи вертикальная мышь. Эти девайсы сами по себе ставят запястья в куда более естественное положение, но, очевидно, чтобы сократить потенциальные разминки, рекомендуется делать разминки. Раз в час я обращаюсь к популярной в осу-сообществе видеоинструкции от Tykato Fitness. Удачи мне; надеюсь, не заброшу эту историю. :')
Дни 1, 2 и 3: первые потуги
В первые три дня изучение шло в формате «вставляю всё, что показывает чувак с гайда, на одну страницу и смотрю, что будет»; на третий день я решил сделать какую-никакую главную страницу, поэтому лучше всего просто взглянуть, как выглядел сайт в списке снапшотов, следующим после секции про обучение по дням.