Как написать веб интерфейс

Как верстать веб-интерфейсы быстро, качественно и интересно

Время на прочтение
14 мин

Количество просмотров 40K

image

Всем привет! Давно хотел и наконец написал небольшую книжку — бодрое пособие по своей профессиональной области: актуальным подходам к разметке интерфейсов, экранному дизайну и доступности. Она о моем оригинальном подходе к созданию GUI, препроцессорам CSS (для объективности, немного и об альтернативных подходах), и его эффективном практическом использовании с javascript и популярными реактивными компонентными фреймворками Vue и React. Материал представлен аккуратно последовательно, но безумно интенсивно и динамично — ничего лишнего или даже слишком подробного — для того чтобы увлеченный и подготовленный читатель не потерял интереса и «проглотил на одном дыхании». С другой стороны, текст, достаточно сложный ближе к концу, и на всем протяжении — густо насыщенный идеями, ссылками на технологии и подходы — поэтому, очевидно, будет «на вырост» начинающим. Но, в любом случае, как и если вы только начали интересоваться данной тематикой, так и если уже давно занимаетесь веб-дизайном, версткой и программированием фронтенда — вам может быть полезно на него взглянуть.

Мотивация

Я уже много лет занимаюсь, прежде всего, разметкой интерфейсов, их оформлением и поведением, экранами и GUI. Участвовал на позиции верстальщика в небольших командах, стартапах, а также реализовал некоторое количество проектов самостоятельно как фрилансер, дизайнер и верстальщик. За это время я накопил некоторый опыт по специфическим проблемам в данной области, которым мне очень хочется поделиться.

Начну с некоторого огульно обобщающего и, поэтому, несколько провокационного наблюдения, «вброса»: большинство, не только начинающих, но даже опытных программистов испытывают своеобразное предубеждение-стереотип о некой «несерьезности» верстки интерфейса как отрасли деятельности в веб-индустрии — «верстка это не программирование!». Очень многие считают что заниматься разметкой «некруто и скучно» для «серьезного» специалиста. И как следствие — уделяют предмету мало своего внимания и времени, имеют мало реального релевантного опыта. Проще говоря, большинство разработчиков не любит и не умеет верстать. И уже и как причина и как следствие — зачастую сами подходы, технологии и архитектура используемые для организации GUI даже на серьезных коммерческих проектах — отставляют желать лучшего, не отвечают реалиям современной веб-индустрии, устарели и недостаточно эффективны. Неудачные, якобы временные, слабые решения и дальнейшие бесконечные быстрые «фиксы», кривые «кряки» наслаиваются друг-на-друга, кодовая база неоправданно распухает и становится все менее связной и контролируемой. Шаблоны, или ныне — в эру компонентных фреймворков — компоненты, стили и логика для них часто и закономерно превращаются в невнятную и крайне излишнюю по сути «свалку», «густой лес», «джунгли» с очевидно неподъемной ценой рефакторинга и масштабирования. Очевидно, что такое состояние системы может легко приводить к серьезным затруднениям, снижению темпов или даже срыву сроков и, ирония как раз в том, что в реальной коммерческой ситуации, авторам подобной громоздкой и неуклюжей системы, все равно придется потратить еще больше времени на то, чтобы, по крайней мере, исправить все оплошности и несовершенства разметки, оформления и логики для них, но делать это придется в изначально плохо организованном коде, по замкнутому кругу — только увеличивая беспорядок и вероятность сбоев. С того момента как вы перестаете быть «джуном», ваша ответственность состоит не только в том чтобы закрыть все «баги» на трекере и навернуть как можно скорее «фичи», любой ценой. Надежная и легко поддерживаемая система — продукт который вы продаете бизнесу.

Реальный жизненный кейс: будучи начинающим специалистом я работал удаленно в одном приятном стартапе. Когда проект запустили, после презентации многие присутствовавшие на ней высказались о том, что кегль основного текста и полей ввода в интерфейсе — мелковат. Получив задачу в трекере, я потратил всего пару минут, поправив одну переменную своей системы — чтобы поднять кегль на всех нужных полях и контролах, и еще 15 минут чтобы удостовериться что ничего действительно не сломалось ни на одном шаблоне. Ваша система изначально должна быть написана так, и только так, чтобы ее было можно легко скорректировать и улучшить, поддерживать и расширять. По-настоящему лаконичный и выразительный качественный код — невероятно мощно экономит время и нервы даже если вы работаете с проектом в одиночку. Кроме того, уважаемые авторитеты в коммерческом программировании утверждают [см. Роберт Мартин — «Чистая архитектура»] что «то что сделано изначально плохо» — в реальности, не только «никогда не будет переписано», но и приводит к постоянному крутому росту стоимости дальнейшей доставки нового функционала, а в перспективе способно полностью блокировать прогресс по проекту!

Хорошее понимание возможностей и ограничений современных браузерных технологий очень желательно и полезно не только для веб-разработчиков, но и для гуманитариев-дизайнеров проектирующих GUI. Часто даже востребованный специалист, выдающий приятный стиль и не делающих серьезных ошибок по UХ, не может внятно ответить на простейшие технические вопросы о своем дизайне при сдаче макета на верстку, то есть — «не понимает что рисует».

В этом пособии я стараюсь в достаточно доступной форме дать некоторые полезные идеи о современном экранном дизайне и эффективных способах его реализации для браузера. Я буду приводить конкретные примеры кода, но не ради специфических моментов и подробностей реализации, а, прежде всего, иллюстрируя и подчеркивая общие мысли, идеи, практические подходы, годные для написания крупных сложных современных проектов. Этот текст — не еще один занудный скучный учебник, а, скорее, «методичка углубленного спецкурса». Материал будет подаваться максимально интенсивно и насыщенно, и новичок может не справиться сходу с примерами кода или даже содержанием некоторых разделов. Не паникуйте. Важнее всего в нашей отрасли — научиться развиваться самостоятельно в выбранном направлении. Этот текст скорее призван помочь вам понять «что гуглить дальше?».

Кому будет полезен текст?

Начинающим. Вы минимально освоились со спецификациями HTML и CSS, начали пробовать JavaScript, успешно сверстали свои первые страницы, макеты и «хотите большего», хотите получить некий «дружеский пинок под зад», который поможет вам осознать дальнейшие горизонты, выйти на новый уровень и начать получать больше удовольствия и удовлетворения, как и от самой этой деятельности, так и от ее результатов.

Не верстающим как бог. Вы давно занимаетесь веб-программированием, но верстаете «нехотя и по-старинке», при этом, осознаете свой пробел в знаниях и навыках, созрели для того чтобы отбросить оковы лени и невежества, переломить ситуацию — ведь на каждом проекте разработка GUI для вас это скучная трудная рутина и мука.

Дизайнерам. Вы веб-дизайнер, но хотите начать верстать.

Эта работа о программировании дизайна и дизайне программных продуктов для фронтенда. Стоит иметь ввиду, что она написана, скорее, веб-дизайнером для веб-программистов, чем веб-программистом для веб-дизайнеров, хотя это и неточно. Я решил разделить текст на две части:

Препроцессор

В первой части представлена мощная практическая метода, дающая яркие идеи и четкие рекомендации по организации разработки стилей и разметки. Материал выбран таким образом, чтобы последовательно, но с крутой интенсивностью ввести, возможно даже, только еще минимально овладевшего HTML и CSS читателя, в мир удивительных возможностей препроцессора. Хочется показать, как можно стремительно организовать рабочую кухню, необходимую и достаточную для того чтобы эффективно создавать качественную адаптивную разметку. В этой части почти ничего не говорится о самом javascript, для того, чтобы, если читатель не освоил еще в достаточной степени язык программирования, но уже начал верстать — все равно смог бы все понять и начать внедрять на практике.

Препроцессор, JavaScript и фреймворки

Вторая часть не такая злая. Она, например, показывает в увлекательной форме некоторые углубленные интересные кейсы современного экранного дизайна и вопросов связанных с доступностью веб-приложений. В ней речь идет о практическом применении подходов к препроцессору представленных в первой части, в связке с javascript для GUI, особенно в контексте компонентных фреймворков.

Левон Гамбарян.
Июнь 2020 года.

Препроцессор


Простейший пример плохого кода

Безобразного кода с каждым днем становится все больше, несмотря на то, что больнее всего страдают от этого сами авторы, горе-разработчики. И если определенную функциональность или рендер можно покрыть тестами, то ошибки оформления выявляются только «ручками».

Также, просто парадоксально, что все программисты слышали о простых основополагающих принципах качественного программирования KISS и SOLID, но подавляющее большинство напрочь забывает о них, когда речь заходит об организации оформления, представления веб-интерфейса.

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

Давайте посмотрим на самый простейший пример плохого кода на CSS:

/* Примитивнейший пример обычного плохого кода на CSS */

/* Где-нибудь в файлах стилей: */

.selector--1 {
  width: 200px;
  height: 200px;
  border: 1px solid #ADADAD;
  border-radius: 3px;
  /* ... и дальше еще огромное количество самых разных правил */
}

.selector--2 {
  width: 200px;
  height: 400px;
  border: 1px solid #ADADAD;
  border-radius: 3px;
  /* ... и дальше еще огромное количество самых разных правил */
}

Не делайте так больше почти никогда! ))) Почему? Код валидный, «в браузере все по макету», да и все именно так обычно и пишут. Но все и не «верстают как бог», правильно? В контексте любого проекта чуть большего чем совсем крохотный, подобный код «плохой и чреват проблемами в будущем». Он конкретен и невыразителен, излишен, его сложно модифицировать и переиспользовать.

А как надо?

На сегодняшний день стандартной практикой для разработки CSS-кода является использование Препроцессора, который отнюдь не превращает формальную спецификацию CSS в язык программирования, но дает синтаксису необходимую силу и мощь, актуальные возможности и эффективность. Если говорить совсем просто, то без него, очень многие требования современного веб-дизайна иначе было бы крайне затруднительно реализовать, особенно в масштабе крупных проектов.

