Полезно и Вкусно: Мир HTML, CSS и JS
6 subscribers
4 photos
9 videos
19 links
Уютное место для вкусной веб-разработке

Administrator: @kirilichcha

GitHub: https://github.com/kirillchacha

Linkedin: www.linkedin.com/in/kirill-chacharskyi-3a658225a
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Градиентное подчеркивание ссылок или любого другого текста при наведение с помощью CSS

HTML разметка
<a href="https://t.me/WebTaverna">
WebTaverna
</a>


CSS стили
a::after {
content: "";
display: block;
width: 0;
height: 3px;
transition: all 0.3s;
background: #12c2e9;
background: linear-gradient(to right,
#f64f59,#c471ed,#12c2e9);
}
a:hover::after {
width: 100%;
}


👍- если было полезно | ➡️ WebTaverna
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
🖥 7 интересных эффектов для кнопок с помощью CSS, SVG и библиотеки GSAP

Код и демо: codepen.io/jdillon/pen/PovYbLN
Please open Telegram to view this post
VIEW IN TELEGRAM
Переводить текст или 🙌 нет

С помощью HTML атрибут translate мы можем указывать браузеру, нужно ли переводить какой-либо текст или нет

Атрибут имеет два значения ⤵️
🔜 yes — (по умолчанию) переводить;
🔜 no — не переводить.

Этот бывает полезно, когда нужно предотвратить перевод специфических текстов: имена, бренды или фрагмент кода.


Translate — глобальный атрибут, его можно назначать любым HTML-элементам.

👍- если было полезно | ➡️ WebTaverna
Please open Telegram to view this post
VIEW IN TELEGRAM
This media is not supported in your browser
VIEW IN TELEGRAM
Управляем стилями выделенного элемента с помощью ::selection в CSS

Данный псевдоэлемент применяет стили к пользовательскому выделению. Например, с помощью ::selection можно применить нужные цвета к выделенному с помощью мыши тексту в соответствии с дизайном вашего сайта
h1::selection {
background-color: #c83e4d;
color: #f4b860;
}


Разрешённые свойства ⤵️
🔜 color
🔜 background-color
🔜 cursor
🔜 caret-color
🔜 outline и его длинные записи
🔜 text-decoration и связанные свойства
🔜 text-emphasis-color
🔜 text-shadow

🔜 А также stroke-color, fill-color, stroke-width для SVG

👍- если было полезно | ➡️ WebTaverna
Please open Telegram to view this post
VIEW IN TELEGRAM
​​добавления активного класса в меню

document.addEventListener("DOMContentLoaded",
function () {
const menuLinks = document.querySelectorAll('.menu__link');
const currentUrl = window.location.href;

menuLinks.forEach(link => {
// Проверяем, чтобы href был не пустым и не равнялся "#"
if (link.href && link.href !== "#" && link.href === currentUrl) {
link.classList.add('menu-active');
}
});
});
​​Поиск


document.addEventListener('DOMContentLoaded',
() => {
  const searchForm = document.querySelector('.header__search');
  const searchInput = searchForm.querySelector('.search-header__input');

  fetch('files/json/search.json')
    .then(response => response.json())
    .then(products => {
      searchForm.addEventListener('submit', (e) => {
        e.preventDefault(); // Останавливаем отправку формы по умолчанию
        const query = searchInput.value.trim().toLowerCase();

        if (query === '') {
          return;
        }

        const foundProduct = products.find(product => product.name.toLowerCase().includes(query));

        if (foundProduct) {
          window.location.href = foundProduct.url;
        } else {
          alert('Товар не знайдено.');
        }
      });

      searchInput.addEventListener('input', () => {
        if (searchInput.value.trim() === '') {
          // Если поле пустое, можно добавить поведение, например, очистить результаты поиска
          console.log('Поле поиска очищено');
        }
      });
    })
    .catch(error => {
      console.error('Ошибка при загрузке продуктов:', error);
    });
});
​​Добавление звезд

//Select all the elements that should contain stars

const starContainers = document.querySelectorAll(
  ".slide-testimonials__rating"
);

// SVG star templates
const filledStar = `
    <svg viewBox="0 0 24 24">
     <path
      fill="#282726"
      d="M23.555,8.729a1.505,1.505,0,0,0-1.406-.98H16.062a.5.5,0,0,1-.472-.334L13.405,1.222a1.5,1.5,0,0,0-2.81,0l-.005.016L8.41,7.415a.5.5,0,0,1-.471.334H1.85A1.5,1.5,0,0,0,.887,10.4l5.184,4.3a.5.5,0,0,1,.155.543L4.048,21.774a1.5,1.5,0,0,0,2.31,1.684l5.346-3.92a.5.5,0,0,1,.591,0l5.344,3.919a1.5,1.5,0,0,0,2.312-1.683l-2.178-6.535a.5.5,0,0,1,.155-.543l5.194-4.306A1.5,1.5,0,0,0,23.555,8.729Z"
     ></path>
    </svg>
  `;

const emptyStar = `
    <svg viewBox="0 0 24 24">
     <path
      fill="#28272670"
      d="M23.555,8.729a1.505,1.505,0,0,0-1.406-.98H16.062a.5.5,0,0,1-.472-.334L13.405,1.222a1.5,1.5,0,0,0-2.81,0l-.005.016L8.41,7.415a.5.5,0,0,1-.471.334H1.85A1.5,1.5,0,0,0,.887,10.4l5.184,4.3a.5.5,0,0,1,.155.543L4.048,21.774a1.5,1.5,0,0,0,2.31,1.684l5.346-3.92a.5.5,0,0,1,.591,0l5.344,3.919a1.5,1.5,0,0,0,2.312-1.683l-2.178-6.535a.5.5,0,0,1,.155-.543l5.194-4.306A1.5,1.5,0,0,0,23.555,8.729Z"
     ></path>
    </svg>
  `;

// Function to generate stars
function generateStars(starCount) {
  let starHTML = "<ul class='slide-testimonials__rating'>";

  // Loop through to generate filled stars
  for (let i = 0; i < starCount; i++) {
    starHTML += <li>${filledStar}</li>;
  }

  // Loop through to generate empty stars (5 - starCount)
  for (let i = starCount; i < 5; i++) {
    starHTML += <li>${emptyStar}</li>;
  }

  starHTML += "</ul>";
  return starHTML;
}

// Go through all star containers and insert the correct number of stars
starContainers.forEach((container) => {
  const starCount = parseInt(container.getAttribute("data-stars"), 10);
  container.innerHTML = generateStars(starCount);
});


css

.slide-testimonialsrating {
  opacity: 0.4;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  gap: 0px;
  svg {
    width: 12px;
    height: 12px;
  }
}
Для плавности слайда: &__wrapper { -webkit-transition-timing-function: linear !important;
transition-timing-function: linear !important; }
Forwarded from JavaScript гайды
🔝 5 полезных однострочных функций JavaScript, которые вам точно пригодятся


🔜 Копирование любого текста в буфер обмена
const copyToClipboard = (text) => navigator.clipboard.writeText(text)

copyToClipboard("This Sring is Copied To Clipboard.")


🔜 Определение темного режима
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches

console.log(isDarkMode)
// Результат: True или False


🔜 Получение случайного числа в определенном диапазоне
const randomNumberInRange = (min = 0, max = 100) => Math.floor(Math.random() * (max - min + 1)) + min

randomNumberInRange()
// Получите случайное число по умолчанию от 0 до 100

// В качестве аргументов вы указываете минимальное и максимальное значение
randomNumberInRange(100, 200)
// Получите случайное число в диапазоне от 100 до 200


🔜 Прокрутка к верху страницы
const goToTop = () => window.scrollTo(0, 0)

goToTop()


🔜 Переключение “показать/скрыть элемент”, используя значение свойства CSS display
const toggleElementDisplay = element => element.style.display = (element.style.display === "none" ? "block" : "none")

toggleElementDisplay(document.body)


👍 - если было полезно

👉 jsProger | #однострочники
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Colourful Flower Popup Menu — набор действий на странице. Реализована с помощью CSS и JavaScript

#анимация #css #javascript
1
WebTaverna /> js, css, html
🖥 Меняем title вкладки, если пользователь перешел на другую // Когда пользователь переключается на другую вкладку window.addEventListener('blur', () => { document.title = 'Вернитесь 😢' }) // Когда пользователь возвращается на вашу страницу window…
Изменений скрипт: Меняем title вкладки, если пользователь перешел на другую страницу

const originalTitle = document.title;
window.addEventListener('blur', () => {
  document.title = 'Повернись 😢';
});

window.addEventListener('focus', () => {
  document.title = originalTitle;
});
​​Календарь на чистом Js (1часть):
Let
let selectedDate = null;
let currentMonth = new Date().getMonth() + 1;
let currentYear = new Date().getFullYear();
const today = new Date();

// Массив названий месяцев
const monthNames = [
  "Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень",
  "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"
];

function createCalendar(elem, year, month) {
  let mon = month - 1;
  let d = new Date(year, mon);
  let daysHtml = "";

  for (let i = 0; i < getDay(d); i++) {
    daysHtml += '<div class="date-calendar__day--blank"></div>';
  }

  while (d.getMonth() === mon) {
    let isToday =
      d.getFullYear() === today.getFullYear() &&
      d.getMonth() === today.getMonth() &&
      d.getDate() === today.getDate();
    daysHtml += <div class="date-calendar__day ${isToday ? "date-calendar__day--today" : ""}" data-date="${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}" data-day="${getDay(d)}">${d.getDate()}</div>;
    d.setDate(d.getDate() + 1);
  }

  let calendarHtml = `
                <div class="date-calendar__headline-block">
               <div class="date-calendar__date text--xxxxs">${monthNames[mon]} ${year}</div>
              <div class="date-calendar__prev-and-next">
                        <button type="button" class="date-calendar__prev _icon-arrow-bottom"></button>
                        <button type="button" class="date-calendar__next _icon-arrow-bottom"></button>
              </div>
                </div>
                <div class="date-calendar__weeks">
                    <div class="date-calendar__week text--xxxxxs">Пн</div>
                    <div class="date-calendar__week text--xxxxxs">Вт</div>
                    <div class="date-calendar__week text--xxxxxs">Ср</div>
                    <div class="date-calendar__week text--xxxxxs">Чт</div>
                    <div class="date-calendar__week text--xxxxxs">Пт</div>
                    <div class="date-calendar__week text--xxxxxs">Сб</div>
                    <div class="date-calendar__week text--xxxxxs">Нд</div>
                </div>
                <div class="date-calendar__days">${daysHtml}</div>
                <div class="date-calendar__button-block">
                    <button type="button" class="date-calendar__button button button--l button--shadow-two border-one--color-five bg-seven b-radius-one date-calendar__button--cancel"><span class="date-calendar__button-text button__text text--xxxxs">Скасувати</span></button>
                    <button type="button" class="date-calendar__button button button--l button--shadow-two border-one--color-five bg-two b-radius-one date-calendar__button--apply"><span class="date-calendar__button-text button__text text--xxxxs">Застосувати</span></button>
                </div>
            `;

  document.querySelector(elem).innerHTML = calendarHtml;

  // Добавляем обработчик клика на день
  document.querySelectorAll('.date-calendar__day').forEach(day => {
    day.addEventListener('click', function () {
      // Убираем активный класс с всех дней
      document.querySelectorAll('.date-calendar__day').forEach(d => d.classList.remove('date-calendar__day--active'));
      // Добавляем активный класс
      this.classList.add('date-calendar__day--active');
      selectedDate = this.getAttribute('data-date');
      // Убираем активный класс у дней недели
      document.querySelectorAll('.date-calendar__week').forEach(w => w.classList.remove('date-calendar__week--active'));
      // Добавляем активный класс к соответствующему дню недели
      let dayIndex = this.getAttribute('data-day');
      document.querySelectorAll('.date-calendar__week')[dayIndex].classList.add('date-calendar__week--active');
    });
  });
  // Обработчики переключения месяцев
  document.querySelector('.date-calendar__prev').addEventListener('click', (event) => {
    event.stopPropagation();
    currentMonth -= 1;
    if (currentMonth < 1) {
      currentMonth = 12;
      currentYear -= 1;
    }
    createCalendar('#calendar', currentYear, currentMonth);
  });
2-я часть:
document.querySelector('.date-calendar__next').addEventL
(event) => {
    event.stopPropagation();
    currentMonth += 1;
    if (currentMonth > 12) {
      currentMonth = 1;
      currentYear += 1;
    }
    createCalendar('#calendar', currentYear, currentMonth);
  });
  // Обработчик кнопки "Скасувати"
  document.querySelector('.date-calendar__button--cancel').addEventListener('click', () => {
    // document.getElementById('calendar').style.display = 'none';
    calendar.classList.remove('calendar-and-search__calendar--open'); // Убираем класс open
  });
  // Обработчик кнопки "Застосувати"
  document.querySelector('.date-calendar__button--apply').addEventListener('click', () => {
    if (selectedDate) {
      document.getElementById('cal-1').value = selectedDate;
    }
    // document.getElementById('calendar').style.display = 'none';
    calendar.classList.remove('calendar-and-search__calendar--open'); // Убираем класс open
  });
}

