Випробування нового HTML-елементу <permission> - https://developer.chrome.com/blog/permission-element-origin-trial?hl=en
Chrome for Developers
An origin trial for a new HTML <permission> element | Blog | Chrome for Developers
The Chrome team is experimenting with a new declarative HTML <permission> element for asking the user for access to powerful features.
BEM-модифікатори у чистому CSS-Nesting - https://whatislove.dev/articles/bem-modifiers-in-pure-css-nesting/
whatislove.dev
BEM Modifiers in Pure CSS Nesting | Vladyslav Zubko
Learn to use BEM modifiers with native CSS nesting for cleaner, efficient stylesheets without preprocessors. Discover tips and tricks for modern CSS development.
Чистий круговий текст CSS (без використання моноширинних шрифтів) - https://frontendmasters.com/blog/pure-css-circular-text-without-requiring-a-monospace-font/
Frontendmasters
Pure CSS Circular Text (without Requiring a Monospace Font)
Setting text on a circle in CSS isn't straightforward, but it is possible with some effort. This technique splits text into segments and uses transforms and perspective to pull it off.
Випущено Htmx 2.0, що має на меті замінити складні фреймворки JavaScript зрозумілими атрибутами HTML - https://devclass.com/2024/06/18/htmx-2-0-released-aims-to-replace-complex-javascript-frameworks-with-easily-understood-html-attributes/
DEVCLASS
Htmx 2.0 released, aims to replace complex JavaScript frameworks with easily understood HTML attributes • DEVCLASS
The Htmx project to extend HTML has released version 2.0, the first major version since 1.0 in November […]
Привіт, 19 жовтня відбудеться React+ fwdays'24 — щорічна конференція для всіх, хто цікавиться розробкою на JavaScript 🤩
Основний фокус заходу — React. Проте, цього разу, Fwdays не обмежуються лише React та поговорять і про інші фреймворки, такі як Vue.js, Node.js, Angular, Svelte та інші.
Вас очікують:
📍Цікаві спікери та практичні доповіді про покращення React за допомогою TypeScript, мікро-фронтенд та монорепо, здоровий ґлузд та перфекціонізм під час рефакторингу та багато іншого.
📍Нетворкінг, Q&A зі спікерами, нові знайомства
📍Вайб Halloween під час офлайн частини заходу 👻
📍Розіграші та подарунки від партнерів
Формат: онлайн та офлайн у Києві
Використайте промокод POPOVREACT10 та отримайте знижку 10%, деталі за посиланням 👉 https://bit.ly/3TvYp6u
Приєднуйтесь до React+ fwdays'24!
Основний фокус заходу — React. Проте, цього разу, Fwdays не обмежуються лише React та поговорять і про інші фреймворки, такі як Vue.js, Node.js, Angular, Svelte та інші.
Вас очікують:
📍Цікаві спікери та практичні доповіді про покращення React за допомогою TypeScript, мікро-фронтенд та монорепо, здоровий ґлузд та перфекціонізм під час рефакторингу та багато іншого.
📍Нетворкінг, Q&A зі спікерами, нові знайомства
📍Вайб Halloween під час офлайн частини заходу 👻
📍Розіграші та подарунки від партнерів
Формат: онлайн та офлайн у Києві
Використайте промокод POPOVREACT10 та отримайте знижку 10%, деталі за посиланням 👉 https://bit.ly/3TvYp6u
Приєднуйтесь до React+ fwdays'24!
Коротше, вирішив я проаналізувати архітектуру проєкту.
Часу, щоб самому її малювати, немає, та й лінь. Вирішив трохи пошукати інформацію, бо думаю, що таких, як я, багато, і рішення точно вже якесь є.
Коротше, по факту, все вийшло.
Результат на фото.
Він не ідеальний, але якщо трохи підкрутити, змінити порядок блоків і прибрати дублікати (так вийшло), то все буде взагалі дуже непогано.
Нижче декілька дописів із повним кодом і описом, що й як.
Часу, щоб самому її малювати, немає, та й лінь. Вирішив трохи пошукати інформацію, бо думаю, що таких, як я, багато, і рішення точно вже якесь є.
Коротше, по факту, все вийшло.
Результат на фото.
Він не ідеальний, але якщо трохи підкрутити, змінити порядок блоків і прибрати дублікати (так вийшло), то все буде взагалі дуже непогано.
Нижче декілька дописів із повним кодом і описом, що й як.
Частина 1
import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import { parse } from "@vue/compiler-sfc";
import { load } from "cheerio";
import glob from "glob";
import { exec } from "child_process";
import { promisify } from "util";
const execAsync = promisify(exec);
const globAsync = promisify(glob);
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const srcDir = path.join(__dirname, "src");
const componentsDTSPath = path.join("", "components.d.ts"); // Change the path if needed
const groupColors = ["red", "blue", "green", "orange", "purple", "yellow", "pink", "cyan"];
const sharedComponents = ["SVGIcons", "Button", "Input", "Tooltip", "Calendar", "ValidationErrorBlock"];
onst getGlobalComponents = (filePath) => {
const content = fs.readFileSync(filePath, "utf-8");
const globalComponents = [];
const regex = /(\w+): typeof import\(['"][^'"]+['"]\)\['default'\]/g;
let match;
while ((match = regex.exec(content)) !== null) {
globalComponents.push(match[1]);
}
return globalComponents;
};
const getUsedComponents = (templateContent, globalComponents) => {
const usedComponents = new Set();
const $ = load(templateContent, { xmlMode: true, decodeEntities: false });
const toKebabCase = (str) => str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
$("*").each((_, elem) => {
const tagName = elem.tagName;
const possibleNames = [tagName, toKebabCase(tagName)];
possibleNames.forEach((name) => {
if (globalComponents.includes(name) || globalComponents.includes(toPascalCase(name))) {
usedComponents.add(name);
}
});
});
return Array.from(usedComponents).filter((comp) => !sharedComponents.includes(comp));
};
const toPascalCase = (str) =>
str
.split("-")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join("");
const getComponentGroup = (relativePath) => {
const parts = relativePath.split(path.sep);
return parts.length > 1 ? parts[0] : "Others";
};
Частина 2
const generateArchitecture = async () => {
try {
if (!fs.existsSync(componentsDTSPath)) {
console.error(`File ${componentsDTSPath} not found.`);
return;
}
const globalComponents = getGlobalComponents(componentsDTSPath);
console.log("Globally registered components:", globalComponents);
const pattern = path.join(srcDir, "**/*.vue");
const vueFiles = await globAsync(pattern, { ignore: "**/node_modules/**" });
if (vueFiles.length === 0) {
console.warn("No Vue components found. Check the file path.");
return;
}
console.log(`Found ${vueFiles.length} Vue components.`);
const dependencyGraph = {};
const groups = {};
vueFiles.forEach((file) => {
const relativePath = path.relative(srcDir, file);
const componentName = path.basename(relativePath, ".vue");
dependencyGraph[componentName] = [];
const group = getComponentGroup(relativePath);
if (!groups[group]) {
groups[group] = [];
}
groups[group].push(componentName);
});
for (const file of vueFiles) {
const relativePath = path.relative(srcDir, file);
const componentName = path.basename(relativePath, ".vue");
const content = fs.readFileSync(file, "utf-8");
const { descriptor } = parse(content);
if (!descriptor.template) {
console.warn(`File ${file} does not contain a <template>.`);
continue;
}
const templateContent = descriptor.template.content;
const usedComponents = getUsedComponents(templateContent, globalComponents);
dependencyGraph[componentName] = usedComponents;
console.log(`Component: ${componentName}, Uses: ${usedComponents.join(", ")}`);
}
let dotContent = 'digraph G {\n node [shape=box];\n rankdir=LR;\n splines=true;\n';
Object.keys(groups).forEach((group, index) => {
const color = groupColors[index % groupColors.length];
dotContent += ` subgraph cluster_${index} {\n label="${group}";\n color="${color}";\n`;
groups[group].forEach((component) => {
dotContent += ` "${component}";\n`;
});
dotContent += " }\n";
});
Object.keys(dependencyGraph).forEach((component) => {
const dependencies = dependencyGraph[component];
if (dependencies.length > 0) {
dependencies.forEach((dep) => {
dotContent += ` "${component}" -> "${dep}";\n`;
});
}
});
dotContent += "}\n";
const dotDir = path.join(__dirname, "docs", "architecture");
const dotPath = path.join(dotDir, "architecture.dot");
fs.mkdirSync(dotDir, { recursive: true });
fs.writeFileSync(dotPath, dotContent, "utf-8");
console.log("\nFile architecture.dot successfully created.");
const outputPngPath = path.join(dotDir, "architecture.png");
const cmd = `dot -Tpng "${dotPath}" -o "${outputPngPath}"`;
const { stdout, stderr } = await execAsync(cmd);
if (stderr) {
console.error(`Graphviz stderr: ${stderr}`);
}
console.log(`Architecture diagram generated at: ${outputPngPath}`);
} catch (error) {
console.error(`Error generating architecture: ${error.message}`);
}
};
generateArchitecture();
Для роботи скрипта необхідно встановити наступні залежності:
@vue/compiler-sfc — для парсингу .vue файлів
cheerio — для роботи з HTML (розбір шаблонів Vue)
glob — для пошуку файлів у файловій системі
js-cookie — для роботи з кукі (якщо використовується у застосунку)
util — для промисифікації функцій.
Для генерації графу потрібен Graphviz
На macOS
На Ubuntu/Debian/Windows треба пошукати 😅
У мене весь проект лежить в src
А ще у мене є components.d.ts для автоматичного підкючення компонентів
По суті той скрипт що вище сканує всі .vue файли в папці src, потім визначає залежності між компонентами. Створює файл architecture.dot, який використовується для генерації графу.
Приклад результату
Якщо структура вашого проєкту виглядає так:
То граф архітектури виглядатиме приблизно так:
Групи:
components: Modal, Button.
pages: Home, Dashboard.
shared: Header, Footer.
Залежності:
Home → Header.
Dashboard → Header, Footer.
Modal → Button.
Короче у підсумку виходить дуже не поганий інструмент для візуалізації архітектури
Він по суті може допогти
1. Швидко розуміти залежності між компонентами.
2. Визначати зайві зв'язки.
3. Покращувати модульність застосунку.
npm install @vue/compiler-sfc cheerio glob js-cookie util
@vue/compiler-sfc — для парсингу .vue файлів
cheerio — для роботи з HTML (розбір шаблонів Vue)
glob — для пошуку файлів у файловій системі
js-cookie — для роботи з кукі (якщо використовується у застосунку)
util — для промисифікації функцій.
Для генерації графу потрібен Graphviz
На macOS
brew install graphviz
На Ubuntu/Debian/Windows треба пошукати 😅
У мене весь проект лежить в src
А ще у мене є components.d.ts для автоматичного підкючення компонентів
По суті той скрипт що вище сканує всі .vue файли в папці src, потім визначає залежності між компонентами. Створює файл architecture.dot, який використовується для генерації графу.
Приклад результату
Якщо структура вашого проєкту виглядає так:
src/
├── components/
│ ├── Button.vue
│ ├── Modal.vue
├── pages/
│ ├── Home.vue
│ ├── Dashboard.vue
├── shared/
│ ├── Header.vue
│ ├── Footer.vue
То граф архітектури виглядатиме приблизно так:
Групи:
components: Modal, Button.
pages: Home, Dashboard.
shared: Header, Footer.
Залежності:
Home → Header.
Dashboard → Header, Footer.
Modal → Button.
Короче у підсумку виходить дуже не поганий інструмент для візуалізації архітектури
Він по суті може допогти
1. Швидко розуміти залежності між компонентами.
2. Визначати зайві зв'язки.
3. Покращувати модульність застосунку.
12 бібліотек, які вам можуть стати у нагоді 😉
AOS (Animate on Scroll) — це легка та налаштовувана бібліотека для додавання ефектних анімацій при прокручуванні ваших вебсторінок.
https://michalsnik.github.io/aos
Chart.js - дозволяє легко створювати різні типи графіків, включаючи лінійні, стовпчасті, радарні та кругові, з мінімальною конфігурацією.
https://www.chartjs.org
SweetAlert2 пропонує адаптивні, повністю налаштовувані спливаючі вікна, які легко інтегруються у ваші проєкти.
https://sweetalert2.github.io
SortableJS дозволяє легко реалізувати функцію перетягування для списків. Її гнучкість робить її ідеальною для створення інтерактивних інтерфейсів, таких як канбан-дошки.
https://sortablejs.github.io/Sortable
Floating UI дозволяє легко керувати складними компонентами інтерфейсу, такими як підказки, випадаючі меню та спливаючі вікна.
https://floating-ui.com
FullCalendar пропонує зручний, повнофункціональний інтерфейс календаря з налаштовуваним керуванням подіями, функцією перетягування та різними режимами перегляду.
https://fullcalendar.io
Animate.css - додавайте попередньо створені анімації до елементів вашого сайту за допомогою Animate.css.
https://animate.style
Lottie від Airbnb - Ця бібліотека дозволяє інтегрувати високоякісні анімації у ваші вебдодатки.
https://lottiefiles.com/free-animations/airbnb
Tippy.js - Легка, розширювана бібліотека для створення красивих, налаштовуваних підказок, спливаючих вікон і випадаючих меню.
https://atomiks.github.io/tippyjs
Day.js — це проста й швидка бібліотека, яка чудово підходить для проєктів, що працюють з датами, не займаючи багато місця та не уповільнюючи роботу.
https://day.js.org
Swiper — це безкоштовний і потужний інструмент для створення слайдерів і каруселей. Він забезпечує плавні переходи й добре працює на різних екранах, що робить його ідеальним для мобільних проєктів.
https://swiperjs.com
Vivus - Створюйте приголомшливі анімовані SVG-малюнки за допомогою Vivus. Ця легка JavaScript-бібліотека дозволяє анімувати SVG, імітуючи процес малювання, додаючи унікальний стиль вашим графікам.
https://maxwellito.github.io/vivus
AOS (Animate on Scroll) — це легка та налаштовувана бібліотека для додавання ефектних анімацій при прокручуванні ваших вебсторінок.
https://michalsnik.github.io/aos
Chart.js - дозволяє легко створювати різні типи графіків, включаючи лінійні, стовпчасті, радарні та кругові, з мінімальною конфігурацією.
https://www.chartjs.org
SweetAlert2 пропонує адаптивні, повністю налаштовувані спливаючі вікна, які легко інтегруються у ваші проєкти.
https://sweetalert2.github.io
SortableJS дозволяє легко реалізувати функцію перетягування для списків. Її гнучкість робить її ідеальною для створення інтерактивних інтерфейсів, таких як канбан-дошки.
https://sortablejs.github.io/Sortable
Floating UI дозволяє легко керувати складними компонентами інтерфейсу, такими як підказки, випадаючі меню та спливаючі вікна.
https://floating-ui.com
FullCalendar пропонує зручний, повнофункціональний інтерфейс календаря з налаштовуваним керуванням подіями, функцією перетягування та різними режимами перегляду.
https://fullcalendar.io
Animate.css - додавайте попередньо створені анімації до елементів вашого сайту за допомогою Animate.css.
https://animate.style
Lottie від Airbnb - Ця бібліотека дозволяє інтегрувати високоякісні анімації у ваші вебдодатки.
https://lottiefiles.com/free-animations/airbnb
Tippy.js - Легка, розширювана бібліотека для створення красивих, налаштовуваних підказок, спливаючих вікон і випадаючих меню.
https://atomiks.github.io/tippyjs
Day.js — це проста й швидка бібліотека, яка чудово підходить для проєктів, що працюють з датами, не займаючи багато місця та не уповільнюючи роботу.
https://day.js.org
Swiper — це безкоштовний і потужний інструмент для створення слайдерів і каруселей. Він забезпечує плавні переходи й добре працює на різних екранах, що робить його ідеальним для мобільних проєктів.
https://swiperjs.com
Vivus - Створюйте приголомшливі анімовані SVG-малюнки за допомогою Vivus. Ця легка JavaScript-бібліотека дозволяє анімувати SVG, імітуючи процес малювання, додаючи унікальний стиль вашим графікам.
https://maxwellito.github.io/vivus
26 листопада був реліз Vite 6
Про нові зміни можна почитати тут
Якщо коротко, то:
- Деякі умови більше не додаються автоматично і мають бути вказані в конфігурації.
- JSON.stringify тепер за замовчуванням працює в режимі 'auto'
- За замовчуванням використовується сучасний API.
- У бібліотечному режимі ім'я CSS-файлу тепер залежить від назви пакету.
Про нові зміни можна почитати тут
Якщо коротко, то:
- Деякі умови більше не додаються автоматично і мають бути вказані в конфігурації.
- JSON.stringify тепер за замовчуванням працює в режимі 'auto'
- За замовчуванням використовується сучасний API.
- У бібліотечному режимі ім'я CSS-файлу тепер залежить від назви пакету.
vitejs
Announcing Vite 6
Vite 6 Release Announcement
Якщо ви цікавитесь Vue як і я, ось вам цікавенька стаття де розповідають як побудувати веб апплікейшин який видаляє фон за допомогою Vue та Transformers.js
LogRocket Blog
Building a background remover with Vue and Transformers.js - LogRocket Blog
Build a real-time image background remover in Vue using Transformers.js and WebGPU for client-side processing with privacy and efficiency.
Зробив із ноутбука власний сервер.
Хотів я арендувати VPS для себе щоб на ньому розмістити свої проекти. Довго шукав, читав, питав і так і не зміг обрати найкращий. А потім я згадав що у мене є ноутбук, який лежить без діла. Тому склавши такі речі як: ноутбук без діла + бажання розібратись як підняті свій сервер, я почав його підіймати
1️⃣ Спочатку встановив Ubuntu Server ( останню версію Ubuntu Server можна завантажити з офіційного сайту )
При встановленні там все інтуітивно зрозуміло.
Єдино що: я обрав мінімальну конфігурацію, одразу під час встановлення додав OpenSSH Server.
2️⃣ Далі після встановлення я новоспечений сервер залишив на столі і пішов вже сів за свій ноут. До серверу підключивя через SSH через локальну мережу.
Як це зробити
Дізнайтеся локальну IP-адресу сервера
Приклад виводу: 192.168.1.100 — ваш локальний IP.
Щоб підключитися
Далі вас попросе пароль.
Введіть його. Ну і якщо правльно ввели, то все, ви зайшли на свій сервер
3️⃣ Далі налаштування фаєрволу (UFW)
Налаштуйте захист сервера, дозволивши лише потрібні порти.
Встановіть UFW:
Дозвольте доступ для SSH та веб-сервера:
Увімкніть фаєрвол:
Перевірка статусу
4️⃣ Встановлення PHP та MySQL
Встановіть PHP та необхідні модулі:
Встановіть MySQL
Налаштуйте MySQL для безпечної роботи (слідуйте інструкціям):
5️⃣ Встановлення веб-сервера Nginx
У браузері на іншому пристрої введіть локальну IP-адресу сервера, наприклад http://192.168.1.100
6️⃣ Налаштування Nginx для роботи з PHP
Сам конфіг такий
Створюєм симлінк для активації конфігурації:
Рестартім nginx
7️⃣ Потім щоб все працювало рівно мені довелось купити у свого провайдера білий айпі. Це коштує 30 грн/місяць. У вашого провайдера це може бути взашалі безкоштовно
І коли у вас є білий айпи, і якщо ви пидєднуєте ваш сервер до мережі інтернет через роутер, треба налаштувати проброс портів на ньому ( роутері ).
У мене в налаштуваннях роутера є така вкладка як Виртуальный сервер
і там вказую зовнішній порт ( 80 ), внутрішній порт ( 80 ), локальну айпі адресу ( 192.168.1.100 ) і протокол ( TCP )
і потім треба зробити ще одну таку запис для SSH
овнішній порт ( 20 ), внутрішній порт ( 20 ), локальну айпі адресу ( 192.168.1.100 ) і протокол ( ALL )
Сам зовнішній айпі можна дізнатися так
8️⃣ Розміщення файлів і все таке відбувається тут /var/www/html
Ту сторінку що ви бачите коли перйший раз заходите можете знайти тут
Це поки все що я зробив 🙂
Далі хочу розгорнути сайт на Wordpress
Купити якийсь дешевий домен і привязати його
А ще, Налаштування HTTPS
Поки все 🙃
Хотів я арендувати VPS для себе щоб на ньому розмістити свої проекти. Довго шукав, читав, питав і так і не зміг обрати найкращий. А потім я згадав що у мене є ноутбук, який лежить без діла. Тому склавши такі речі як: ноутбук без діла + бажання розібратись як підняті свій сервер, я почав його підіймати
1️⃣ Спочатку встановив Ubuntu Server ( останню версію Ubuntu Server можна завантажити з офіційного сайту )
При встановленні там все інтуітивно зрозуміло.
Єдино що: я обрав мінімальну конфігурацію, одразу під час встановлення додав OpenSSH Server.
2️⃣ Далі після встановлення я новоспечений сервер залишив на столі і пішов вже сів за свій ноут. До серверу підключивя через SSH через локальну мережу.
Як це зробити
Дізнайтеся локальну IP-адресу сервера
ip a
Приклад виводу: 192.168.1.100 — ваш локальний IP.
Щоб підключитися
ssh username@192.168.1.100
Далі вас попросе пароль.
Введіть його. Ну і якщо правльно ввели, то все, ви зайшли на свій сервер
3️⃣ Далі налаштування фаєрволу (UFW)
Налаштуйте захист сервера, дозволивши лише потрібні порти.
Встановіть UFW:
sudo apt update
sudo apt install ufw
Дозвольте доступ для SSH та веб-сервера:
sudo ufw allow OpenSSH
sudo ufw allow 80
sudo ufw allow 22
Увімкніть фаєрвол:
sudo ufw enable
Перевірка статусу
sudo ufw status
4️⃣ Встановлення PHP та MySQL
Встановіть PHP та необхідні модулі:
sudo apt install php php-fpm php-mysql
Встановіть MySQL
sudo apt install mysql-server
Налаштуйте MySQL для безпечної роботи (слідуйте інструкціям):
sudo mysql_secure_installation
sudo ufw status
5️⃣ Встановлення веб-сервера Nginx
sudo apt install nginx
У браузері на іншому пристрої введіть локальну IP-адресу сервера, наприклад http://192.168.1.100
6️⃣ Налаштування Nginx для роботи з PHP
sudo nano /etc/nginx/sites-available/example
Сам конфіг такий
server {
listen 80;
server_name <ваш_білий_IP>;
root /var/www/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Створюєм симлінк для активації конфігурації:
sudo ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/
Рестартім nginx
sudo nginx -t
sudo systemctl reload nginx
7️⃣ Потім щоб все працювало рівно мені довелось купити у свого провайдера білий айпі. Це коштує 30 грн/місяць. У вашого провайдера це може бути взашалі безкоштовно
І коли у вас є білий айпи, і якщо ви пидєднуєте ваш сервер до мережі інтернет через роутер, треба налаштувати проброс портів на ньому ( роутері ).
У мене в налаштуваннях роутера є така вкладка як Виртуальный сервер
і там вказую зовнішній порт ( 80 ), внутрішній порт ( 80 ), локальну айпі адресу ( 192.168.1.100 ) і протокол ( TCP )
і потім треба зробити ще одну таку запис для SSH
овнішній порт ( 20 ), внутрішній порт ( 20 ), локальну айпі адресу ( 192.168.1.100 ) і протокол ( ALL )
Сам зовнішній айпі можна дізнатися так
curl ifconfig.me
8️⃣ Розміщення файлів і все таке відбувається тут /var/www/html
Ту сторінку що ви бачите коли перйший раз заходите можете знайти тут
sudo nano /var/www/html/index.html
Це поки все що я зробив 🙂
Далі хочу розгорнути сайт на Wordpress
Купити якийсь дешевий домен і привязати його
А ще, Налаштування HTTPS
Поки все 🙃
Ubuntu
Get Ubuntu Server | Download | Ubuntu
Get Ubuntu Server one of three ways; by using Multipass on your desktop, using MAAS to provision machines in your data centre or installing it directly on a server.
https://dou.ua/forums/topic/51735/ - мій перший топік на DOU 🙃
DOU
Можливо прийшов час перестати використовувати БЕМ ?
Методологія BEM вже давно стала частиною арсеналу веб-розробників, але чи актуальна вона у 2024 році? Денис Попов, Frontend-розробник Nova Digital, поділився своїм поглядом на переваги та недоліки цієї технології й відповів на запитання: чи варто сьогодні
Відносно нові речі, які ви повинні знати про HTML у 2025 року - https://frontendmasters.com/blog/bone-up-html-2025/
Frontendmasters
Relatively New Things You Should Know about HTML Heading Into 2025
Accordion details, toggle switches, styleable selects, responsive video, and more!
https://una.im/advanced-attr/ - Нові можливості attr()
Цікава стаття.
Точно вартої вашої уваги бо впевнений що рано чи пізно у вас буде кейс де attr() вас спасе 😉
https://css-tricks.com/positioning-text-around-elements-with-css-offset/ - Розташування тексту навколо елементів із зсувом CSS. Виглядає дуже гарно
https://css-tricks.com/some-things-you-might-not-know-about-custom-counter-styles/ - Деякі речі, які ви можете не знати про спеціальні стилі лічильників
Цікава стаття.
Точно вартої вашої уваги бо впевнений що рано чи пізно у вас буде кейс де attr() вас спасе 😉
https://css-tricks.com/positioning-text-around-elements-with-css-offset/ - Розташування тексту навколо елементів із зсувом CSS. Виглядає дуже гарно
https://css-tricks.com/some-things-you-might-not-know-about-custom-counter-styles/ - Деякі речі, які ви можете не знати про спеціальні стилі лічильників
Всім првиіт
Стартувало друге голосування на Премію Доу
Я увійшов у шорт ліст серед кандитатів в категоріі "Вони – надихають"
Тому, якщо у вас є трохи хвилинок, зайдіть сюди https://dou.ua/awards-2025/ і залиште будь ласка свій голос 😉
Стартувало друге голосування на Премію Доу
Я увійшов у шорт ліст серед кандитатів в категоріі "Вони – надихають"
Тому, якщо у вас є трохи хвилинок, зайдіть сюди https://dou.ua/awards-2025/ і залиште будь ласка свій голос 😉