Справедливости ради, нужно упомянуть, что последние годы, в связи с стремительным ростом популярности компонентных js-фреймворков и их подходов, все больше сторонников набирают также различные «CSS-in-JS»-реализации (например: Styled Components). Скоро, вероятно, можно будет спокойно использовать переменные в самом CSS (CSS Custom Properties). Тема холиварная, существуют контексты и ситуации когда подобный CSS-in-JS подход может оказаться более оправданным и изящным, без сомнения. И даже существует масса реалистичных кейсов когда проще всего будет действительно обойтись несколькими наборами правил на CSS, а любое его расширение будет излишним. Но в общем случае, в реальной коммерческой практике, имхо, для верстки сложных дизайнов и интерфейсов удобнее и эффективнее всего сейчас использовать любой препроцессор, и, шок — даже с компонентным фреймворком, дальше я планирую показать «как именно это лучше всего делать». Препроцессоры дают максимум возможностей и позволяют стремиться к максимальной выразительности и переиспользуемости. Вот во что превратился бы «плохой код» выше в SCSS-синтаксисе, наверное — самого популярного на сегодняшний день препроцессора — Sass:

// В @/src/scss/utils/_variables.scss:

$colors__border: #adadad;

$border-radius: 3px;

// В @/src/scss/utils/_placeholders.scss:
%border-block {
  border: 1px solid $colors__border;
  border-radius: $border-radius;
}

// В @/src/scss/utils/_mixins.scss:
@mixin size($width, $height) {
  width: $width;
  height: $height;
}

// В любом месте проекта:
.selector {
  $selector--1__size: 200px;
  $selector--2__width: 200px;
  $selector--2__height: 400px;

  &--1,
  &--2 {
    @extend %border-block;
    /* ... включение других сущностей препроцессора
      и специфическиих правил общих для селекторов */
  }

  &--1 {
    @include size($selector--1__size, $selector--1__size);
    /* ... включение других сущностей препроцессора
      и специфических правил уникальных для селектора */
  }

  &--2 {
    @include size($selector--2__width, $selector--2__height);
    /* ... включение других сущностей препроцессора
      и специфических правил уникальных для селектора */
  }
}

Точно тоже самое легко сделать и на, кажется, недооцененном, но очень удачном Stylus — совершенно не важно какой именно расширенный синтаксис вы используете, главное как и зачем. Очень много раз мне приходилось видеть плохой чужой код написанный якобы для препроцессора, видимо, «потому что так сейчас модно», но, на самом деле, практически ничем не отличающийся от кода CSS. Не делайте так! Препроцессор дает нам крайне ценную возможность абстрагировать общие качества гайдлайна, стиль и основанные на нем частные стили, организовать их намного более выразительно и лаконично, легко модифицировать и переиспользовать при необходимости.

В данном, вырванном из контекста, но, при этом, вполне жизненном примере, кажется, что кода препроцессора — сильно больше. Он еще и раскидан по нескольким разным файлам, что, как будто, еще все усложняет. Зачем так напрягаться, а? Прежде всего, привычка начинать писать разметку с переменных и обобщений — очевидно грамотная. Перестаньте плодить изолированные глухие кряки с магическими числами, начните применять абстракцию! Делайте хорошо сразу, потому что вы почти никогда и ничего не переделаете «потом», на самом деле. «Когда наш стартап наконец взлетит», и как раз во многом из-за такого отношения он может и не взлететь, в результате. Чем детализированнее и сложнее ваш интерфейс, его дизайн, тем больше строк и времени вы будете «экономить» просто оптимизируя общие наборы правил, переиспользуя стили. Кроме того, поддерживать код и, тем более, вносить серьезные изменения будет на порядок проще.

Первый пример демонстрирует что на начальных этапах развития проекта хорошо продуманного кода препроцессора может быть даже визуально несколько больше, чем неорганизованного, внутренне плоского, скучного CSS. Но давайте разберем очень часто встречающийся кейс, в котором мы очевидно сразу сильно экономим много трафика и явно оптимизируем возможную поддержку. Такое очень часто встречается: нам нужно создать большое количество, предположим — 20 штук — модификаторов одного селектора — квадратной иконки размеров в 100 пикселей — и поставить в них нужные картинки в бекграунд. В Sass мы можем написать цикл с интерполяцией для создания селектора модификатора и указания пути до ресурса. И хотя такая синтаксическая возможность не является чем-то идейно решающе важным — на практике она экономит кучу времени и повышает качество жизни на работе:

// В @/src/scss/utils/_variables.scss:

// Paths
$images__path--root: "../../assets/images/";

// Sizes 
$icons__size: 100px;

// Views
$icons: 20;

// В любом месте проекта (в папке В @/src/scss/project/):
.icon {
  // корректируем путь до картинок
  $image-path: $image_path--root + "icons/";

  @include size($icons__size, $icons__size); // эта примесь уже создана выше

  @for $i from 1 through $icons {
    &.icon--#{$i} {
      background: url("#{$image-path}icon--#{$i}.svg") center center no-repeat;
    }
  }
}

Пример предполагает что в вашем проекте следующая структура:

.
└─ src
   ├─ assets
   │  └─ images
   │     └─ icons 
   │        ├─ icon--1.svg
   │        ├─ icon--2.svg
   │        └─ ...
   └─ sscs
      ├─ project
      │  └─ ...
      └─ utils
         ├─ _mixins.scss
         └─ _variables.scss

Теперь в шаблонах мы можем использовать:

<div class="icon icon--1"></div>

Если вы желаете чтобы картинки были с осмысленными именами — можете перебирать список:

.icon {
  $image-path: $image_path--root + "icons/";
  $images: "name1", "name2", "name3"; // Список имен

  @include size($icons__size, $icons__size);

  @each $image in $images {
    &.icon--#{$image} {
      background: url("#{$image-path}#{$image}.svg") center center no-repeat;
    }
  }
}

Ну и раз уж мы упомянули интерполяцию, необходимо вспомнить еще один простой кейс, который сейчас часто нужен и в котором вам она точно пригодится — «посчитать с переменной»:

.selector {
  $width: 100px;

  width: calc(100vw - #{$width});
}

Используйте на полную мощность и изучайте подробно свои ключевые инструменты. Применяйте свой интеллект и фантазию. В хорошем коде препроцессора наборы правил не повторяются и какдый селектор содержит только небольшое количество объявлений. Повторяющиеся и похожие наборы, большое количество самых разных объявлений в селекторах — признак плохо организованного кода. Пока бесконечный поиск и замена остаются вашим главным и единственным инструментом рефакторинга кода разметки — вы живете в каменном веке веб-технологий и еще даже не начинали верстать!)

Абстрагируй все!

Что такое дизайн, если совсем кратко? Дизайн — это «гайдлайн» — строгая система, набор стилевых правил и ограничений, перечень констант, аксиом и отношений в разметке и оформлении интерфейса, которым он неукоснительно должен соответствовать. Задача верстальщика в том чтобы правильно воспринять эту систему и максимально эффективно перевести ее с языка графических прототипов в работающий по заявленным требованиям код.

Поэтому маниакально абстрагируй все что только можно. Все что должно и может быть переиспользовано и любые конкретные значения, те, которые, когда-нибудь, но, в принципе, могут измениться. К примеру, на Stylus:

// В @/src/stylus/utils/variables.styl:

$colors = {
  mint: #44c6a8,
  // ... другие конкретные значения цветов
}

// Создаем "основной цвет", абстрагируясь от конкретного цвета
$colors['primary'] = $colors.mint
// ... другие "функциональные" цвета

Любое имеющее глобальное значение и потенциально переиспользуемое качество гайдлайна и дизайна должно быть отражено в файле переменных препроцессора. Теперь в любом месте где потребуется предоставить основной «брендовый» цвет:

.selector
  color $colors.primary

Очевидно, что если весь остальной код будет аккуратно использовать правильную переменную — просто «по щелчку пальцев» возможно изменить этот основной цвет по всему интерфейсу! Все это логично и закономерно приводить нас к идее некой общей «стилевой базы», медиатора единого стиля оформления интерфейса. Такую глобальную абстракцию легко способен предоставить препроцессор, и ее, вероятно, будет удобно использовать даже для оформления «изолированных» компонентов.

Структура и стилевая база препроцессора

Дальше я покажу определенную логичную и простую структуру организации файлов препроцессора, которую использую на проектах сам. Но вы можете что-то делать совсем иначе и, в результате, прийти к совсем другой, удобной именно для ваших методов работы системе. Важно не следовать каким-то зазубренным до автоматизма теориям и якобы «лучшим практикам», а гибко и к месту применять возможности, и даже, вероятно — все время немного экспериментировать, стараясь расти и меняться к лучшему. Категорически важно только то, что ваши стили должны быть действительно всегда четко и понятно организованы.

На практике во многих командах «вытесняют» и игнорируют выгоду от более продвинутых и аккуратных подходов к разметке. Ведь это требует определенных затрат на коммуникацию. Например, очень часто файлы стилей даже на препроцессоре — тупо и незамысловато «складируются в кучу» и практически никак не связаны друг-с-другом. Признайтесь себе наконец честно: даже аккуратная подробная компонентность, хоть и позволяет решить проблему на самом примитивном физическом уровне, она вообще не решает ее глобально, на уровне абстракций. Наоборот — компонентность даже еще несколько затрудняет решение, так как строится именно на противоположных глобальности препроцессора, изолирующих подходах. Ваша куча это по прежнему невыразительная невнятная неповоротливая куча, просто теперь она еще и разделена на множество подобных и глобально излишних куч, поменьше.

Но давайте уже организуем препроцессор, если с SCSS:

.
└─ src
   └─ sscs
      ├─ core // обшие и компилируемые сущности препроцессора
      │  ├─ _animations.scss // keyframes
      │  ├─ _base.scss // минимальная нормализация основных HTML-элементов
      │  ├─ _grid.scss // сетки
      │  ├─ _typography.scss // типографика
      │  └─ _utilities.scss // быстрые удобные классы-утилиты для включения прямо в разметку
      ├─ libraries // папка с файлами стилизаций сторонних модулей
      │  └─ _modal.scss - например какая-нибудь готовая модаль
      ├─ project // стили конкретного проекта
      │  ├─ _elements.scss // отдельные простые элементы-компоненты
      │  ├─ _fixes.scss // этот файл всегда должен быть практически пустой, и предназначен только для редких общеизвестных "собственных проблем браузеров"
      │  ├─ _layout.scss - стили общей для всех страниц GUI-обертки над контентом интерфейса
      │  └─ _widgets.scss - сложные составные комбинации простых элементов-компонентов
      ├─ utils // обшие и некомпилируемые основные сущности препроцессора
      │  ├─ _functions.scss // на практике нужны крайне редко
      │  ├─ _mixins.scss // параметризируемые и способные принимать контент примеси-микстуры
      │  ├─ _placeholders.scss // повторяющиеся наборы правил - растворы
      │  └─ _variables.scss // самый важный файл с переменными )
      ├─ _main.scss // точка сборки всех стилей препроцессора
      └─ _stylebase.scss // стилевая база