// Функция для получения дня недели (0 = Пн, 6 = Нд)
function getDay(date) {
  let day = date.getDay();
  return (day === 0) ? 6 : day - 1;
}
// Открытие календаря при клике на input
document.getElementById('cal-1').addEventListener('click', function () {
  let calendar = document.getElementById('calendar');
  createCalendar('#calendar', currentYear, currentMonth);
  // calendar.style.display = 'block';
  calendar.classList.add('calendar-and-search__calendar--open'); // Добавляем класс open
});
// Закрытие календаря при клике вне него
document.addEventListener('click', function (event) {
  let calendar = document.getElementById('calendar');
  let input = document.getElementById('cal-1');

  if (!calendar.contains(event.target) && event.target !== input) {
    // calendar.style.display = 'none';
    calendar.classList.remove('calendar-and-search__calendar--open'); // Убираем класс open
  }
});
3-я часть:
<input class="calendar-and-search__input b-radius-one" type="text" placeholder="Оберіть дату"
name="calendar" id="cal-1">
<div id="calendar"
class="calendar-and-search__calendar date-calendar bg-seven c-five b-radius-sex">
</div>
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
✏️ Анимация подписи на JavaScript

Интересная задумка! Когда пользователь вводит какой-либо текст, то он преобразовывается в словно написанную от руки подпись


