Задать вопрос
  • Как сделать изображения адаптивнной?

    delphinpro
    @delphinpro Куратор тега CSS
    всё верно, чудес не бывает.

    4 вариант.
    Готовить картинки вручную, одного размера, с одной пропорцией.
    Сделать обертку с этой пропорцией (через padding-bottom) и растянуть картинку внутри.
  • Как правильно сделать две колонки на flexbox?

    delphinpro
    @delphinpro Куратор тега CSS
    Ankhena, ну я же поменял разметку. Думаю лдя него некритично, он только пилит верстку, а не дорабатывает.
  • Стоит ли реализовывать такой подход и если да, то как скомпилировать?

    Есть два режима — development и production.
    Первый, как вы понимаете, для разработки, в нем даже файлы на диске не создаются (говорю за Vue + Webpack)
    Второй — как раз для продашена, всё собирается в несколько файлов (index.html, main.js, main.css, в зависимости от настроек). Эти файлы просто заливаются на сервак.

    Для серверного рендера страницы, если он требуется, уже запускают инстанс ноды или прикручивают v8js к php (для любителей поизвращатся). Этот инстанс только собирает страницу при первом запросе, ничего более (в основном для поисковиков, ну и для более быстрого отображения первого запроса). Остальное также подключается статикой.
  • Как оптимизировать подгрузку содержимого?

    delphinpro
    @delphinpro Куратор тега JavaScript
    Фризы когда появляются? Возможно слишком много коментов на странице накапливается. Попробуйте удалять те, что уже далеко вверху (просмотренные)
  • Начали поступать письма как бы с моего ящика на мой, Стоит опасаться или развод?

    EYPPNM, да элементарно

    $to      = 'nobody@example.com';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: webmaster@example.com' . "\r\n" . // ЛЮБОЙ АДРЕС!!!
        'Reply-To: webmaster@example.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();
    
    mail($to, $subject, $message, $headers);
  • Есть ли скрипт очень лёгкого календаря для выбора даты?

    delphinpro
    @delphinpro Куратор тега JavaScript
    Можно ли сэкономить на загрузке если на сервере средствами php сгенерить календарь, например, только на один конкретный месяц?


    Зачем? Любой месяц генерится на клиенте, джаваскриптом.

    очень лёгкого календаря


    Можно и свой скрипт накидать, строк на 100-200.

    Вот например, из недавнего. Там всплывающие подсказки, их можно урезать.
    Говнокалендарик, зато легкий =)
    //==
    //== Calendar
    //== ======================================= ==//
    
    (function () {
        const baseClass = 'calendar';
        const directions = {
            prev: { cls: 'prev', icon: 'arrow-left' },
            next: { cls: 'next', icon: 'arrow-right' },
        };
    
        const weekDays = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс'];
    
        const months = [
            'Январь',
            'Февраль',
            'Март',
            'Апрель',
            'Май',
            'Июнь',
            'Июль',
            'Август',
            'Сентябрь',
            'Октябрь',
            'Ноябрь',
            'Декабрь',
        ];
    
        class Calendar {
            /**
             * @param {HTMLElement} el
             * @param {Array} events
             */
            constructor(el, events) {
                this.data = {
                    monthName: 'default',
                };
    
                this.events = events;
    
                /** @var {HTMLElement} */
                this.el = el;
                /** @var {HTMLElement} */
                this.elDays = null;
    
                /** @var {Date} */
                this.today = new Date();
                this.updateStartDate(this.today.getFullYear(), this.today.getMonth());
    
                this.el.appendChild(this.makeHeader());
                this.el.appendChild(this.makeWeekDays());
                this.el.appendChild(this.makeMonthDays());
    
                this.displayYear = this.today.getFullYear();
                this.displayMonthIndex = this.today.getMonth();
                this.displayMonth = months[this.displayMonthIndex] + ' ' + this.displayYear;
    
                this.el.addEventListener('mouseover', event => {
                    let handler = event.target.closest('.events');
                    if (handler) {
                        let content = handler.querySelector('.popper');
                        if (content) {
                            tippy(handler, {
                                content: `<div class="popper">${content.innerHTML}</div>`,
                                arrow: true,
                                arrowType: 'round', // sharp, round
                                interactive: true,
                                // trigger:'click'
                            });
                        }
                    }
                });
            }
    
            updateStartDate(fullYear, monthIndex){
                this.firstDayDate = new Date(fullYear, monthIndex, 1);
                this.firstDayOfMonth = this.firstDayDate.getDay();
                if (!this.firstDayOfMonth) this.firstDayOfMonth = 7;
                this.startDate = new Date(
                    this.firstDayDate.getFullYear(),
                    this.firstDayDate.getMonth(),
                    this.firstDayDate.getDate() - this.firstDayOfMonth + 1,
                );
            }
    
            get displayMonth() { return this.data.monthName; }
    
            set displayMonth(val) {
                this.data.monthName = val;
                this.elTitle.innerHTML = val;
            }
    
            makeHeader() {
                const el = document.createElement('div');
                const btnPrev = this.makeNavButton('prev');
                const btnNext = this.makeNavButton('next');
                el.classList.add(`${baseClass}__header`);
                el.appendChild(btnPrev);
                el.appendChild(this.makeMonthTitle());
                el.appendChild(btnNext);
    
                btnPrev.addEventListener('click', event => {
                    if (this.displayMonthIndex - 1 >= 0) {
                        this.displayMonthIndex--;
                    } else {
                        this.displayMonthIndex = 11;
                        this.displayYear--;
                    }
                    // console.log(this.displayMonthIndex, this.displayYear);
                    this.displayMonth = months[this.displayMonthIndex] + ' ' + this.displayYear;
                    this.updateStartDate(this.displayYear, this.displayMonthIndex);
                    this.updateMonthDays();
                });
    
                btnNext.addEventListener('click', event => {
                    if (this.displayMonthIndex + 1 <= 11) {
                        this.displayMonthIndex++;
                    } else {
                        this.displayMonthIndex = 0;
                        this.displayYear++;
                    }
                    console.log(this.displayMonthIndex, this.displayYear);
                    this.displayMonth = months[this.displayMonthIndex] + ' ' + this.displayYear;
                    this.updateStartDate(this.displayYear, this.displayMonthIndex);
                    this.updateMonthDays();
                });
    
                return el;
            }
    
            makeMonthTitle() {
                this.elTitle = document.createElement('div');
                this.elTitle.classList.add(`${baseClass}__month-title`);
                this.elTitle.innerHTML = this.displayMonth;
                return this.elTitle;
            }
    
            makeNavButton(direction) {
                if (!directions.hasOwnProperty(direction)) {
                    throw new Error('Неверный параметр (prev/next)');
                }
    
                const el = document.createElement('button');
                el.classList.add(`${baseClass}__button`);
                el.classList.add(`${baseClass}__button_${directions[direction].cls}`);
                el.innerHTML = App.makeSvgIcon(directions[direction].icon, `${baseClass}__btn-icon`);
                return el;
            }
    
            makeWeekDays() {
                const el = document.createElement('div');
                el.classList.add(`${baseClass}__weekdays`);
                el.innerHTML = weekDays.reduce((acc, cur) => acc + `<div class="${baseClass}__weekday">${cur}</div>`, '');
                return el;
            }
    
            updateMonthDays(){
                let html = '';
                let counter = 0;
                let isMuted = this.startDate.getDate() !== 1;
    
                let idCounter = 1;
                while (counter < 7 * 6) {
                    let start = this.startDate.getDate();
                    let mutedClass = isMuted ? ` ${baseClass}__day_muted` : '';
                    let events = this.events.find(item => {
                        let d1 = this.startDate.getFullYear().toString()
                            + this.startDate.getMonth().toString()
                            + this.startDate.getDate().toString();
                        let _T = new Date(item.date);
                        let d2 = _T.getFullYear().toString()
                            + _T.getMonth().toString()
                            + _T.getDate().toString();
                        return d1 === d2;
                    });
    
                    let pastEvent = false;
    
                    if (events) {
                        let eventDate = new Date(events.date);
                        if (eventDate < this.today) {
                            pastEvent = true;
                        }
                    }
    
                    let innerHtml = `<span>${start}</span>`;
    
                    if (events && events.events && events.events.length > 0) {
                        let eventsHtml = events.events.reduce((p, i) => `${p}<a href="${i.link}">${i.title}</a>`, '');
                        innerHtml = `<span class="events ${pastEvent
                            ? 'past'
                            : ''}">${start}<span class="popper" id="iddpr${idCounter++}" hidden>${eventsHtml}</span></span>`;
                    }
    
                    html += `<div class="${baseClass}__day${mutedClass}">${innerHtml}</div>`;
                    counter++;
                    this.startDate.setDate(this.startDate.getDate() + 1);
                    if (this.startDate.getDate() === 1) { isMuted = !isMuted; }
                }
    
                this.elDays.innerHTML = html;
            }
    
            makeMonthDays() {
                this.elDays = document.createElement('div');
                this.elDays.classList.add(`${baseClass}__days`);
                this.updateMonthDays();
                return this.elDays;
            }
        }
    
        App.calendar = function (el, data) {
            if (!el) return;
    
            return new Calendar(el, data);
        };
    
    })();
  • Как убрать отступ?

    delphinpro
    @delphinpro Куратор тега CSS
    Браузер применяет к некоторым элементам стили по-умолчанию.
    Откройте для себя инструмент в браузере — инспектор элементов. Там вы всё сможете увидеть своими глазами.
  • Кто как делает разметку по БЭМ?

    Заголовок вполне может быть, и чаще всего есть, отдельным блоком. Дополнительные стили в контексте родительского блока миксуются через элемент этого блока.

    Контейнер тоже есть самостоятельный блок. И к нему так же могут миксоваться дополнительные стили.

    Всё нормально, никаких противоречий.
  • Как сделать поиск по странице?

    delphinpro
    @delphinpro Куратор тега JavaScript
    Stalker_RED, Интересно, застаррил, посмотрю на досуге.
  • Кто может проверить верстку / сборку лендинга на flexbox / сделать код ревью?

    delphinpro
    @delphinpro Куратор тега CSS
    jupyter, насчет body я неточно написал — имел ввиду, что этот элемент не должен участвовать в раскладке страницы, быть частью сетки. Любые другие стили — пожалуйста.
  • Какой самый простой способ шаблонизации html-страниц (js)?

    delphinpro
    @delphinpro Куратор тега JavaScript
    А все эти паги от лукавого =)) ни к чему учить еще один синтаксис...
  • Какой самый простой способ шаблонизации html-страниц (js)?

    delphinpro
    @delphinpro Куратор тега JavaScript
    Spaceoddity, Вам для верстки, не для сайта, я так понимаю.

    Если хочется совсем простого и эйчтиэмэльного, посмотрите на gulp-twig (или другие порты этого шаблонизатора под нужную вам систему)

    Как раз то что вам нужно:

    {% include './blocks/header.twig' %}
    <div class="my-page">
      bla
    </div>
    {% include './blocks/footer.twig' %}


    Ну и остальные плюшки постепенно освоите в процессе использования.
  • Зачем нужен frontend, если всю начинку сайта или проекта можно реализовать с помощью backend'a?

    Ага. А давайте вы вконтактик напишете без html/css/javascript. Вот тогда будет о чем разговаривать.

    Не вопрос, а толстый троллинг.
  • Кто может проверить верстку / сборку лендинга на flexbox / сделать код ревью?

    delphinpro
    @delphinpro Куратор тега CSS
    Spaceoddity, но ведь это вы прицепились к БЭМу =))
    Я лишь упомянул его, как один из вариантов.
    Попробуем еще раз, снова.

    Порядок и система в стилях должны быть. С этим, надеюсь, не будете спорить.
    Какую методологию вы выберете - не суть важно. Вернемся к пресловутой кнопке, о которой я написал замечание.
    .button { margin-top: 40px; ... }
    Это очень плохо. Для примитивной единственной страницы — допустимо, для сайта — нет. Кнопки разные, по разному расположены, и нельзя в базовый стиль кнопки писать такое правило, чтобы потом не переопределять его везде где надо и не надо.

    Лирическое отступление для полного понимания:
    Читая слово "кнопка" подразумевайте любой блок на страницах.


    Используя бэм, мы примиксуем в кнопке элемент родительского блока

    <div class="super-block">
      <button class="button super-block__button"></button
    </div>
    .super-block__button { margin-top: 40px; }


    Используя AtomicCSS мы напишем утилитарный класс, что то типа:
    <button class="button mt40"></button>
    .mt40 { margin-top: 40px; }


    Используя OOCSS мы опять же разделим стили структуры и стили оформления.
    И т.д.

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

    Это вам заодно и ответ о независимых блоках. С ними верстка более гибкая, ее сложнее сломать. И на всякий случай уточню, чтобы избежать лишних вопросов: независимые блоки — это не только лишь БЭМ. Я бы даже сказал, это вовсе не БЭМ. БЭМ реализует эту идеологию, но имплементации могут быть разными.

    Что вы думаете по поводу каскадирования?


    Что тут думать? Богатство возможностей CSS прекрасно. И им стоит пользоваться. Я не впадаю в крайности.
  • Кто может проверить верстку / сборку лендинга на flexbox / сделать код ревью?

    delphinpro
    @delphinpro Куратор тега CSS
    Spaceoddity,
    Вы совершенно не поняли о чем я написал.
    Ответьте на один вопросик: по вашему нормально спорить, не разбираясь в предмете? Поучитесь еще годик-другой, тогда возможно, нам с вами будет о чем подискутировать.

    Поймите, я не позиционирую себя богом верстки. Хотя и опыт у меня огромный. И для споров открыт, когда предмет спора стоит того. Но когда речь идет о базовых вещах, которые давным давно устоялись, которые проверены сотнями разработчиков и по сути являются неписанными правилами, я не вижу смысла в дискуссии. Вы либо принимаете чужой опыт, либо сами его получаете путем проб и ошибок, придя в итоге в ту же точку.
  • Как сделать такой же текст с линией, как на скрине?

    delphinpro
    @delphinpro Куратор тега CSS
    google: "horizontal line with words", "line on side header"
  • Кто может проверить верстку / сборку лендинга на flexbox / сделать код ревью?

    delphinpro
    @delphinpro Куратор тега CSS
    Spaceoddity, Позиционировать от контекста. Как именно — зависит от выбранной методики. Если это БЭМ, то элементами, если это Атомик, то утилитарными классами, и т.д.

    На второе отвечать не буду, потому что глупость написали.