То есть, на самом деле — порядок сборки всей кухни имеет значение, конечно же:

// В @/src/scss/_stylebase.scss:
// Stylebase
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////

// Uncompiled kitchen
@import "./utils/_functions";
@import "./utils/_variables";
@import "./utils/_mixins";
@import "./utils/_placeholders";

// Core base normal style and common utils
@import "./core/_animations";
@import "./core/_typography";
@import "./core/_base";
@import "./core/_grid";
@import "./core/_utilities";

// В @/src/scss/_main.scss:
// Project styles
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////

// Stylebase for components
@import "_stylebase";

// App styles
@import "./project/_fixes";
@import "./project/_elements";
@import "./project/_widgets";
@import "./project/_layout";

/* External libraries customization */
@import "./libraries/_modal";

Итак, «стилевой базой» мы будем называть некое основное ядро стилей, доступный всем остальным компонентам системы общий код препроцессора. Более детально, он состоит из условно двух разных видов файлов:

  1. Растворяемые при компиляции инструменты-помощники, сущности позволяющие генерировать лаконичный, оптимальный, связный код:

    1. функции
    2. переменные
    3. параметризуемые примеси
    4. включения-плейсхолдеры

  2. Компилируемые глобальные стили:

    1. анимации keyframes
    2. типографика
    3. базовая нормализация основных HTML-элементов
    4. сетки
    5. утилитарные классы-помощники для разметки

В папки @/src/scss/project и @/src/scss/libraries вы можете добавлять файлы по необходимости.

Удобно держать подобную минимальную «кухню» наготове в ваших стартовых проектах, чтобы с самого начала работы быстро настраивать стилизацию под конкретные требования и гайдлайн.

У меня вот, например, можно посмотреть — есть различные такие заготовки-«болванки» для быстрого старта на разных комбинациях актуальных технологий:

  • React c TypeScript и Stylus;
  • Vue c SCSS;
  • Webpack c SCSS и Nunjucks.

Читать книжку дальше можно пройдя по ссылке: Как верстать веб-интерфейсы быстро, качественно и интересно.

Часто бывает, что для анализа данных необходимо многократно выполнять одни и те же действия над исходными данными.

Для примера возьмем задачу, которую решала наша команда по анализу документов различных форматов таких как docx, xlsx, pptx, jpeg, pdf и др. Для удобства последующей обработки данных было решено создать веб-приложение с понятным для пользователя интерфейсом и зашитым внутри кодом. Код Python для обработки документов был готов, и мы не будем на нем останавливаться, а расскажем о том, как решали задачу красиво его «упаковать» в небольшую программу с понятным интерфейсом. Для этого мы использовали инструмент Flask. Это микро-фреймворк со всеми средствами и библиотеками, необходимыми для создания веб-приложения на основе языка Python, его цель – решение базовых задач без излишней нагрузки на сервер. Еще одним преимуществом является то что на его изучение не потребуется много времени.

Установим Flask:

pip install flask

Создадим основной файл с именем app.py в корневом каталоге рабочей папки и пропишем базовый код для приложения:

# импортируем Flask
from flask import Flask
# создаем приложение
app = Flask(__name__)

Посредством файла app.py мы получили возможность доступа ко множеству функций библиотеки Flask, в т.ч. для отслеживания URL-адреса страницы. Для этого используется маршрутизация:

# для отслеживания URL-адреса главной страницы:
@app.route(‘/’)
def index():
return render_template(‘index.html’)

При переходе на главную страницу приложение будет отображать файл index.html – необходимо создать его в каталоге templates. Но сначала создадим шаблон base.html, из которого будем наследовать настройки страниц нашего приложения. В своем примере я пропишу базовую структуру без ввода дополнительных настроек:

<!doctype html>
<html lang=»ru»>
<head>
<meta charset=»UTF-8″>
<meta name=»viewport»
content=»width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0″>
<meta http-equiv=»X-UA-Compatible» content=»ie=edge»>
<link rel=»stylesheet» href=»./static/css/main.css»>
<title>Приложение для обработки документов</title>
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

Вернемся к файлу главной страницы index.html. В этом и последующих файлах мы не будем прописывать структуру и настройки, а обратимся за настройками к файлу base.html. В файле index.html пропишу кратко инструкцию по работе приложения, а также кнопки, с помощью которых будут загружаться документы, запускаться модуль их обработки и выгружаться результаты.

# так настройки из файла base.html перенесутся в этот файл
{% extends ‘base.html’ %}

{% block body %}

<div class=»title»>
<h1>Приложение для обработки документов</h1>
</div>
<h3 align=»center»>Инструкция</h3>
<div align=»center»>
<table id=»instruction»>
<tr id=»row»>
<td>Краткая инструкция по использованию приложения состоит из 3 шагов:</td> </tr>
<tr id=»row»>
<td>1 шаг. Загрузить материалы. Добавить документы в открывшуюся папку.</td> </tr>
<tr id=»row»>
<td>2 шаг. Запуск модуля. Обработка документов.</td> </tr>
<tr id=»row»>
<td>3 шаг. Итог. Выгрузка результатов отработки модуля.</td> </tr>
</table>
</div>
<div align=»center»>
<p><a class=»btn» href=»/upload» target=»_blank»>Загрузить материалы</a></p>
<p><a class=»btn» href=»/start»>Запуск</a></p>
<p><a class=»btn» href=»/output_data»>Итог</a></p>

</div>

{% endblock %}

Мы получили главную страницу веб-приложения, которая выглядит так:

Пропишем шаблоны страниц, которые будут отображаться при нажатии кнопок с главной страницы:

Кнопка «Запуск», файл start.html

{% extends ‘base.html’ %}
{% block body %}
<h2 align=»center»>Обработка завершена. Посмотреть
<a href=»/output_data»>результаты.</a></h2>
{% endblock %}

Кнопка «Итог», файл output_data.html

{% extends ‘base.html’ %}
{% block body %}
<h1>Общая статистика</h1>
<h2><a href=»/index»>На главную</a></h2>
<h1>Проанализировано <b>{{count}}</b> документов.</h1>

<br>
<h3><a href=»#»>Вверх</a></h3>
<br>
{% endblock %}

Теперь вернемся к файлу app.py:

from flask import Flask, render_template, Response, request, render_template_string
app = Flask(__name__)

# главная страница
@app.route(‘/’)
@app.route(‘/index’)
def index():
return render_template(«index.html»)

# запуск обработки документов
@app.route(‘/start’)
def start():
if # здесь ваш код обработки документов
return render_template(«start.html»,
start_data=’Обработка завершена. Посмотреть
<a href=»/output_data»>результаты.</a>’)
# условие, если файлы не загружены:
else:
return render_template_string(‘<h2 align=»center»>Не загружены файлы для обработки. Вернитеcь на <a href=»/index»>главную страницу.</a></h2>’)

# вывод результатов
@app.route(‘/output_data’)
def output():
if # здесь ваш код вывода результатов
else:
# условие, если запуск не был произведен, и пользователь пытается попасть на # страницу с результатами:
return render_template_string(‘<h2 align=»center»>Для начала надо нажать на «Запуск». Вернитеcь на <a href=»/index»>главную страницу.</a></h2>’)

# запуск Flask-приложения:
if __name__ == «__main__»:
app.run(debug=False)

Таким образом, мы познакомились с простым инструментом по созданию веб-приложений. Данный инструмент может быть интересен ИТ-специалистам, в чьи обязанности входят частые запросы коллег на выгрузку и обработку однотипных данных. Flask позволит создать красивую и понятную пользователю «упаковку» для ваших алгоритмов и кода.

Компьютерные и пиксельные коды (пиксели) являются основой экономики 21 века. Если вы когда-либо видели в своем браузере «Исходный код страницы» или «Инструменты разработчика», вы можете столкнуться с множеством смешанных документов. Прокатился и задумался, как заставить сайт работать.

Веб-разработчики называют графический интерфейс пользователя (GUI) внешним интерфейсом веб-страницы, в противном случае — внутренним интерфейсом. Пользовательский интерфейс или интерфейс — это то, чем пользователи могут манипулировать, выполнять действия и использовать. Серверную часть можно рассматривать как инфраструктуру, которая содержит и поддерживает всю информацию и задачи из интерфейса.

  1. Как отличить Front-End, Back-End и Full Stack?

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

Хотите создать веб-интерфейс, с чего начать?

  1. Веб-дизайн и Front-end разработка
    1. Языки маркировки, стиля и программирования в интерфейсе
  2. HTML
    1. Причина, по которой вам это нужно
    2. Структура HTML-элемента
    3. Передовой
  3. CSS
    1. Причина, по которой вам это нужно
    2. Структура правила CSS
    3. Передовой
  4. JavaScript
    1. Причина, по которой вам это нужно
    2. Популярные фреймворки
    3. Передовой
  5. С чего начать учиться?
    1. Начинать
    2. Резюме
    3. Рекомендации

Веб-дизайн и Front-end разработка

В крупных организациях проектирование и разработка — это задачи, выполняемые группами экспертов с самыми разными навыками. Дизайнер создаст конкретный визуальный и интерактивный дизайн; затем фронтенд-разработчики будут его реализовывать.

Однако для человека нет причин ограничивать самопознание. То, что вы заботитесь о развитии, не означает, что у вас нет видения дизайна, и наоборот. Скромный объем знаний об основных веб-технологиях или принципах дизайна может стать сильной стороной вашей карьеры или бизнеса.

Front-end разработка — это более или менее программирование. Потому что это более половины работы, связанной с дизайном, многие концепции взяты из области полиграфического производства. Между тем, он также использует компьютерный код, но не является сложным и требует больших знаний программирования в дополнение к языкам веб-программирования (многие языки можно найти в серверной части).

Языки маркировки, стиля и программирования в интерфейсе

Большинство веб-сайтов построено с помощью набора из трех технологий: язык гипертекстовой разметки — язык гипертекстовой разметки (HTML), каскадные таблицы стилей — язык каскадных стилей (CSS) и JavaScript (JS):

  1. Языки маркировки, такие как HTML, помечают документы тегами (тегами). Тег, разграничивающий семантическое содержание и структуру документа. Структурированные документы можно стилизовать.
  2. CSS — это язык стилей или ориентация стиля отображения для редактора страницы. На веб-странице CSS предлагает команды, которые представляют контент, такой как типографика и макет в целом, а также размещение графики.
  3. JavaScript, в отличие от двух предыдущих объектов, является языком программирования. JS обрабатывает взаимодействие с пользователем и ввод данных и фокусируется на событиях, создаваемых пользователями.