Код и демо: codepen.io/kiranpate1/pen/ExBpaeW
3
This media is not supported in your browser
VIEW IN TELEGRAM
Анимированный текст с градиентом на 🔠🔠🔠

HTML разметка
<h1>t.me/WebTaverna</h1>


CSS стили
h1 {
background: linear-gradient(90deg,
#d988da, #dcde8a, #d988da);
background-repeat: no-repeat;
background-size: 80%;
animation: animate 3s linear infinite;
-webkit-background-clip: text;
-webkit-text-fill-color: rgba(255, 255, 255, 0);
}
@keyframes animate {
0% { background-position: -500%; }
100% { background-position: 500%; }
}


👍- если было полезно | ➡️ WebTaverna
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
🔰 Эффектное меню для сайта с помощью CSS

Код и демо: codepen.io/ig_design/pen/XWXZaGb
Please open Telegram to view this post
VIEW IN TELEGRAM
Как добавить жирность при наведении?
Все очень просто. Пишим дата атрибут data-text="какой-то текст":

<a data-text="Про нас" href="#" class="menulink menulink--text">Про нас</a>

И теперь нужно прописать некие стили в псевдоелемент content: attr(data-text) :

 &__link {
    position: relative;
    transition: all 0.3s;
    font-size: 20px;
    line-height: 1.00; /* 20px */
    font-weight: 400;
    &::before{
      content: attr(data-text);
      position: absolute;
      top: 0;
      left: 0;
      display: block;
      font-size: 20px;
      font-weight: 500;
      line-height: 1.00; /* 20px */
      opacity: 0;
      white-space: nowrap;
      transition: opacity 0.3s ease;
      color: rgb(0, 0, 0);
    }
    @media (any-hover: hover){
      &:hover{
        color: $orangeColor;
      }
    }
    @media (max-width: toEm($mobile)) {
    }
  }




@media (any-hover: hover){
        &:hover{
          .menu__link {
            // color: $orangeColor;
            // color: rgb(0, 0, 0);
            // font-weight: 500;
            // transform: scale(1.1);
            &--text {
              color: transparent;
              &::before{
                content: attr(data-text);
                opacity: 1;
              }
            }
          }
        }
      }

Готово теперь при наведении текст будет жирным.