- Видео 49
- Просмотров 57 747
Алексей Сигеев - Frontend
Россия
Добавлен 2 сен 2015
Привет! Я верстаю и пишу фронтенд c 2016 года. Работал в финтехе, биотехе, крупном российском банке и на фрилансе. Здесь я рассказываю про Frontend и делюсь своим опытом из мира IT. Подписывайся
Адаптивная верстка сайта с нуля: HTML, SASS, BEM
Друзья, это видео для тех, кто знает базовый HTML и CSS.
В нём я буду адаптивно верстать лендинг, ссылку на который вы можете найти ниже.
Также я объясню на примерах следующую теорию:
1) Что такое адаптивная и резиновая верстка и зачем это нужно;
2) Что такое css-препроцессоры, зачем они нужны и как ими пользоваться;
3) Как использовать методологию BEM для именования классов в разметке;
4) Что такое компонентный подход в разработке интерфейсов;
5) Что такое svg-спрайты, зачем они нужны, как их создавать.
Лендинг сверстаем частично, а остальное останется вам в качестве домашнего задания.
Приятного просмотра
Полезные ссылки:
Дизайн лендинга: www.figma.com/community/file/1230604708032389430
Репозиторий ...
В нём я буду адаптивно верстать лендинг, ссылку на который вы можете найти ниже.
Также я объясню на примерах следующую теорию:
1) Что такое адаптивная и резиновая верстка и зачем это нужно;
2) Что такое css-препроцессоры, зачем они нужны и как ими пользоваться;
3) Как использовать методологию BEM для именования классов в разметке;
4) Что такое компонентный подход в разработке интерфейсов;
5) Что такое svg-спрайты, зачем они нужны, как их создавать.
Лендинг сверстаем частично, а остальное останется вам в качестве домашнего задания.
Приятного просмотра
Полезные ссылки:
Дизайн лендинга: www.figma.com/community/file/1230604708032389430
Репозиторий ...
Просмотров: 1 303
Видео
Вёрстка сайта с нуля: создаём простую страницу на HTML и CSS
Просмотров 1 тыс.4 месяца назад
Вёрстка сайта с нуля: создаём простую страницу на HTML и CSS
Codewars: Sudoku solver. Разбираем алгоритм и код на Javascript.
Просмотров 1,3 тыс.5 месяцев назад
Codewars: Sudoku solver. Разбираем алгоритм и код на Javascript.
Создаем UI-KIT с нуля на Storybook. Экспресс-гайд: от теории до публикации и использования
Просмотров 4,9 тыс.5 месяцев назад
Создаем UI-KIT с нуля на Storybook. Экспресс-гайд: от теории до публикации и использования
IT-профессия за полгода - это реально?
Просмотров 9896 месяцев назад
IT-профессия за полгода - это реально?
спасибо за урок, продолжай братан
Красава мужик!! Шикарный гайд без воды
Очень качественно, коммент для поддержки
Здравствуйте, вопрос возник. А для чего тут применение относительных единиц(rem)? обычно видел их использование в кейсах, где под адаптив свойство font-size элемента html меняли условно с 10 до 8px и т.д(вроде это даже bad practice у некоторых считается), чтобы масштаб всей страницы уменьшить на адаптиве, но тут я конкретного применения под эти цели не увидел.
Привет! Использование относительных единиц - это лучшая практика, чем использование абсолютных, даже несмотря на то, что тут они как будто не особо нужны. Мы всегда делаем задел на будущее, чтобы можно было что-то исправить в одном месте, а не бегать по всему проекту, когда дизайн-система изменится. С этим и переменные нормально справляются, конечно, но тем не менее. Но для элементов UI, размеры которых не должны меняться относительно шрифта страницы, можно использовать px. Например толщина рамки, тени и т.д.
@alsigeev Понял, можно же не ставить в селекторе html font-size:10px, а просто через sass mixin всё конвертировать?
@@pidoras1234 Если мы говорим про rem-ы, то нельзя. Если про альтернативную работу с размерами, то можно, но выглядит избыточно. Придётся везде тащить этот миксин, постоянно закидывать в него аргументы и стили станет сложно читать
Привет, столкнулся с проблемой с переменными чтоб они заработали, мне нужно было писать @use "variables" в каждом scss файле где они использовались, также нужно было возле прописанных переменных писать слово variables. Типа так font-family: variables.$font-family. И только после этого все работало. Как иначе можно решить эту проблему?
Привет! Действительно, в свежей версии sass директива @import помечена как устаревшая, поэтому в терминале сыпятся ошибки. Теперь вместо неё предлагают использовать @use. Отличие том, что с использованием @use файлы импортируются как независимые модули и не видны друг для друга. Поэтому в каждый файл нужно добавить переменные, а из главного файла index.scss импорт переменных можно удалить. Чтобы получилось чуть короче, можно указать альтернативное название импортируемого модуля примерно так: @use "./variables" as vars; Тогда в стилях запись станет короче: vars.$color-green;
@@alsigeev Спасибо за помощь
Задача: www.codewars.com/kata/55bf01e5a717a0d57e0000ec tg: t.me/sigeev_frontend
sass с недавнего времени просит импортировать не через @import а через @use
Есть возможность залить в VK или Rutube - ?
@@frankshepherd5953 залью ВК позже. Ссылку здесь оставлю
Залил в вк. Ссылку оставил в шапке профиля
классно, было полезно посмотреть как это делает более опытный человек, пасибаа!!
мазахист vs code с белой темой на 2 минуте уже смотреть даже желание отпадает
Брат, сидел на темной, когда писал на убунте и sublime text был популярен. Постарел и глаза начали уставать. Ты уж прости, что не угодил
дизайн верстаемого проекта похож чем-то на одну известную ИТ-инет-школу))))
Мне так же сказал друг, когда я делал обложку на базе темы этого дизайна) Взял в фигма комьюнити тот, который показался симпатичным. Там даже есть контакты автора, в самом дизайне.
О! Кто-то еще BEM юзает
Уже не особо, но раньше всегда юзал. Дополнительная ачивка: учишься придумывать названия блокам на английском
Привет! Отличное видео, спасибо!
Нельзя сравнивать backend и frontend. Это как сравнивать сварщика и слесаря.
Проблема в том, что фронты думают, что раз они могут писать бек на js, то они считаются фуллстеками. При этом человек не знает банальную теорию ОС или уровни OSI. Чем отличается поток от процесса или многопоточность от асинхронности? Одно дело, когда фронт может стандартными компонентами nodejs развернуть веб-сервер, реализовать маршрутизацию, а также реализовать код для работы с сервером. Другое дело, развернуть веб-сервер на express/next/next/nest и тд...
@ConstantineKa, fullstack в таком случае будет лишь знать базово, что база данных - это просто хранилище. Но как это хранилище устроено, как оптимизировать доступ к нему, как соблюдать ACID, чем SQL базы отличается от NoSQL, как настроить ролевую модель доступа к данным. И компоненты базы данных они тоже вряд ли знают: процедуры, триггеры, представления. Про всякие репликации, шардирования вообще молчу. Одго дело знать теорию многопоточного программирования - другое дело реализовать его на практике и столкнуться порой с непредсказуемыми результатами. Как я знаю - JavaScript однопоточный язык и многопоточность там сгодится только для I/O операции. Ни в коем случае не умаляю заслуг FrontEnd разработчиков.
как же он оправдывает фронт ахахахахаза
Фронтенд сила 😂
Стать сеньером за 3 года не возможно 🤣 Отдохнул бы немного.
Друзья, обязательно пишите как вам видео и подача материала, что нравится и не нравится, задавайте вопросы по теме. Буду рад пообщаться в комментах.
Как full stack разработчик заявляю - backend на порядок сложнее. Front в 90% случаев это типовые задачи, а back это постоянно какой-то геморрой.
Я читаю бэк посложнее потому что по мимо разработки бэк приходится вникать в бизнес логику, на предыдущем месте работы мы бжу и фронт ходили на общие созвоны ну и тесно общались, и зачастую бэк объяснял фронту бизнес логику, ято где работает и т.д., при этом по моему личному ощущению на бэуе очень много дополнительных приколов такие как sql и no-sql базы, метрики, статистика, кэширование, логирование, взаимодействие между сервисами, в общем много внешних инструментов по мимо базовых которые нужно так же хорошо понимать, тот же ci cd и sql уже не простые навыки
Мне кажется что стоит разделять понятия бизнес-логики и написания бэка. Бизнес-логика - это когда надо провалиться в конкретную доменную область и изучить её, чтобы потом нормально написать сервис. Порой часть бизнес-логики вполне себе реализуется на стороне фронта, как бы ни хотелось сбросить это целиком на бекенд и просто рисовать json, а потом на дейликах говорить: "Проблема на бекенде, хехех". А если отбросить бизнес-логику, то что прям сложного в освоении можно придумать? Ну да, иногда сидишь, куришь интеграции всякие, очереди и т.д, то есть дружишь инструменты и фреймворки между собой. Это всё требует времени, но не является неподъемной концепцией. Но и на фронте таких приколов тоже достаточно.
@@alsigeev ну как минимум базы и перформанс.
Тут категорически не согласен. Хоть и работаю инженером данных, но во Frontend есть адаптивная верстка, + тяжело поддерживать отображение на разных разрешениях устройств.
Вот пилить архитектуру бд, модель данных (data vault, anchor, звезда, 3-я нормальная форма). Разбираться за репликации и шаржирование. Оптимизировать запросы(разбираться как устроены индексы в памяти - какой из них лучше использовать, разбираться с планом запроса, смотреть, какой физический join (hash или nested loop или merge). Разбираться в конфигах базы данных, работать с ролевой моделью доступа,, настраивать AD. Шарить за процедуры, функции, триггеры. И это еще маленькая часть того, что нужно знать. Ааа, точно. Работа с транзакциями, блокировщиками запросов - мое самое любимое. А писать SQL и ни о чем не думать может практически любой.
А если серьёзно. В чем сложность фронта? Дизайнер тебе дал картинку. Ты её через флекс по строчкам/колонкам побил и готово. С tailwind-ом вообще сказка. Даже с учётом реакта, бекендер освоит фронт за месяц при долгой мотивации. А вот фронтендер дальше CRUDа в беке за месяц не продвинится.
Хехехех, baited Представления о фронте как о наборе кнопок во флексовых колоночках - это ровно то же, что и представление о бэке как о наборе CRUDовых ручек и бесконечном клепании микросервисов 😁 И там, и там есть специфичные вещи, которые решаются не за 10 минут. Если уж разбираться, то надо начинать с того, какой специализации разраба мы берём за основу. Если это новичок без бэкграунда, то очевидно что будет сложно и там, и там. Не то чтобы print на питоне увидеть сложнее, чем кнопку во флексовой колоночке 😉 А если брать что-то сложнее CRUDа, то вы же не думаете что сильный сеньорный фронт не сможет разобраться в этом от слова совсем? Думаю что сможет с таким же успехом, как и сеньорный бекендер разберётся со специфичной задачей фронта, потратив какое-то время.
@@alsigeevЯ как раз и имею ввиду сильного фронта. Так уж сложилось, что все мои друзья-программисты либо фронты, либо фулстеки на ноде. И уровень их задач я знаю. Да, фронт - это долго и рутинно, но совсем не сложно. Говорю как человек, которому пришлось его освоить, будучи беком всю жизнь. На обучение ушло 2 недели. Правда, вместо реакта у меня Vue. Поэтому накинул ещё 2 недели, если реакт прям сильно сложнее(зачем тогда его использовать?). Вёрстка, состояние страниц, вызов апишек - это всё что включает в себя фронт. Сюда невозможно впихнуть больше. В то время как бек включает и архитектуру(с которой чтобы разобраться надо посчитать ни одну книгу) и разные наборы протоколов(фронты даже не знают как tcp работает), и права доступа(это тебе не галочку в состоянии страницы поставить), а если ещё и микросервисы добавить, то тут ещё и jwt, oauth, redis и sqrs. И это только то, что на поверхности.
@@AntiPolarity Я правильно понимаю что вы, будучи сеньорным бекендом, за две недели погрузились во фронт на уровень вызова апишек и работой с состоянием приложения, поэтому он кажется вам проще в освоении? Как будто если порешать задачи фронтенда чуть больше двух недель, то придёт понимание что и там есть что-то сложнее вызова апишек. Например, можно посидеть с какой-нибудь специфичной задачей с web-workers, или поработать с либой из под wasm-а, которая занимается рендером 3d-штук. Опять же, это всё вполне подъемные вещи, но требующие время на освоение не меньшее, чем задачи бекенда. Поэтому, мне кажется, мы просто упираемся в компетенцию.
@@alsigeev напоминаю, что с фронтендерами я общаюсь часто. Да, признаю, про web-workers забыл. Но там же тоже ничего сложного. А вот на счёт wasm и 3d... Вы их часто используете? Потому, что дальше чем поиграться, как мне известно, мало кто заходил. Да и я больше говорю о типичных задачах. Понятно, что на фронте можно и рейтресинг написать, но кто из фронтовиков реально это делал? Мы упираемся не в компетенцию, а в круг задачь, котрый на фронте явно уже. И да, ваше предположение в начале абсолютно верно. Но оно же основывается не чисто на моих задачах. Я на задачи для фронта смотрю каждый день. Просто посещая сайты. Мне интересно представлять как они сделаны. И я не видел сайта, кторый бы я не смог сверстать. А вот примеров очешуительно сложных беков полно. Взять тот же ютуб, к примеру. Может у вас найдётся пример сложного фронта? Я не исключаю вероятности, что я просто посещаю простые сайты и не знаю о сложных)
@@AntiPolarity Возьмите любую рисовалку типа веб-клиента figma, или miro и будет вам сложный фронтенд. А если говорить про типичные задачи бОльшей части бизнесов, которые решаются фронтендом и бэком, то мы тогда действительно спускаемся до рисования форм с кнопками на фронте и crud-ов на беке) Почти уверен что на том же ютубе работа с плеером та ещё возня)
Да как войти в гитхаб жовый крот!
Вопрос хороший, а почему именно тут?)
Весь фронт пишу через гпт, делает отлично особенно на реакте
😁Очень интересно. А продукт-то какой? В компании, или что-то для себя?
Бэкэнд все же посложнее
Например?
@ Например рест апи работающий с бд на 100 тб с которой так же работают другие сервисы и малейшая ошибка может влететь в копеечку и данные в 10 лет, а так же веб приложение где у графика не работает кнопочка, которую заметит 1 пользователь из 1000
С таким же успехом можно придумать ситуацию, когда заваливается фронт нагруженного сервиса и бизнес так же влетает в копеечку. Но здесь ни слова именно о сложности в освоении одного, либо другого. Риски для бизнеса несут любые ошибки. Может бэк для новичка действительно чуть сложнее, потому что вход не такой простой, но в остальном - не знаю, не знаю ☺️
а бэкэнд теперь входит во фронтенд. BFF называется :D
@@ne4to777 😁
Спасибо за видео и задачку! 👍 Можно её решить и как-то так: const alphabetPosition = (text) => text .toLowerCase() .replace(/[^a-z]/g, '') .replace(/./g, (char) => char.charCodeAt() - 96 + ' ') .trimEnd();
Задача: www.codewars.com/kata/546f922b54af40e1e90001da tg: t.me/sigeev_frontend
Спасибо за видео и интересную задачку! 👍 Можно её решить ещё и так: function duplicateEncode(word) { word = word.toLowerCase(); const replaceMap = new Map(); for (const char of word) { const replacement = replaceMap.has(char) ? ')' : '('; replaceMap.set(char, replacement); } return word.replace(/./gu, Map.prototype.get.bind(replaceMap)); } Такая реализация позволяет корректно обрабатывать все строки UTF-16. ☝️
word_lower = input().lower() print(''.join(')' if word_lower.count(char) == 1 else '(' for char in word_lower))
Задача: www.codewars.com/kata/54b42f9314d9229fd6000d9c tg: t.me/sigeev_frontend
Хм, ну как вариант еще модно два цикла создать, типо решотчитай структуры (создать масив из 0 в котором будет н элементов, и пробегать по нему циклом и если значение == 0 то превращаем в еденицу, если же ==1 ничего неделаем)
Если я правильно понял мысль, то тогда потом нужно будет еще раз пробежаться по массиву и посчитать все единички. Алгоритм получится чуть сложнее. А ещё дополнительную память под этот массив нулей выделить придется.
@alsigeev не я щас подумал, тут проще сделать двумя циклами, типо в одном ставим условие что не делиться на 5 , и бежим с шагом 3 и считаем сумму а во втором с шагом 5 идем и считаем сумму ну это будет чуть быстрее, чем просто проходить циклом (вроде как)
@@sawasawe6409 оптимальное решение «не в лоб» предложил @SerzhNesteruk в комментах. Оно не интуитивное, но шустрое.
Спасибо за разбор задачи! 👍 Можно предложить ещё такой вариант решения: function findOutlier(integers) { const isEven = (int) => int % 2 === 0; const isOdd = (int) => int % 2 !== 0; const oddCount = integers.slice(0, 3).filter(isOdd).length; const isOutlier = oddCount > 1 ? isEven : isOdd; return integers.find(isOutlier); }
Спасибо за видео интересную задачку! 👍 Можно её решить ещё и так: function duplicateCount(text) { const countMap = Object.create(null); let duplicates = 0; for (const char of text.toLowerCase()) { countMap[char] = (countMap[char] || 0) + 1; if (countMap[char] === 2) duplicates++; } return duplicates; } ...или даже так: function duplicateCount(text) { const seenOnce = new Map(); let duplicates = 0; for (const char of text.toLowerCase()) { if (seenOnce.get(char)) duplicates++; seenOnce.set(char, !seenOnce.has(char)); } return duplicates; }
Задача: www.codewars.com/kata/54bf1c2cd5b56cc47f0007a1 tg: t.me/sigeev_frontend
Какой смысл делать лишний цикл и вообще плюсовать элементы в объекте если можно сразу плюсовать в нужную переменную при наличии её в этом самом объекте?
Точно! Можно просто проверять наличие буквы в объекте и добавлять единицу к sum при наличии. При решении задач я не всегда думал как решить оптимальнее всего. Спасибо за идею)
Сгруппировать чётные и нечётные числа сейчас, кстати, можно и без цикла. В ES2024 вот обновы завезли. 🙂 const res = Object.groupBy(arr, (int) => int % 2 === 0 ? 'even' : 'odd');
@@SerzhNesteruk А под капотом метода там что?
@@alsigeev Ну, цикл конечно. 🙃 Но есть преимущества: более компактный синтаксис; подкапотная оптимизация; безопасность - прототипом получаемого объекта будет null, а значит коллизии с именами унаследованных свойств полностью исключены.
Про прототип и унаследованные свойства - да. Но это ж базовые задачки codewars :) Даже не leetcode. А вообще надо будет сделать видосик про метод... Пока намеренно беру базовые задачки и стараюсь не привязываться к методам конкретного языка, т.е более-менее универсальную схему предложить
Программа: почувствуй сеья тупым...
Ребята и мне иногда наваливают комментов, что чувствую то же. Так что это норм
Можно за О(1) по памяти. Нет смысла держать дополнительные массивы, запомни по одному любому четному и нечетному числу, а также суммарно сколько было четных и нечетных чисел. Если четных чисел было всего 1, то это единственное число ты и сохранил. Тоже самое и для нечетных
Точно, точно. Это я ерунду придумал с массивами.
Для работы с большими массивами можно чуть улучшить и временную сложность. У нас она сейчас Ω(n) ∧ O(n) ~ Θ(n), а можно добиться Ω(1) ∧ O(n), сделав улучшение для оптимистичного сценария (если искомое значение находится в самом начале массива). Для этого нужно взять первые три числа и опрелелить свойство большинства (чётность/нечётность), затем в цикле просто искать число с противоположным свойством и вернуть его сразу же при нахождении, не дожидаясь окончания обхода массива.
Эту идею можно реализовать по-разному. Например, лаконично получается через побитовые операторы: function findOutlier(integers) { const [a, b, c] = integers; const mod2 = (a & 1) + (b & 1) + (c & 1) >> 1; for (const num of integers) { if (num & 1 ^ mod2) return num; } }
Задача: www.codewars.com/kata/5526fc09a1bbd946250002dc tg: t.me/sigeev_frontend
Можно решить и за константное время (вместо линейного). Например, как-то так: function solution(number) { if (number < 3) return 0; const sumMultiples = (k) => { const count = Math.floor((number - 1) / k); return k * count * (count + 1) / 2; }; return sumMultiples(3) + sumMultiples(5) - sumMultiples(15); }
Шустро) Но мне не совсем понятно как интуитивно к этому прийти
@alsigeev Нужно чуточку школьной математики) Просто немножко адаптируем формулу суммы арифметической прогрессии, затем складываем суммы кратных 3 и 5, затем отнимаем сумму кратных 15 (3*5), так как они просуммированы дважды.
@@SerzhNesteruk, ну тут частный случай формулы включения/исключения, что не во всех школах рассказывают, а уже в курсе дискретки в вузах
@@undefined_5396 Кратность чисел, теория множеств, арифметическая прогрессия - это не очень сложные темы, раньше они были обязательной частью школьного курса математики. Допускаю, что за последние годы это могло как-то измениться. 🤷♂️
В условии написано, что запрещено логическое ИЛИ использовать? Зачем заводить объект под гласные? Переменная для суммы + цикл + 1 if со всеми гласными.
@@DimaSkart Не, не написано. Но такой код-стайл я не могу себе позволить, хоть он и самый простой. Это чистый брутфорс
В пайтоне решение - одна строка
@@far439 одна строка - это не всегда про оптимальность решения. Но я тут не осуждаю) Задачки-то лёгкие. Первое и необходимое для новичка - чтобы код работал. Дальше улучшай сколько хочешь
Можно создать список из нужных гласнвх и сделать цикл форм который будет проходится по строке и проверять есть ли эта буква в нашем списке, если есть то к переменной answer прибавляется еденица, после цикла выводим a Stroka = str Glasnuy = ['a', 'e', 'i', 'o', 'u' ] Answer = 0 For i in Stroka: If i in Glasnuy: Answer += 1 return Answer
Ага, это самое интуитивное решение. Просто проверка формата *if i in Glasnuy* будет бегать по массиву на каждом шаге цикла. Это медленнее, чем проверить, обратившись к свойствую обьекта (словаря).
Лучшее наверное сделать glasnuy set- ом, тогда проверка будет занимать O(log2(N))
А почему нельзя завести HashSet и проверить наличия глассной в этом множестве, просто это мапа немного как костыль выглядит, извините если сморозил глупость
@@vivaldi3385 Будет приличнее выглядеть, правда. У меня задача рассказать новичку про самое простое решение, пусть и костыльное немного. До Set ещё добраться надо)
Не знаю как на js, но на пайтоне можно сделать это быстре воспользовавшись count))))))
Я с python не очень дружу, но по синтаксису видно что count умеет считать кол-во вхождений символа в строке. Получается что тогда его нужно будет запускать для каждой гласной и мы будем бегать по строке несколько раз. На JS такого метода нет, но тоже можно с помощью встроенных методов написать)
Задача: www.codewars.com/kata/514b92a657cdc65150000006 tg: t.me/sigeev_frontend
Я на пайтоне за минуту написал
А благодаря единичкам в словаре цикл как-то быстрее отрабатывает? Не пойму просто зачем они, можно же в принципе и без этого обойти, разве нет?
@@_kulio_ доступ к элементу в словаре быстрее, чем поиск по строке, или массиву. На практике проще регулярку написать, или пару встроенных методов использовать.
@@alsigeev Этот объект с единичками в решении выглядит как какой-то костыль. 🩼 Правда, эти единички можно сделать хоть как-то осмысленными. Например, так: count += vowels[char] ?? 0;
Как по мне, то тут лучше использовать Set (с его методом has) или регулярку. 🧐
@ я за то, чтобы дать новичку максимально простой и понятный алгоритм с минимальным кол-вом средств языка
@@alsigeev Это хорошо. Но постоянное использование не самых подходящих для решения задачи средств языка формирует привычку, побуждающую писать запутанный и небезопасный код.
const vowels = "eyuioa"; const regex = new RegExp(`[^${vowels}]`); return str.replaceAll(regex, "").length;
Задача: www.codewars.com/kata/54ff3102c1bad923760001f3 tg: t.me/sigeev_frontend Задачка на 7kyu. Ошибся на монтаже.
а зачем сравнивать с 1 на предпоследнем шаге? просто суммируем всех
Да) Но я сообразил уже после монтажа