HTML

Прошло более двадцати лет, и основная цель HTML остается прежней: отделить текст для читателя от структуры, необходимой для синтаксического анализа документа.

Причина, по которой вам это нужно

Почему HTML по-прежнему важен? Проще говоря, HTML — это место, которое содержит семантическое значение контента. Это необходимо для машинного чтения, таких как сканеры поисковых систем и программы чтения с экрана (чтобы быть доступными). Со временем актуальность разделения семантики и структуры выросла. В последней версии HTML5 появились такие теги, как ,,

, и с целью прояснения семантики и структуры. Это приносит пользу как машинным, так и человеческим читателям.

Структура HTML-элемента

Элементы HTML, как минимум, представляют собой пары открытых и закрытых тегов, каждая из которых заключена в квадратные скобки, например тег нижнего абзаца голубым цветом. Элементы, которым могут быть присвоены следующие ярко-красные атрибуты, такие как «класс», сделают этот элемент членом группы, на которую могут влиять HTML и JS. Свойства стиля с содержимым, написанным ниже красным цветом, на самом деле являются способом создания правил CSS для этого элемента. (CSS лучше всего писать на уровне сайта или страницы, об этом будет сказано ниже.)

Изображение 1 из Хотите создать веб-интерфейс, с чего начать?

Передовой

Разработчики одержимы производительностью. Для достижения этой цели они оптимизируют язык для ускорения записи и создания читаемых строк. Это называется синтаксическим приукрашиванием (специальный синтаксис).

Зачем сосредотачиваться на разработчиках, если вы, наверное, только новичок? Упростив все на языке разметки, вы можете сосредоточиться на намерении, а не на выражении, при проверке на основе окончательного стандарта. Исходные файлы, которые вы создаете на упрощенном языке разметки, будут переведены в допустимый HTML, или компилятор выдаст ошибки в некоторых конкретных строках. Вы можете видеть, что существует больше рекомендаций по исправлению ошибок, чем просто поиск недостающих элементов. Им требуется промежуточное программное обеспечение для преобразования их в HTML.

  1. Haml (язык разметки абстракций HTML): для компиляции требуется Ruby.
  2. Jade: для компиляции требуется Node.js.
  3. Slim: попросите Ruby скомпилировать.

CSS

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

Причина, по которой вам это нужно

Неформатированные сайты выглядят ужасно и непривлекательно. Несмотря на то, что они по-прежнему читабельны, CSS является основой децентрализованной визуальной информации из-за макета, который он позволяет. Например, на рисунке ниже показано текущее верхнее меню навигации веб-сайта makeuseof.com без применения CSS.

Изображение 2 из Хотите создать веб-интерфейс, с чего начать?

Обратите внимание, что в дополнение к шрифту и цвету меню не имеет стиля для размещения по вертикали — это стиль браузера по умолчанию. Конечно, вы не хотите возвращаться к Интернет-интерфейсу 1990 года, поэтому вам понадобятся некоторые знания CSS, чтобы что-то изменить. Кроме того, с увеличением количества подключенных устройств различного размера, таких как iPhone, планшеты и т. Д., Одним из наиболее важных навыков является создание адаптивного дизайна или веб-сайтов. с разными размерами экрана. Это делается через CSS.

Структура правила CSS

Правила CSS написаны в одном из трех мест:

а) Встроенный элемент.

б) Создавая разделы

Во время предыдущей лабораторной работы мы завершили разработку основной логики приложения. Приложение отлично справляется со своей задачей — находит страны на основе предпочтений пользователя. Однако, пользоваться им врядли кто-либо захочем. У этого приложения очень неудобный для обозначенных целей интерфейс. Во время этой лабораторной работы мы поговорим про интерфейсы, которые составляют фронтенд часть приложения.

Слейте в свою ветку изменения из новой ветки lab-6. Как это сделать можно подглядеть в шпаргалке или загуглить.

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

  • веб приложение (сайт в браузере)

  • мобильное приложение

  • консольное приложение

  • приложение для приставки

  • приложение для TV

Какой интерфейс лучше? Ответить на этот вопрос невозможно. Разные интерфейсы используются для работы с различными приложениями в зависимости от требований, находя баланс между удобством, эффективностью, затратами на производство и другими характеристиками. Также, для использования различных визуальных интерфейсов применяются различные аппаратные интерфейсы:

  • мышь и клавиатура для работы с веб-приложением

  • смартфон для работы с мобильными приложениями

  • джойстик для работы с приложением для приставки

  • пульт для работы с приложением для TV

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

  • Git — изначально консольный интерфейс, для которого также существуют дополнительно написанные интерфейсы — приложения для рабочего стола

  • ВКонтакте — веб-приложение, мобильное приложение, приложение для рабочего стола

  • Netflix — веб-приложение, мобильное приложение, приложение для TV, приложение для приставки, приложение для рабочего стола

Как видите, часто приложения имеют несколько разных интерфейсов для работы с ними. Каждый из них приходится разрабатывать отдельно, хотя на данный момент активно развивается движение прогрессивного веба. Главная причина появления этого движения — вселенская лень. Среди причин также: экономия денег и времени. Идея заключается в том, что необходимо разработать одно веб-приложение для работы в браузере, которое будет принимать разные формы в зависимости от размера экрана, а браузер будет запущен на TV, смартфоне или приставке. Будем надеяться, что это станет распространено достаточно быстро.

Но даже сейчас веб-приложения — наиболее распространенный интерфейс. А значит и вакансий в сфере веб разработки наибольшее количество. Познакомимся с веб-приложениями поближе. Начнем разработку интерфейса для использования рекомендателя стран в браузере.

Требования к интерфейсу веб-приложения

Как мы уже знаем, разработка начинается с требований. В случае разработки интерфейсов — требования представлены в визуальном виде, как правило от дизайнера. У нас, к сожалению, нет возможности нанять профессионального дизайнера, поэтому придется верстать ЭТО. Не самый привлекательный дизайн для нашей программы, но этого достаточно для того чтобы познакомиться с разработкой интерфейсов.

Требования оформляются в профессиональных дизайнерских инструментах, например, Adobe Illustrator, Adobe XD или Sketch. Раньше подобные приложения имели только приложения для рабочего стола, но тенденция перехода на веб-приложения дошла и до них. В нашем случае требования разработаны при помощи Figma. Figma — это онлайн-сервис для разработки интерфейсов и прототипирования.

Помимо основной функции приложения — разработки дизайна интерфейсов, приложение дает возможность работать совместно с другими людьми над одним проектом. Это одно из больших преимуществ веб-приложений — совместная работа нескольких пользователей над одним проектом/документом/слайдами становится очень распространенной функцией. Google делает большие успехи в создании целого набора приложений для офиса с поддержкой совестной работы — презентации, документы, таблицы и формы. Кстати, каждая из этих программ хранит историю изменений каждого файла, а также информацию об авторах и указывает, что именно было изменено. И конечно, для этого они используют систему контроля версий, очень возможно что git.

Рекомендуется дать шанс этим приложениям. Можно попробовать составлять презентации в группах, совместно готовить ответы на вопросы к экзамену или вместе писать конспекты лекций.

Экспресс-экскурсия по ASP.NET Core MVC

После сливания изменений из ветки lab-6 в папке bukep-software-engineering появилась новая папка с решением CountriesRecommendationWebApp. Откройте эту папку в VS Code. Мы видим знакомую ранее структуру — 3 папки с проектами Helpers, Helpers.Texts и новый проект CountriesRecommendationWebApp. Откройте папку этого нового проекта. Перед вами типичная структура приложения ASP.NET Core MVC. Этот «шаблон» из папок и файлов подготовлен Microsoft для облегчения жизни разработчикам. Вы всегда можете создать приложение с шаблоном при помощи команды dotnet new webapp.

Кратко рассмотрим папки в проекте. Открывайте папки и смотрите файлы, чтобы сопоставить увиденное с описанием.

  • Controllers — в папке располагаются контроллеры — специальные классы, методы которых связываются с интерфейсом и могут отправлять туда данные или получать данные из интерфейса. В консольном приложении мы писали код для связи интерфейса и нашей программы в классе Program и использовали методы чтения с консоли и вывода в консоль. В ASP.NET Core MVC приложении подобный код пишется в методах классов-контроллеров

  • Enums — папка не создается по-умолчанию, но часто встречается в различных проектах. В эту папку помещают файлы с перечислениями (enum), в нашем случае там расположен enum CountrySize

  • Models — в папке располагаются модели — классы с логикой приложения: UserPreferences и Country уже находятся там

  • Properties — в папку «свойства» положили файл launchSettings.json — настройки запуска приложения. Заметьте, опять формат json

  • Views — папка «представления» содержит файлы интерфейса приложения, а точнее — его HTML разметки. Скоро мы увидим что это такое на примере, а затем познакомимся с теорией на лекции

  • wwwroot — в папке «www корень» располагаются «статические» файлы — файлы стилей CSS, картинки, код javascript. Эти файлы загружаются в браузер пользователю для работы приложения

  • appsettings.json и appsettings.Development.json — настройки приложения. И снова в формате json

  • CountriesRecommendationWebApp.csproj — уже известный нам файл проекта. В нем уже есть строка подключения проекта Helpers, вам не придется снова это делать

  • Program.cs — класс, в котором инициализируется и запускается приложение

  • Startup.cs — класс, с которого начинается запуск приложения. Входная точка приложения с настройками

Экскурсия окончена! Теперь пишем код! Не переживайте если не все понятно (или все не понятно), на этой лабораторной работе мы просто «щупаем» приложение вслепую. Теория последует на лекции.

Разработка разметки на HTML

  1. В папке Views/Home Создайте файл CountryInfo.cshtml. Расширение cshtml происходит от cs (с sharp) и html (hypertext markup language — язык гипертекстовой разметки). Это все потому, что мы сможем писать в этом файле и HTML и C# код

  2. Добавьте «шапку» страницы, то есть ее верхнюю часть. У нас там логотип и название приложения «Рекомендатель стран». Для этого нам понадобится следующий код:

<img src=«~/images/logo.png«>

<h1>Рекомендатель стран</h1>

Что это такое? Все это — теги. Ведь HTML — теговый язык разметки документов. Каждый документ — это набор тегов, который описывает структуру (разметку) страницы.

  • img — тег image (картинка) для встраивания картинок в приложение. Внутрь картинки ничего поместить нельзя, поэтому тег img— одиночный (у него нет закрывающего тега). У тега img также есть один важный атрибут — src (source — источник). В значении атрибута необходимо указать путь к картинке. В нашем случае файл с логотипом logo.png располагается в папке wwwroot/images. Вместо полного пути к файлу можно указать ~/images/, где ~ обозначает корневую папку, в нашем случае — папка wwwroot. src — не единственный атрибут, все теги имеют различные атрибуты

  • h1 — заголовок (header) первого уровня, то есть самый большой и главный заголовок. Есть еще h2, h3, h4, h5, h6, каждый меньше предыдущего. Тег парный, то есть у него есть и открывающийся <h1> и закрывающийся </h1> теги, а внутри можно помещать текст

Запустим наше приложение. Вы можете сделать это в разделе запуска приложения VS Code, как было показано ранее. Оно запускается на локальном хосте, то есть ваш компьютер — и есть сервер приложения на котором оно работает. Для удобства за вас уже установили веб-сервер вместе с dotnet SDK.

Ваш браузер — это клиент, который может пользоваться этим приложением благодаря серверу. По умолчанию ASP.NET Core MVC приложение запускается на порте 5000. Чтобы открыть нашу новую страничку, необходимо в браузере в адресную строку ввести https://localhost:5001/Home/CountryInfo. Попробуем. Изменений не видно…

Для того, чтобы все заработало необходимо добавить новый метод в класс HomeController в папке Controllers. После метода Index() добавьте следующий код:

public IActionResult CountryInfo()

{

return View();

}

Но в браузере все еще ничего не изменилось. Все дело в том, что приложение на C# — компилируемое. А значит, после внесения изменений, каждый раз необходимо перекомпилировать всё приложение и запускать его заново. Избежать этого невозможно, разве что выбрать другой язык программирования. Но компилируемые языки дают слишком много плюсов, чтобы вот так просто от них отказаться.

Хотя избавиться от необходимости перекомпилировать приложение каждый раз после внесения изменений не получится — можно эту задачу автоматизировать! И, конечно, мы не первые кто об этом задумался. У программы dotnet уже есть такая команда.

3. В терминале перейдите в папку bukep-software-engineering/CountriesRecommendationWebApp/CountriesRecommendationWebApp и введите:

dotnet watch run

Эта команда запустила приложение в особом режиме watch. Теперь каждый раз после изменения и сохранения файла в терминале вы увидите это

watch : Exited

watch : File changed: /home/vitalii/Documents/Repos/bukep-software-engineering/CountriesRecommendationWebApp/CountriesRecommendationWebApp/Controllers/HomeController.cs

watch : Started

Происходит очень простая вещь — инструмент watch отслеживает, какие файлы были изменены, останавливает приложение, компилирует его заново и запускает измененное приложение. Если же вы измените статические файлы (файлы стилей или картинки), то рекомпиляции не понадобится.

Запустили приложение — видим результат! Однако расположения логотипа и названия приложения не соответствуют макету. В макете название идет сразу за логотипом в одну строку, а здесь каждый блок занял свою строку. Наша главная задача при написании html — задать верную структуру расположения элементов. Объединим их в одну строку при помощи еще одного тега.

Для объединения тегов в одну строку первым делом необходимо добавить «внешний» тег, в котором будут располагаться эти теги. В нашем случае отлично подойдет тег header.

  • header — специальный тег для обозначения шапки приложения, где часто расположены логотип и название. Как раз то, что нам нужно. Тег «парный», то есть у него есть и открывающийся <header> и закрывающийся </header> теги, а внутри располагаются другие элементы

4. Обернем логотип и название тегом header следующим образом:

<header>

@* теги для логотипа и названия *@

</header>

Вложенные теги всегда отделяются отступами, как блоки в С# коде. Кстати, при помощи @* комментарий *@ можно писать комментарии в файлах cshtml. Почти как в С#: /* комментарий */.

Пока что ничего не изменилось. теги все еще занимают отдельную строку. Для того, чтобы это исправить, можно добавить специальный класс тегу header. Класс — это специальный атрибут любого тега, который помогает в коде находить элемент или набор элементов, например, для добавления стилей. Подробнее про классы поговорим на лекции. А пока замените строку <header> на:

<header class=«row«>

Класс row (строка) — это класс библиотеки стилей boostrap. Опять же — библиотека, только на этот раз не только с кодом, но и с файлами стилей для внешнего вида страницы и описания правил расположения элементов на этой странице. Часто встречаемая задача — поставить элементы в одну строку решена за нас, а мы просто используем готовый код других разработчиков. Класс!

Добавим остальной контент страницы. Нам нужно добавить название страны (это будет заголовок раздела о стране) и информацию об этой стране в виде списка фактов.

5. После закрывающегося тега header добавьте заголовок второго уровня, и впишите туда текст — Индия

<h2>Индия</h2>

6. Добавьте список. Списки обозначаются тегами ul или ol в зависимости от того, нужен ли нам ненумерованный список (unordered list) или нумерованный список (ordered list). В нашем случае подойдет ненумерованный список. После тега заголовка добавьте парный тег ul

<ul>

@* Здесь будут расположены элементы списка *@

</ul>

7. В список добавьте два элемента списка (list item) при помощи тега li

<ul>

<li></li>

<li></li>

</ul>

8. В каждом элементе списка будет располагаться текст. Текст добавляется при помощи тега p от слова paragraph (параграф). В каждом параграфе сразу добавьте текст с информацией о стране

<ul class=«list«>

<li>

<p>Население: 1380230000</p>

</li>

<li>

<p>Средняя зарплата: 88 $</p>

</li>

</ul>

На странице уже появилась базовая структура, но это все еще далеко от заданных в макете требований. На этой лабораторной работе ограничимся тем, что выровняем блок с информацией о стране посередине страницы и уберем стили для списка по-умолчанию. (кружочки слева).

Для выравнивания блока при помощи bootstrap первым делом необходимо объединить информацию в один блок, как мы это сделали с логотипом и названием приложения.

9. Заключите заголовок с названием страны и список с информацией о стране в тег <section> (секция). Часто контент сайта можно условно разделить на секции, это популярный тег который помогает удобно организовывать блоки верхнего уровня на странице. Тег парный, а значит имеет закрывающийся тег. Вам необходимо организовать разметку таким образом, что заголовок и список будут вложены в этот блок, то есть будут находится между открывающим и закрывающим тегами.

Центрирование при помощи bootstrap предстоит сделать в 3 этапа — задать размер блока, центрировать его посередине страницы, выровнять текст внутри блока посередине.

10. Сперва определим какую часть страницы будет занимать информация о стране. Судя по макету это примерно 1/4 часть страницы. В bootstrap для разметки используют не только строки (класс row), но и колонки (класс col), часто с различными значениями (col-1, col-2, col-3col-12). В итоге получается сетка из сток и колонок внутри этих строк. Страница в bootstrap разделена на 12 колонок. Каждую из них также можно разбить на 12 колонок и так далее. Такое количество выбрали, потому что 12 нацело делится на 6, 4, 3 и 2, что очень удобно и позволяет легко покрыть большинство требований верстки. Определим для этого блока 3 колонки при помощи класса col-3

<section class=«col-3«>

Ничего не изменилось? Да нет, в этот раз изменения есть, просто пока что они не видны. Есть способ проверить, что изменение вступило в силу. Разработчики интерфейсов для браузера постоянно пользуются инструментами разработки, встроенными в браузер. Открыть панель разработчика можно при помощи горячей клавиши F12 в Google Chrome. В других браузерах это может различаться, загляните в туториал, чтобы узнать, как открыть панель инструментов, если вы пользуетесь другим браузером.

11. Откройте вкладку Elements и наведите мышью на ново созданную секцию с классом col-3. Вы увидите, что сам блок занимает примерно 1/4 страницы (3 колонки из 12).

Как сделать чтобы этот блок выровнялся по-середине? У bootstrap есть еще один специальный класс — mx-auto.

12. Добавим класс mx-auto через пробел в том же атрибуте class тега section.

<section class=«col-3 mx-auto«>

13. Отлично! Тег section выровнялся по центру страницы! Но вот текст внутри блока — еще нет. Думаете, у bootstrap есть класс для этого? Конечно, text-center — то, что нам нужно. Добавьте его к остальным классам тега section.

Теперь мы расположили элементы так, как нам нужно. Осталось убрать стили по-умолчанию, заданные списку браузером — кружочки слева от элементов списка. Для этого нам потребуется создать свой кастомный (определенный нами) класс, потому что у bootstrap нет именно того, что нам нужно.

14. Добавьте класс list к элементу ul

15. Добавьте селектор по классу list в файл wwwroot/css/site.css следующим образом:

.list {

list-style: none;

padding-left: 0;

}

Что такое и какие бывают селекторы мы подробнее узнаем на лекции. Внутри селектора указываются стили, которые необходимо применить ко всем элементам, удовлетворяющим этому селектору. В нашем случае — всем элементам с классом list. Свойства стилей, которые мы изменяем:

  • list-style (стиль листа) со значением none (никакой). По умолчанию назначено значение disc, в таком случае каждый элемент списка обозначен закрашеным кружочком. Значение circle добавляет не закрашенные кружочки. Попробуйте поменять значение этого свойства и увидите, как изменяется список. Кстати, заметьте, что при изменении стилей рекомпиляция приложения не нужна, ведь css не нужно компилировать, мы просто загружаем его в браузер и уже браузер считывает и применяет указанные значения.

  • padding-left (внутренний отступ слева) со значением 0. Свойство обнуляет расстояние слева от элементов списка. По умолчанию, список отступает на 40 пикселей, чтобы вместить кружочки. Попробуйте поменять значения и увидите, что меняется. Воспользуйтесь панелью инструментов разработчика в браузере, чтобы отследить изменения. Разлинчые отступы в css — отдельная тема, которую мы кратко рассмотрим на лекции.

Лабораторная работа выполнена! Не забудьте залить новые изменения в удаленный репозиторий.

На лабораторной работе мы прикоснулись к веб-приложению и начали разрабатывать его интерфейс.

  • узнали что такое интерфейс и какие бывают интерфейсы

  • познакомились с требованиями к интерфейсу приложения Рекомендатель стран

  • прошлись по папкам веб-приложения ASP.NET Core MVC, узнали об их назначении

  • научились запускать приложение в режими watch с автоматической рекпомпиляцией

  • познакомились с тегами HTML, написали шапку нашего приложения и добавили список с информацией о странах. Для этого мы воспользовались тегами:

    • header — специальная секция страницы «шапка»

    • section — секция страницы общего назначения для логического разбиения страницы на части

    • h1, h2 — заголовки (header) первого и второго уровней

    • img — тег для добавления картинки (image) на страницу с аттрибутом src, в котором указывается путь к картинке

    • ul — тег для добавления неупорядоченных списков (unordered list)

    • li — тег для добавления элементов списка (list item) в список

    • p — тег для добавления параграфов (paragraph) с текстом

  • воспользовались классами библиотеки для разработки веб-интерфейсов bootstrap

    • row и col для организации элементов в сетку из строк и колонок

    • mx-auto для выравнивания блока по-середине страницы

    • text-center для выравнивания текста по-середине

  • добавили стили касмомному (добавленному самостоятельно) классу list для обнуления стилей для списков по-умолчанию

    • list-style со значением none, чтобы убрать крожочки вначале списка

    • padding-left со значением 0, чтобы убрать отступ текста списка слева, который по-умолчанию выделен для кружочков

  • в очередной раз убедились в необходимости изучения английского для программирования

На сегодняшний день в мире разработки на Java существует огромное количество библиотек и технологий, в которых новичку очень легко запутаться. В этом руководстве я постараюсь простым языком описать все шаги, возникающие проблемы и пути их решения. Начинать будем с самого простого и постепенно наращивать функциональность.

Spring Boot

Spring Boot — один из самых популярных универсальных фреймворков для построения веб-приложений на Java. Создадим в среде разработки Gradle Project. Для облегчения работы воспользуемся сайтом https://start.spring.io, который поможет сформировать build.gradle.

Для начала нам необходимо выбрать следующие зависимости:

  • Spring Web — необходим для создания веб-приложения;
  • Spring Data JPA — для работы с базами данных;
  • PostgreSQL Driver — драйвер для работы с PostgreSQL;
  • Lombok — библиотека, позволяющая уменьшить количество повторяющегося кода.

В результате генерации build.gradle должно получиться что-то похожее:

plugins {
    id 'org.springframework.boot' version '2.4.3'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group 'org.example'
version '1.0-SNAPSHOT'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok:1.18.22'
    annotationProcessor 'org.projectlombok:lombok:1.18.22'
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    runtimeOnly 'org.postgresql:postgresql'
}

test {
    useJUnitPlatform()
}

Тот же результат можно получить и в самой IntelliJ Idea: File → New → Project → Spring Initializr.

Объявим Main-класс:

@SpringBootApplication
public class SpringDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDemoApplication.class, args);
    }
}

Опишем самый простой контроллер, чтобы удостовериться, что проект работает:

@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(@RequestParam(required = false) String name) {
        return "Hello, " + name;
    }
}

Запустим проект в среде разработки или через терминал: ./gradlew bootRun.

Результат работы можно проверить в браузере перейдя по адресу http://localhost:8080/hello?name=World или с помощью консольной утилиты curl:

curl "http://localhost:8080/hello?name=World"
Hello, World

Наш сервис запускается и работает, пора переходить к следующему шагу.

Представим, что нам требуется разработать некий сервис для интернет-магазина по продаже книг. Это будет rest-сервис, который будет позволять добавлять, редактировать, получать описание книги. Хранить данные будем в БД Postgres.

Docker

Для хранения данных нам потребуется база данных. Проще всего запустить инстанс БД с помощью Docker. Docker позволяет запускать приложение в изолированной среде выполнения — контейнере. Поддерживается всеми операционными системами.

Выкачиваем образ БД и запускаем контейнер:

docker pull postgres:12-alpine

docker run -d -p 5432:5432 --name db 
    -e POSTGRES_USER=admin 
    -e POSTGRES_PASSWORD=password 
    -e POSTGRES_DB=demo 
    postgres:12-alpine

Lombok

Создадим data-класс «книга». Он будет иметь несколько полей, которые должны иметь getters, конструктор и должна быть неизменяемой (immutable). Среда разработки позволяет автоматически генерировать конструктор и методы доступа к полям, но чтобы уменьшить количество однотипного кода, будем использовать Lombok.

Аннотация @Value при компиляции исходного кода добавит в наш класс getters, конструктор, пометит все поля класса private final, добавит методы hashCode, equals и toString.

@Value
public class Book {
    Long id;
    String author;
    String title;
    Double price;
}

После сборки проекта можно посмотреть, как выглядит класс после компиляции. Воспользуемся стандартной утилитой, входящей в состав JDK:

javap -private build/classes/java/main/com/example/BookStore/model/Book

public final class com.example.bookstore.model.Book {
  private final java.lang.Long id;
  private final java.lang.String author;
  private final java.lang.String title;
  private final java.lang.Double price;
  public com.example.bookstore.model.Book(java.lang.Long, java.lang.String, java.lang.String, java.lang.Double);
  public java.lang.Long getId();
  public java.lang.String getAuthor();
  public java.lang.String getTitle();
  public java.lang.Double getPrice();
  public boolean equals(java.lang.Object);
  public int hashCode();
  public java.lang.String toString();
}

Lombok очень упрощает читаемость подобного рода классов и очень широко используется в современной разработке.

Spring Data JPA

Для работы с БД нам потребуется Spring Data JPA, который мы уже добавили в зависимости проекта. Дальше нам нужно описать классы Entity и Repository. Первый соответствует таблице в БД, второй необходим для загрузки и сохранения записей в эту таблицу.

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "books")
public class BookEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String author;

    private String title;

    private Double price;
}

Мы также используем аннотации Lombok: @Data добавляет getters и setters, @NoArgsConstructor и @AllArgsConstructor — конструкторы без параметров и со всеми параметрами, соответственно. @Entity, @Table, @Id, @GeneratedValue — аннотации относящиеся к JPA. Здесь мы указываем, что это объект БД, название таблицы, первичный ключ и стратегию его генерации (в нашем случае автоматическую).

Класс Repository будет выглядеть совсем просто — достаточно объявить интерфейс и наследоваться от CrudRepository:

public interface BookRepository extends CrudRepository<BookEntity, Long> {
    
}

Никакой реализации не требуется. Spring всё сделает за нас. В данном случае мы сразу получим функциональность CRUD — create, read, update, delete. Функционал можно наращивать — чуть позже мы это увидим. Мы описали DAO-слой.

Теперь нам нужен некий сервис, который будет иметь примерно следующий интерфейс:

public interface BookService {
    Book getBookById(Long id);// получить книгу по id
    List<Book> getAllBooks();// получить список всех книг
    void addBook(Book book);// добавить книгу
}

Это так называемый сервисный слой. Реализуем этот интерфейс:

@Service
@RequiredArgsConstructor
public class DefaultBookService implements BookService{
    private final BookRepository bookRepository;

    @Override
    public Book getBookById(Long id) {
        BookEntity bookEntity = bookRepository
                .findById(id)
                .orElseThrow(() -> new BookNotFoundException("Book not found: id = " + id));

        return new Book(bookEntity.getId(), 
                        bookEntity.getAuthor(), 
                        bookEntity.getTitle(), 
                        bookEntity.getPrice());
    }

    @Override
    public List<Book> getAllBooks() {
        Iterable<BookEntity> iterable = bookRepository.findAll();
        
        ArrayList<Book> books = new ArrayList<>();
        for (BookEntity bookEntity : iterable) {
            books.add(new Book(bookEntity.getId(), 
                               bookEntity.getAuthor(), 
                               bookEntity.getTitle(), 
                               bookEntity.getPrice()));
        }

        return books;
    }

    @Override
    public void addBook(Book book) {
        BookEntity bookEntity = new BookEntity(null, 
                                               book.getAuthor(), 
                                               book.getTitle(), 
                                               book.getPrice());
        bookRepository.save(bookEntity);
    }
}

Аннотацией @Service мы возлагаем на Spring создание объекта этого класса. @RequiredArgsConstructor — уже знакомая нам аннотация, которая генерирует конструктор с необходимыми аргументами. В нашем случае класс имеет final-поле bookRepository, которое необходимо проинициализировать. Добавив эту аннотацию, мы получим следующую реализацию:

public DefaultBookService(BookRepository bookRepository) {
    this.bookRepository = bookRepository;
}

При создании объекта класса Spring опять всё возьмёт на себя — сам создаст объект BookRepository и передаст его в конструктор. Имея объект репозитория мы можем выполнять операции с БД:

bookRepository.findById(id); //прочитать запись из БД по первичному ключу id
bookRepository.findAll(); //прочитать все записи из БД и вернуть их в виде списка
bookRepository.save(bookEntity); //сохранить объект в БД

Метод findById возвращает объект типа Optional<BookEntity>. Это такой специальный тип который может содержать, а может и не содержать значение. Альтернативный способ проверки на null, но позволяющий более изящно написать код. Метод orElseThrow извлекает значение из Optional, и, если оно отсутствует, бросает исключение, которое создается в переданном в качестве аргумента лямбда-выражении. То есть объект исключения будет создаваться только в случае отсутствия значения в Optional.

MapStruct

Смотря на код может показаться, что класс Book не нужен, и достаточно только BookEntity, но это не так. Book — это класс сервисного слоя, а BookEntity — DAO. В нашем простом случае они действительно повторяют друг друга, но бывают и более сложные случаи, когда сервисный слой оперирует с несколькими таблицами и соответственно DAO-объектами.

Если присмотреться, то и тут мы видим однотипный код, когда мы перекладываем данные из BookEntity в Book и обратно. Чтобы упростить себе жизнь и сделать код более читаемым, воспользуемся библиотекой MapStruct. Это mapper, который за нас будет выполнять перекладывание данных из одного объекта в другой и обратно. Для этого добавим зависимости в build.gradle:

dependencies {
    ...
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
}

Создадим mapper, для этого необходимо объявить интерфейс, в котором опишем методы для конвертации из BookEntity в Book и обратно:

@Mapper(componentModel = "spring")
public interface BookToEntityMapper {
    BookEntity bookToBookEntity(Book book);
    Book bookEntityToBook(BookEntity bookEntity);
}

Так как имена полей классов соотносятся один к одному, то интерфейс получился таким простым. Если поля имеют отличающиеся имена, то потребуется аннотацией @Mapping указать какие поля соответствуют друг другу. Более подробно можно найти в документации. Чтобы spring смог сам создавать бины этого класса, необходимо указать componentModel = "spring".

После сборки проекта, в каталоге build/generated/sources/annotationProcessor появится сгенерированный исходный код mapper, избавив нас от необходимости писать однотипные десятки строк кода:

@Component
public class BookToEntityMapperImpl implements BookToEntityMapper {

    @Override
    public BookEntity bookToBookEntity(Book book) {
        if ( book == null ) {
            return null;
        }

        BookEntity bookEntity = new BookEntity();

        bookEntity.setId( book.getId() );
        bookEntity.setAuthor( book.getAuthor() );
        bookEntity.setTitle( book.getTitle() );
        bookEntity.setPrice( book.getPrice() );

        return bookEntity;
    }

    @Override
    public Book bookEntityToBook(BookEntity bookEntity) {
        if ( bookEntity == null ) {
            return null;
        }

        Long id = null;
        String author = null;
        String title = null;
        Double price = null;

        id = bookEntity.getId();
        author = bookEntity.getAuthor();
        title = bookEntity.getTitle();
        price = bookEntity.getPrice();

        Book book = new Book( id, author, title, price );

        return book;
    }
}

Воспользуемся мэппером и перепишем DefaultBookService. Для этого нам достаточно добавить добавить final-поле BookMapper, которое Lombok автоматически подставит в аргумент конструктора, а spring сам инстанциирует и передаст параметром в него:

@Service
@RequiredArgsConstructor
public class DefaultBookService implements BookService{
    private final BookRepository bookRepository;
    private final BookToEntityMapper mapper;

    @Override
    public Book getBookById(Long id) {
        BookEntity bookEntity = bookRepository
                .findById(id)
                .orElseThrow(() -> new BookNotFoundException("Book not found: id = " + id));
        
        return mapper.bookEntityToBook(bookEntity);
    }

    @Override
    public List<Book> getAllBooks() {
        Iterable<BookEntity> iterable = bookRepository.findAll();
        ArrayList<Book> books = new ArrayList<>();
        for (BookEntity bookEntity : iterable) {
            books.add(mapper.bookEntityToBook(bookEntity));
        }

        return books;
    }

    @Override
    public void addBook(Book book) {
        BookEntity bookEntity = bookMapper.bookToBookEntity(book);
        mapper.save(bookEntity);
    }
    ...

Теперь опишем контроллер, который будет позволять выполнять http-запросы к нашему сервису. Для добавления книги нам потребуется описать класс запроса. Это data transfer object, который относится к своему слою DTO.

@Data
public class BookRequest {
    private String author;
    private String title;
    private Double price;
}

Нам также потребуется конвертировать объект AddBookRequest в объект Book. Создадим для этого BookToDtoMapper:

@Mapper(componentModel = "spring")
public interface BookToDtoMapper {
    Book AddBookRequestToBook(BookRequest bookRequest);
}

Теперь объявим контроллер, на эндпоинты которого будут приходить запросы на создание и получение книг, добавив зависимости BookService и BookToDtoMapper. При необходимости аналогично объекту AddBookRequest можно описать Response-объект, добавив соответствующий метод в мэппер, который будет конвертировать Book в GetBookResponse. Контроллер будет содержать 3 метода: методом POST мы будем добавлять книгу, методом GET получать список всех книг и книгу по идентификатору, который будем передавать в качестве PathVariable.

@RestController()
@RequestMapping("/books")
@RequiredArgsConstructor
public class BookController {

    private final BookService bookService;
    private final BookToDtoMapper mapper;

    @GetMapping("/{id}")
    public Book getBookById(@PathVariable Long id) {
        return bookService.getBookById(id);
    }

    @GetMapping
    public List<Book> getAllBooks() {
        return bookService.getAllBooks();
    }
    
    @PostMapping
    public void addBook(@RequestBody AddBookRequest request) {
        bookService.addBook(mapper.AddBookRequestToBook(request));
    }
}

Осталось создать файл настроек приложения. Для Spring boot по умолчанию это application.properties или application.yml. Мы будем использовать формат properties. Необходимо указать настройки для соединения с БД (выше мы задавали пользователя и его пароль при старте docker-контейнера):

spring.datasource.url=jdbc:postgresql://localhost:5432/demo
spring.datasource.username=admin
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

Настройка spring.jpa.hibernate.ddl-auto=update указывает hibernate необходимость обновить схему когда это нужно. Так как мы не создавали никаких схем, то приложение сделает это автоматически. В процессе промышленной разработки схемы баз данных постоянно меняются, и часто используются инструменты для версионирования и применения этих изменений, например Liquibase.

Запустим наше приложение и выполним запросы на добавление книг:

curl -X POST --location "http://localhost:8080/books" 
    -H "Content-Type: application/json" 
    -d "{
          "author" : "Joshua Bloch",
          "title" : "Effective Java",
          "price" : 54.99
        }"
        
curl -X POST --location "http://localhost:8080/books" 
    -H "Content-Type: application/json" 
    -d "{
          "author" : "Kathy Sierra",
          "title" : "Head First Java",
          "price" : 12.66
        }"
        
curl -X POST --location "http://localhost:8080/books" 
    -H "Content-Type: application/json" 
    -d "{
          "author" : "Benjamin J. Evans",
          "title" : "Java in a Nutshell: A Desktop Quick Reference",
          "price" : 28.14
        }"

После выполнения запросов в таблице books должны появиться записи. Чтобы удостовериться в этом, можно использовать любой удобный клиент БД. Для примера сделаем это, используя консольный клиент, входящий в состав docker-контейнера. При создании контейнера, мы указали его имя ‘db’ (если имя не задавалось, то можно вывести список всех запущенных контейнеров командой docker container ls, и дальше использовать идентификатор нужного контейнера). Для доступа к шелл-оболочке выполним:

docker exec -ti db sh

Запустим клиент БД и выполним sql-запрос:

psql --username=admin --dbname=demo
psql (12.6)
Type "help" for help.

demo=# SELECT * FROM books;
 id |      author       | price |                     title                     
----+-------------------+-------+-----------------------------------------------
  1 | Joshua Bloch      | 54.99 | Effective Java
  2 | Kathy Sierra      | 12.66 | Head First Java
  3 | Benjamin J. Evans | 28.14 | Java in a Nutshell: A Desktop Quick Reference
(3 rows)

Получим список всех книг:

curl -X GET --location "http://localhost:8080/books" 
    -H "Accept: application/json"

[
  {
    "id": 1,
    "author": "Joshua Bloch",
    "title": "Effective Java",
    "price": 54.99
  },
  {
    "id": 2,
    "author": "Kathy Sierra",
    "title": "Head First Java",
    "price": 12.66
  },
  {
    "id": 3,
    "author": "Benjamin J. Evans",
    "title": "Java in a Nutshell: A Desktop Quick Reference",
    "price": 28.14
  }
]

Получим книгу через запрос к api нашего сервиса, указав идентификатор книги:

curl -X GET --location "http://localhost:8080/books/2" 
    -H "Accept: application/json"

{
  "id": 2,
  "author": "Kathy Sierra",
  "title": "Head First Java",
  "price": 12.66
}

Добавим к нашему api более сложную функциональность — поиск по автору книги. Для этого в BookRepository нужно описать метод, который будет делать соответствующий SELECT из БД. Это можно сделать с помощью аннотации @Query, а можно назвать метод в соответствии со специальной нотацией Spring:

List<BookEntity> findAllByAuthorContaining(String author);

В документации можно подробнее прочитать об именовании методов. Здесь мы указываем findAll — найти все записи, ByAuthor — параметр обрамляется %. При вызове этого метода (например с аргументом ‘Bloch’) будет сгенерирован следующий запрос:

SELECT * FROM books WHERE author LIKE '%Bloch%';

Далее добавим метод в BookService и DefaultBookService:

@Override
public List<Book> findByAuthor(String author) {
    Iterable<BookEntity> iterable = bookRepository.findAllByAuthorContaining(author);
    ArrayList<Book> books = new ArrayList<>();
    for (BookEntity bookEntity : iterable) {
        books.add(mapper.bookEntityToBook(bookEntity));
    }

    return books;
}

А в контроллере немного модифицируем метод получения списка книг таким образом, что при передаче get-параметра author мы искали по автору, а если параметр не передётся, то используется старая логика и выводится список всех книг:

@GetMapping
public List<Book> getAllBooks(@RequestParam(required = false) String author) {
    if (author != null)
        return bookService.findByAuthor(author);

    return bookService.getAllBooks();
}

Теперь можно выполнить поиск:

curl -X GET --location "http://localhost:8080/books?author=Bloch" 
    -H "Accept: application/json"
[
  {
    "id": 1,
    "author": "Joshua Bloch",
    "title": "Effective Java",
    "price": 54.99
  }
]

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

Код проекта доступен на GitHub.

Содержание

  • 1 Веб-дизайн против фронт-энда
    • 1.1 Интерфейс Интернета: разметка, таблица стилей и языки программирования
  • 2 HTML
    • 2.1 Зачем тебе это нужно
    • 2.2 Анатомия элемента HTML
  • 3 CSS
    • 3.1 Зачем тебе это нужно
    • 3.2 Анатомия правила CSS
  • 4 JavaScript
    • 4.1 Зачем тебе это нужно
  • 5 С чего начать обучение
    • 5.1 Начиная
    • 5.2 Короткие сокращения
    • 5.3 Справочный материал
    • 5.4 Заключение

Компьютерный код и пиксели — это больше, чем просто кирпичи, — основа экономики XXI века. Если вы когда-либо просматривали «Источник страницы» или «Инструменты разработчика» в своем браузере, вы, скорее всего, столкнулись с беспорядком текста и удивились, как это работает на веб-странице.

Веб-разработчики называют графический пользовательский интерфейс (GUI) вместе фронтэндом веб-страницы, в отличие от серверной части. Пользовательский интерфейс — это то, с чем пользователь может манипулировать, предпринимать действия и иным образом использовать. Серверная часть может рассматриваться как инфраструктура, которая содержит и поддерживает всю информацию и задачи, подразумеваемые интерфейсом.

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

Веб-дизайн против фронт-энда

В крупных организациях проектирование и разработка — это задачи, выполняемые командами профессионалов с различными наборами навыков. Дизайнеры создадут конкретный визуальный и интерактивный дизайн; разработчики переднего плана будут реализовывать это.

Однако для отдельного человека нет причин ограничивать свое исследование: просто потому, что вы заинтересованы в разработке, это не означает, что у вас нет видения дизайна, и наоборот. Небольшое количество знаний об основных веб-технологиях или принципах дизайна может оказаться чрезвычайно полезным в вашей карьере или бизнесе.

Фронт-энд разработка — все более и менее кодирующая деятельность. Более того, в его мышлении более половины дизайна: многие концепции взяты из мира печатной продукции. Меньше, потому что, хотя он использует компьютерный код, этот код является менее сложным, более щадящим и требует меньших базовых знаний по программированию, чем другие языки веб-программирования (многие из которых можно найти на сервере)

,

Интерфейс Интернета: разметка, таблица стилей и языки программирования

Большинство веб-страниц построены с использованием трех технологий: языка разметки гипертекста (HTML), каскадных таблиц стилей (CSS) и JavaScript (JS):

  • Языки разметки, такие как HTML, помечают документ тегами. Теги разграничивают семантическое содержание и структурируют документ. Структурированные документы могут быть стилизованы.
  • CSS является языком таблиц стилей и потомком указателей стиля печати к компоновщику страниц (который создает окончательное печатное изображение для печатного станка); в Интернете CSS диктует представление контента, такого как типография и верстка в целом, а также размещение графики.
  • JavaScript, в отличие от двух предыдущих, является языком программирования. JS управляет взаимодействием и пользовательским вводом и фокусируется на событиях, которые производит пользователь. Чтобы заполнить картину немного больше, противоположность парадигме, управляемой событиями, — это та, где программирование выполняется независимо от пользовательского ввода.

HTML

Прошло более двадцати лет, и основная цель HTML остается неизменной: отделить текст, предназначенный для читателя, от структуры, необходимой для анализа документа.

Зачем тебе это нужно

Почему HTML все еще важен? Проще говоря, в HTML заключается семантическое значение вашего контента. Это необходимо для машинных читателей, таких как поисковые машины и программы для чтения с экрана (для доступности). Со временем актуальность разделения того, что является семантическим, и того, что является структурным, со временем выросла, а не уменьшилась. В самой последней версии HTML (5) были введены такие теги, как,, и, для уточнения семантики и структуры. Это приносит пользу как читателям, так и людям.

Анатомия элемента HTML

Элементы HTML, как минимум, являются парами

) Скомпилировать

  • Джейд | Требуется Node.js (введение вы найдете здесь

    ) Скомпилировать

  • Slim | Требуется Ruby для компиляции (как указано выше)
  • CSS

    CSS позволяет размещать семантическое содержимое и представление документа по отдельности, что делает такие стилистические функции, как макет, цвета и типография, переносимыми и применимыми к различным документам. Когда контент и визуальный дизайн разделены, разработчик получает больше гибкости и согласованности в визуальном дизайне.

    Зачем тебе это нужно

    Нестайл-сайты выглядят ужасно и непривлекательно. Несмотря на то, что они могут быть читабельными, CSS является краеугольным камнем визуальной информационной иерархии из-за разметки, которую он включает. Например, рисунок ниже частично иллюстрирует текущее верхнее меню навигации на makeuseof.com без применения CSS.

    Ий-менюОбратите внимание на то, что кроме типографики и цвета меню без стилей является вертикальным, потому что это стиль браузера по умолчанию. Маловероятно, что вы захотите воссоздать Интернет 1990-х годов, поэтому вы хотите, чтобы здоровая и непрерывная порция знаний CSS была по-настоящему компетентной. Кроме того, с появлением различных по размеру и подключенных устройств, таких как iPhone, планшеты и т. Д., Одним из наиболее важных навыков стал «Адаптивный дизайн» или веб-страницы, которые адаптируются к экранам разных размеров. Все это выполняется с помощью CSS.

    Анатомия правила CSS

    Правила CSS написаны в одном из трех мест: а) встроенный в элемент, б) путем создания раздела в теге HTML-документа, в) в отдельной таблице стилей, такой как style.css.

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

    Правила CSS начинаются с селектора, написанного зеленым цветом ниже. В этом случае селектором правила будет p для абзаца: правило применяется к элементам абзаца. Правило заключено в {фигурные скобки}, в отличие от. В этом случае правило делает шрифт для текста абзаца нормальным.

    Создание веб-интерфейсов: с чего начать правила CSS

    Правила CSS могут стать более сложными и сложными, чем позволяет это введение. Вот почему с точки зрения времени, вы можете ожидать Освоение CSS займет намного больше времени, чем HTML.

    Дополнительный кредит (продвинутый)

    Как и HTML, CSS имеет свои оптимизации для тех, кто хочет достичь большего и быстрее.

    • SASS (и SCSS) | Требуется Ruby, как указано выше
    • Меньше | Требуется Node.js, как указано выше

    JavaScript

    Когда многие люди думают о кодировании, они думают об этом как о том, как наставлять компьютер, как что-то делать. Это задача языка программирования, нашего последнего дополнения к внешнему уравнению.

    Javascript-udemy-курсы

    Языки программирования обычно классифицируются по уровню абстракции, которую они используют в своей семантике, языках своих предков, своих парадигмах и своих типах дисциплин. JavaScript не поддается простой классификации, потому что он был распространен на очень много фреймворков, чтобы соответствовать такому разнообразию целей. Это гибкая мультипарадигмальная гибридная модель хамелеона со слабой типизацией, имеющая неопределенное происхождение от семейства C, играющая в сорока с концепциями кодирования. Это либо отличный пример языка общего назначения, либо очень плохой пример множества различных типов языков.

    Зачем тебе это нужно

    Зачем учить JavaScript? Как отмечает мой коллега, в JavaScript есть свои чемпионы и недоброжелатели

    особенно в случае его пригодности для начинающих учеников. Это, пожалуй, самый популярный язык программирования сегодня. Хотя это не дает прочной основы для понимания остального царства кодирования, есть хороший аргумент для изучения JS наряду с Ruby или PHP.

    Тем не менее, vanilla JS не заходит слишком далеко — фреймворки отвечают за современные веб-страницы.

    Популярные рамки

    • Angular, Google JS Framework для веб-приложений, таких как GMail и другие.
    • JQuery

      , уже охваченный MUO здесь

      , который работает WordPress среди других приложений.

    • React, созданный техническими легионами Facebook, создан для создания пользовательских интерфейсов.

    Дополнительный кредит (продвинутый)

    Примитивная природа JavaScript требует некоторого навязывания структуры. Каждый из нижеприведенных сахарных шкур идет по пути реализации

    • CoffeeScript | Требуется Node.js, как указано выше
    • Машинопись | Требуется Node.js, как указано выше

    С чего начать обучение

    Поскольку начальная разработка в настоящее время широко считается важнейшим рабочим навыком для работников умственного труда всех видов, вы найдете множество отправных точек в виде курсов электронного обучения. Вот список, который мы подготовили для наших читателей:

    • Coursera (Платная)
      Coursera собирает онлайн-курсы от университетов и учебных заведений. Диапазон цен падает от 50-250 долларов США за курс, но они рекламируют высокий уровень знаний и результаты высокой компетентности.
    • Dash Генеральной Ассамблеи (бесплатно)
      Генеральная Ассамблея является популярным вариантом платного профессионального образования. Dash является их бесплатным предложением и охватывает HTML / CSS / JS.
    • MakeUseOf.com — пакет «Учимся кодировать 2017» (платный, подключаемый модуль)
      Пожизненный доступ к 10 классам, охватывающим всю гамму веб-разработки на передней и задней части, всего за 20 долларов США.
    • Сеть разработчиков Mozilla (бесплатно)
      MDN является авторитетным, но больше походит на стиль документации, чем на обучение в стиле классной комнаты или игровые предложения только для онлайн.
    • Treehouse (Платный)
      Еще одно онлайн предложение, платное за месяц, а не за курс. Это происходит по рекомендации Карен X Ченг в ее вирусном издании Medium «Как устроиться на работу дизайнером, не посещая школу дизайна».
    • Учебные пособия по веб-дизайну от Envato Tuts + (Смешанное бесплатное и платное содержимое одинакового качества)
      Совокупность одноразовых статей и многокомпонентных серий высококачественной, конкретной и целевой информации, обычно по одному предмету.

    Начиная

    Одним из преимуществ, которые имеет передовая разработка для начинающих, является то, что, по большей части, она не требует дорогостоящих проприетарных инструментов: самый основной инструмент передовой разработки — это текстовый редактор в сочетании с выбранным вами браузером. :

    • Текстовые редакторы, такие как текстовый редактор Git Atom, Sublime Text (платный) или VS Code от Microsoft
    • Браузеры, такие как Mozilla Firefox или Google Chrome
    • Полезно, но за рамками этой статьи, настроить хостинг или локальный сервер (например, XAMPP).

    Более удобными, но менее постоянными альтернативами являются живые веб-редакторы, такие как:

    • Codepen.io
    • JSbin.com

    Короткие сокращения

    Структуры HTML, по большей части, понятны и не заслуживают повторного ввода с большой частотой. Для CSS средняя таблица стилей сайта имеет длину в тысячи строк, и вы можете поспорить, что немногие современные написаны исключительно вручную. И с точки зрения интерактивности, определенные стандарты появились. На основании этих фактов вы обнаружите, что многие разработчики внешних интерфейсов используют предварительно созданные инфраструктуры в качестве основы, а затем настраивают, удаляют или заменяют по мере необходимости.

    • Bootstrap, изначально разработанный Twitter, содержит шаблоны HTML, CSS и JS, которые сегодня широко распространены в Интернете. Bootstrap — почти лингва франка в начале веб-разработки.
    • Фонд позиционирует себя как наиболее продвинутый фреймворк в мире и построен с акцентом на небольшой размер и скорость.

    Справочный материал

    • A List Apart — A-list публикация «Для людей, которые делают сайты»
    • Могу ли я использовать — «Поддержка таблиц для HTML5, CSS3 и т. Д.»
    • CSS-Tricks — центр для сообщества CSS и источник знаний о лучших практиках и совместимости
    • Документация HTML Living Standard — «Стандарт жизни — издание для веб-разработчика»
    • HTML5 Пожалуйста — «Используйте новые и блестящие ответственно»
    • Smashing Magazine — «Для профессиональных веб-дизайнеров и разработчиков»

    Заключение

    Мы надеемся, что вам понравилась эта ориентация на мир front-end. Как видите, разработка интерфейса — это область, которая наполнена множеством возможностей, но имеет много точек входа. Изучение его добавит впечатляющий навык в ваш портфель и позволит вам сделать следующий шаг в своей карьере или перейти к совершенно новому.

    Разработчики: Что у вас в стеке переднего плана?

    Начинающие: Что еще мы могли бы включить, чтобы сориентировать вас?

    Понравилась статья? Поделить с друзьями:
  • Как написать веб бота
  • Как написать вдали от дома
  • Как написать вдалеке или вдалике
  • Как написать вглубь вместе или раздельно
  • Как написать вводную часть проекта