Category: Web

27
Мар
2020

Как сделать кликабельный телефон на сайте

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

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

13
Фев
2020

«Каждый охотник желает знать»: теория цвета для веба и приложений

Рассказываем, как правильно подбирать и комбинировать цвета. Цветовой круг, модель HSL, цветовые схемы и психология, советы и правила. Показываем на примерах, как применять в CSS.

12
Фев
2020

Секреты правильной растяжки: адаптивные графики в вебе без клиентского JavaScript

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

Существует кучах библиотек для создания графиков и диаграмм в вебе. Можно даже имитировать отрисовку диаграмм «от руки». Обычно данные для графиков запрашиваются из сети или сама картинка рендерится на canvas – кажется, что без JavaScript не обойтись.

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

Ещё одна проблема – адаптивность. Графики необходимо перерисовывать при ресайзе, иначе они «поломаются». Это создаёт лишнюю работу и для браузера, и для программиста. Особенно если используются низкоуровневые библиотеки вроде D3.

Возьмём для примера SVG-графики из статьи New York Times и подумаем, можем ли построить их без JS.


Все методы, используемые в статье, собраны в экспериментальный компонент Pancake для фреймворка Svelte.

Проблема

Создать линейный график на SVG не так уж и сложно. Допустим, есть вот такие данные:

            const data = [
  { x: 0,  y: 0 },
  { x: 1,  y: 1 },
  { x: 2,  y: 4 },
  { x: 3,  y: 9 },
  { x: 4,  y: 16 },
  { x: 5,  y: 25 },
  { x: 6,  y: 36 },
  { x: 7,  y: 49 },
  { x: 8,  y: 64 },
  { x: 9,  y: 81 },
  { x: 10, y: 100 }
];
        

Требуется вывести результат в область размером 300×100 пикселей.

Чтобы получить координаты опорных точек, нужно умножить x на 30, а y вычесть из 100:

            <polyline points="
  0,0
  30,99
  60,96
  90,91
  120,84
  150,75
  180,64
  210,51
  240,36
  270,19
  300,0
"></polyline>
        

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

            function scale(domain, range) {
  const m = (range[1] - range[0]) / (domain[1] - domain[0]);
  return num => range[0] + m * (num - domain[0]);
}

const x = scale([0, Math.max(...data.map(d => d.x))], [0, 300]);
const y = scale([0, Math.max(...data.map(d => d.y))], [100, 0]);

const points = data.map(d => `${x(d.x)},${y(d.y)}`).join(' ');

const chart = `
<svg width="300" height="100">
  <polyline points="${points}"></polyline>
</svg>
`;
        

Добавив в svg пару осей и немного стилей, получаем график:


Живой пример

Всю логику можно разместить в NodeJS-скрипте, так что код будет целиком генерироваться на сервере. Таким образом, нам не требуется ни строчки клиентского JavaScript.

Однако этот чарт не адаптивен, размеры всегда составляют 300x100px. А это не то, чего мы ожидаем.

Решение. Часть 1

У SVG-элемента есть атрибут viewBox, задающий систему координат изображения, независящую от реальных размеров. По умолчанию соотношение сторон, заданное в viewBox сохраняется. Подавляется такое поведение с помощью preserveAspectRatio="none".

Добавим простую систему координат:

            <svg viewBox="0 0 100 100" preserveAspectRatio="none">
        

Что ж, теперь наш график действительно стал гибким…


Живой пример

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

Вторую проблему легко решить, используя малоизвестное CSS-свойство vector-effect: non-scaling-stroke для каждого элемента.


Живой пример

Но с масштабированием текста придётся разбираться другими методами.

Решение. Часть 2

Оси графика необязательно рисовать прямо в SVG. Мы можем использовать обычные HTML-элементы и расположить их с помощью CSS. Чтобы синхронизировать масштабирование HTML- и SVG-слоев, применяем процентную координатную сетку.

            <!-- x axis -->
<div class="x axis" style="top: 100%; width: 100%; border-top: 1px solid black;">
  <span style="left: 0">0</span>
  <span style="left: 20%">2</span>
  <span style="left: 40%">4</span>
  <span style="left: 60%">6</span>
  <span style="left: 80%">8</span>
  <span style="left: 100%">10</span>
</div>

<!-- y axis -->
<div class="y axis" style="height: 100%; border-left: 1px solid black;">
  <span style="top: 100%">0</span>
  <span style="top: 50%">50</span>
  <span style="top: 0%">100</span>
</div>

<style>
  .axis {
    position: absolute;
  }

  .axis span {
    position: absolute;
    line-height: 1;
  }

  .x.axis span {
    top: 0.5em;
    transform: translate(-50%,0);
  }

  .y.axis span {
    left: -0.5em;
    transform: translate(-100%,-50%);
  }
</style>
        

График больше не ломается!


Живой пример

Ещё одно преимущество HTML-элементов – они автоматически привязываются к ближайшему пикселю. Так что не появляется неприятный эффект нечёткости, который встречается в SVG.

Готовое решение

Потребовалось много ручной работы. Чтобы этого избежать, воспользуемся готовым решением – компонентом Pancake для SvelteJS.

            <script>
  import * as Pancake from '@sveltejs/pancake';

  const points = [
    { x: 0,  y: 0 },
    { x: 1,  y: 1 },
    { x: 2,  y: 4 },
    { x: 3,  y: 9 },
    { x: 4,  y: 16 },
    { x: 5,  y: 25 },
    { x: 6,  y: 36 },
    { x: 7,  y: 49 },
    { x: 8,  y: 64 },
    { x: 9,  y: 81 },
    { x: 10, y: 100 }
  ];
</script>

<div class="chart">
  <Pancake.Chart x1={0} x2={10} y1={0} y2={100}>
    <Pancake.Box x2={10} y2={100}>
      <div class="axes"></div>
    </Pancake.Box>

    <Pancake.Grid vertical count={5} let:value>
      <span class="x label">{value}</span>
    </Pancake.Grid>

    <Pancake.Grid horizontal count={3} let:value>
      <span class="y label">{value}</span>
    </Pancake.Grid>

    <Pancake.Svg>
      <Pancake.SvgLine data={points} let:d>
        <path class="data" {d}/>
      </Pancake.SvgLine>
    </Pancake.Svg>
  </Pancake.Chart>
</div>

<style>
  .chart {
    height: 100%;
    padding: 3em 2em 2em 3em;
    box-sizing: border-box;
  }

  .axes {
    width: 100%;
    height: 100%;
    border-left: 1px solid black;
    border-bottom: 1px solid black;
  }

  .y.label {
    position: absolute;
    left: -2.5em;
    width: 2em;
    text-align: right;
    bottom: -0.5em;
  }

  .x.label {
    position: absolute;
    width: 4em;
    left: -2em;
    bottom: -22px;
    font-family: sans-serif;
    text-align: center;
  }

  path.data {
    stroke: red;
    stroke-linejoin: round;
    stroke-linecap: round;
    stroke-width: 2px;
    fill: none;
  }
</style>
        

Живой пример

Благодаря Svelte этот чарт отрендерить на сервере с помощью NodeJS или вставить в DOM на клиенте. Для больших и сложных интерактивных графиков может потребоваться одновременно и то, и другое. Основную разметку можно генерировать на сервере, а затем прогрессивно улучшать на клиенте, добавляя интерактивность. Без компонентных фреймворков типа Svelte это было бы непросто.

Обратите внимание, Pancake не создаёт элементы span и path внутри SVG-изображения. Компоненты прежде всего логические – вы детально контролируете представление.

Усложняем задачу

Мы можем сделать гораздо больше, чем простейшие линейные графики:


Например, очень интересны диаграммы рассеивания (scatterplots).

Живой пример

Мы не можем использовать для них элементы circle, так как они могут некорректно масштабироваться. Компонент Pancake.Scatterplot генерирует path, состоящий из несвязанных дуг с нулевым радиусом. Размер окружностей определяется шириной контура (stroke width).

Благодаря тому, что библиотека оформлена в виде компонента Svelte, мы легко можем добавить графикам немного интерактива.

Живой пример

Взаимодействия также можно декларативно обрабатывать прямо внутри графика Pancake. Например, создадим дерево квадрантов (quadtree, во многом заимствовано из библиотеки D3), которое позволит находить ближайшую к курсору точку.

            <Pancake.SvgScatterplot data={points} let:d>
  <path class="data" {d}/>
</Pancake.SvgScatterplot>

<Pancake.Quadtree data={points} let:closest>
  {#if closest}
    <Pancake.SvgPoint x={closest.x} y={closest.y} let:d>
      <path class="highlight" {d}/>
    </Pancake.SvgPoint>
  {/if}
</Pancake.Quadtree>
        

В будущем в библиотеке появится поддержка canvas (2D и WebGL). Конечно, графики на canvas не смогут работать без JavaScript, но при работе с большими наборами данных SVG может не справляться.

Предостережения

Помните, Pancake является экспериментальной библиотекой, у него ещё не очень много реальных кейсов.

Основное внимание уделено управлению системой координат для двумерных чартов. Для графиков, гистограмм и диаграмм рассеивания этого достаточно, но круговые диаграммы, к сожалению, не поддерживаются.

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

***

Название Pancake (Блин) связано с тем, что фактически чарты строятся путём наложения слоёв друг на друга. Проект во многом вдохновлялся фреймворком Layer Cake и библиотекой D3.

А какие инструменты вы применяете для построения графиков?

06
Фев
2020

Нет времени объяснять! Пишем таймер обратного отсчёта на чистом CSS

Ради фана реализуем динамический виджет таймера на одних стилях. Для порядка приводим ещё и решение на JavaScript (но это не главное).

CSS – мощный инструмент современного разработчика. Он многое умеет, в нём есть переменные, функции, наследование и ещё много крутых штук. Но всё-таки это не язык программирования – у него совсем другая сфера ответственности. Тем интереснее использовать CSS для решения задач программирования 🙂 Именно этим сегодня и займёмся.

Дисклеймер! Многие вещи в принципе невозможно сделать на CSS. Ещё больше вещей делать на CSS нерационально. Мы занимаемся этим только из болезненного любопытства и стремления познать все скрытые возможности инструмента.

Условие задачи

Нужно сделать таймер обратного отсчёта. Предъявляемые требования:

  • Таймер должен выводить миллисекунды от 99 до 0.
  • Когда остаётся меньше 10 миллисекунд, нужно выводить только одну цифру (от 9 до 0) и центрировать её.
  • Бонус #1: Цвет шрифта и фона можно настраивать в процессе работы (без кусочка JS не обойтись).
  • Бонус #2. После остановки таймера его можно перезапустить.
  • Код должен работать и на ПК, и на мобильных устройствах.

Чтобы выполнить указанные условия, пойдём напролом. Все нужные цифры (от 0 до 9) запишем прямо в базовую разметку страницы. Затем для имитации таймера анимируем их в нужном ритме и правильной последовательности.

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

Что нам потребуется?

  1. CSS трансформации
  2. CSS анимации
  3. Flexbox-модель
  4. CSS переменные
  5. Различные селекторы

Вот что получится в итоге:

Реализация на JavaScript

Сразу посмотрим, как это можно было сделать на JS.

Простой и понятный код, состоящий из пары функций. Для обновления таймера подписываемся на момент перерисовки браузера с помощью метода window.requestAnimationFrame().

            let end;
const now = Date.now;
const timer = document.getElementById("timer");
const duration = 9900;

function displayCountdown() {
  const count = parseInt((end - now()) / 100);
  timer.textContent =
    count > 0 ? (window.requestAnimationFrame(displayCountdown), count) : 0;
}

function start() {
  end = now() + duration;
  window.requestAnimationFrame(displayCountdown);
}
        

Всего пара блоков в HTML:

            <div class="timer-container">
  <p class="timer" id="timer">99</p>
</div>
        

И элементарные стили для выравнивания:

            .timer-container {
  display: flex;
  height: 100vh; 
}

.timer {
  margin: auto;
}
        

Согласитесь, ровным счётом ничего интересного. Поэтому бросаем эту ерунду и идём писать по-настоящему крутой таймер.

Общий подход

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

            <div class="timer">
  <div class="digit seconds">
    <span>9</span>
    <span>8</span>
    <span>7</span>
    <span>6</span>
    <span>5</span>
    <span>4</span>
    <span>3</span>
    <span>2</span>
    <span>1</span>
    <span>0</span> 
  </div><div class="digit milliseconds">
    <span>9</span>
    <span>8</span>
    <span>7</span>
    <span>6</span>
    <span>5</span>
    <span>4</span>
    <span>3</span>
    <span>2</span>
    <span>1</span> 
    <span>0</span>
  </div>
</div>
        

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

CSS трансформации

Большинство CSS-свойств плохо подходят для анимирования, так как их изменение вызывает перерисовку страницы. Но есть два «безопасных» свойства, которыми мы можем воспользоваться: transform и opacity.

Подробнее об анимации в вебе можно прочитать в замечательном руководстве High Performance Animations.

Для оживления таймера возьмём надёжное свойство translateY. Оно обеспечит перемещение блока только по y-оси.

            .selector {
  transform: translateY(0);
}
        

Можно воспользоваться и полным свойством translate, но помните, что его первый аргумент соответствует x-координате. Если хотите перемещать элемент только по вертикали, то передайте первым параметром 0.

            .selector {
  transform: translate(3em);
}

/* то же самое */
.selector {
  transform: translate(3em, 0);
}
        

Чтобы лучше понять функции трансформации, загляните в спецификацию CSS Transforms Module Level 1. Там всё разобрано на подробных примерах, так что вы разберётесь, даже если не очень любите математику.

CSS animations

Следующий шаг – анимировать применение трансформаций. Для этого мы используем CSS-анимации.

Самое важное правило, которое вы должны знать, – это @keyframes. Оно позволяет разбить анимацию на кадры и описать каждый из них в отдельности.

            @keyframes seconds {
  0% { transform: translateY(0) }
  10% { transform: translateY(-1em) }
  20% { transform: translateY(-2em) }
  30% { transform: translateY(-3em) }
  40% { transform: translateY(-4em) }
  50% { transform: translateY(-5em) }
  60% { transform: translateY(-6em) }
  70% { transform: translateY(-7em) }
  80% { transform: translateY(-8em) }
  90% { 
    transform: translateY(-10em);
    width: 0;
  }
  100% { 
    transform: translateY(-10em);
    width: 0;
  }
}

@keyframes milliseconds {
  0% {transform: translateY(0) }
  10% { transform: translateY(-1em) }
  20% { transform: translateY(-2em) }
  30% { transform: translateY(-3em) }
  40% { transform: translateY(-4em) }
  50% { transform: translateY(-5em) }
  60% { transform: translateY(-6em) }
  70% { transform: translateY(-7em) }
  80% { transform: translateY(-8em) }
  90% { transform: translateY(-9em) }
  100% { transform: translateY(-9em) }
}
        

Здесь мы создали две анимации – по одной для каждого блока с цифрами.

Обратите внимание на два последних кадра в анимации первого блока. В этот момент там должна отображаться цифра 0, но она нам не нужна, поэтому скрываем её с помощью width: 0.

Чтобы применить анимации, используем краткий синтаксис свойства animation:

            .seconds {
  animation: seconds 10s 1 step-end forwards;
}

.milliseconds {
  animation: milliseconds 1s 10 step-end forwards;
}
        

Если вы зайдете в панель инструментов разработчика и откроете вкладку с вычисленными значениями (computed), то увидите, что вместо одного свойства animation к элементу применились сразу несколько:


animation-name

Имя анимации, использующееся для её идентификации. Для него можно использовать латинские буквы, цифры, нижнее подчёркивание и дефисы. Первой должна идти буква. В начале не могут стоять зарезервированные слова none, unset, initial или inherit, а также сочетание --. Регистр символов имеет значение.

animation-duration

Продолжительность одного цикла анимации. Для первой колонки цифр анимация будет длиться 10 секунд (10s). Вторая колонка двигается в 10 раз быстрее (1s).

animation-iteration-count

Количество циклов анимации, которое должно выполниться до ее остановки. Первую колонку нужно прокрутить лишь один раз – от 9 до 0. Вторую – целых 10 раз, по одному на каждое положение первой колонки.

animation-timing-function

Это свойство описывает прогресс анимации в течение одного цикла. Если вы знакомы с кривыми Безье, то можете контролировать его до мельчайших подробностей с помощью функции cubic-bezier(). Для простых смертных есть несколько готовых значений animation-timing-function, обозначенных ключевыми словами (ease, ease-in и т.д)

Нам же больше подойдёт значение step-end. Это то же самое, что и steps(1, jump-end).

Функция steps() разбивает анимацию на равные «шаги», то есть величина изменяется не плавно, а прерывисто. Первый аргумент – количество шагов, второй – момент, когда начинается анимация. Ключевое слово jump-end означает, что анимация запускается в конце, а не начале каждого шага.

Чтобы лучше разобраться в этой функции, обратитесь к статье Дэна Уилсона Jumps: The New Steps() in Web Animation.

animation-fill-mode

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

Когда анимация остановится, первая цифра будет скрыта, а вторая колонка замрёт на позиции -9em.

Ещё больше о CSS анимациях вы можете узнать в спецификации CSS Animations Level 1.

Flexbox

Цифру 0 в первом разряде мы уже скрыли с помощью инструкции @keyframes, осталось только выровнять таймер по центру страницы:

            .timer-container {
  display: flex;
  height: 100vh; 
}

.timer {
  overflow: hidden;
  margin: auto;
  height: 1em;
  width: 2ch;
  text-align: center;
}

.digit {
  display: inline-block;
}

.digit span {
  display: block;
  width: 100%;
  height: 1em;
}
        

Для вертикального выравнивания используем автоматический расчёт маргинов у потомка флекс-контейнера. Другими словами, назначаем display: flex родительскому блоку, и margin: auto дочернему.

Горизонтальное выравнивание достигается обычным text-align: center.

Больше информации о Flex-модели – в спецификации CSS Flexible Box Layout Module Level 1.

Бонус #1: Динамическое изменение цвета

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

Используем для ее решения кастомные свойства CSS и инпут выбора цвета.

Положим цвета в переменные:

            :root {
  --fontColour: #000000;
  --bgColour: #ffffff;
}
        

И используем их в таймере:

            .timer {
  background-color: var(--bgColour, white);
}

.digit {
  color: var(--fontColour, black);
}
        

Добавим на страницу два инпута для изменения цветовой схемы:

            <aside>
  <label>
    <span>Font colour:</span>
    <input id="fontColour" type="color" value="#000000" />
  </label>
  <label>
    <span>Background colour:</span>
    <input id="bgColour" type="color" value="#ffffff" />
  </label>
</aside>
        

Теперь придётся написать пару строк JS-кода, чтобы динамически изменять переменные цветов при изменении инпутов:

            let root = document.documentElement;
const fontColourInput = document.getElementById('fontColour');
const bgColorInput = document.getElementById('bgColour');

fontColourInput.addEventListener('input', updateFontColour, false);
bgColorInput.addEventListener('input', updateBgColour, false);

function updateFontColour(event) {
  root.style.setProperty('--fontColour', event.target.value);
}

function updateBgColour(event) {
  root.style.setProperty('--bgColour', event.target.value);
}
        

Да, не всё можно решить на чистом CSS.

Бонус #2: Перезапуск таймера

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

Возможно, вы подумали, что нам придётся снова смошенничать и добавить JavaScript? А вот и нет, мы справимся своими силами!

Воспользуемся чекбоксом, который обладает состоянием checked. Мы легко можем получить к нему доступ из CSS.

            .toggle span {
  font-size: 1.2em;
  padding: 0.5em;
  background-color: palegreen;
  cursor: pointer;
  border-radius: 4px;
}

input[type="checkbox"] {
  opacity: 0;
  position: absolute;
}

 input[type="checkbox"]:checked ~ aside .toggle span:first-of-type {
  display: none;
}

.toggle span:nth-of-type(2) {
  display: none;
}

input[type="checkbox"]:checked ~ aside .toggle span:nth-of-type(2) {
  display: inline;
}
        

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

            input[type="checkbox"]:checked ~ .timer .seconds {
  animation: seconds 10s 1 step-end forwards;
}

input[type="checkbox"]:checked ~ .timer .milliseconds {
  animation: milliseconds 1s 10 step-end forwards;
}
        

Важно, чтобы чекбокс находился на одном уровне с таймером и стоял в разметке перед ним. Это даст нам возможность воспользоваться селектором “сиблингов” (~). А лейбл для него может находиться где угодно.

***

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

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

Если вы любите CSS, вот ещё кое-что:

В комментариях делитесь самыми нестандартными решениями ваших задач.

20
Янв
2020

Графический приём, благодаря которому пользователи будут регистрироваться чаще

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

При разработке приложения мы прикладываем все усилия к со…

17
Янв
2020

Веб-скрапинг по расписанию с Django и Heroku

оздаём Django-приложение, ежедневно проверяющее доску объявлений о работе. Парсим в BeautifulSoup, сохраняем в PostgreSQL, развёртываем на сервере Heroku.

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

31
Окт
2019

WebMoney Domains

В настоящее время существует много интересных доменных зон, некоторые из них были и раньше. У большинства сервисов позволяющих регистраторовать на такие зоны большие скидки и на какой-то момент можно поверить, чтобы были созданы дешёвые и доступные зоны для всех пользователей для любых нужд, но на самом деле это и близко не так. На днях столкнулся с интересным сервисом от webmoney… Читать далее »

Запись WebMoney Domains впервые появилась Индиго.

13
Сен
2019

Поддержка сайта

С момента появления таких сервисов как narod.ru, Google Sites или Front Page, которые позволяли «склепать» самостоятельно простой сайт с использованием элементарных шаблонов, многие создавали себе домашние странички, где рассказывали о себе, о своих услугах, хобби, достижениях. Однако, для рекламы коммерческих услуг такое решение не подходило и стали обращаться к профессионалам, которые предлагали комплекс услуг по созданию сайта. Так было до тех… Читать далее »

Запись Поддержка сайта впервые появилась Индиго.

05
Сен
2019

Что такое IT-аутсорсинг и способы организации

За последние несколько лет IT-аутсорсинг прочно вошел в экономическую жизнь общества и взаимоотношения в бизнесе. Использование сторонних сервисов для решения задач в самом широком спектре информационных технологий можно назвать трендом нашего времени Выгоды и преимущества IT-аутсорсинга Более высокое качество услуг при относительно низкой стоимости. Возможность в одной фирме решить все необходимые задачи по созданию и обслуживанию IT-инфраструктуры. Абонентские услуги в… Читать далее »

Запись Что такое IT-аутсорсинг и способы организации впервые появилась Индиго.

30
Авг
2019

Список лучших CSS фреймворков для фронтенд-разработки

Список лучших CSS фреймворков для фронтенд-разработкиМечтаете быстро создавать прототипы приложений? Упростите себе задачу с помощью этих CSS фреймворков. И не придётся беспокоится о стилях. Зачем использовать CSS фреймворки при написании пользовательского CSS-кода? Время – ограниченный ресурс, поэтому тратьте его на создание функциональности. Улучшите ли производительность и эстетику, когда создадите CSS с нуля? Абсолютно! Но когда нет творческих способностей в области […]

Запись Список лучших CSS фреймворков для фронтенд-разработки впервые появилась Библиотека программиста.

26
Авг
2019

Мастер отзывчивого дизайна за 5 минут: 4 секретные техники

Современный веб-сайт должен хорошо выглядеть в любых условиях. Разбираемся в основах отзывчивого дизайна и учим страницу подстраиваться. Что такое отзывчивый дизайн?  Это способность вашего сайта подстраиваться под изменение внешних условий, например, ширины браузера, без потери визуальной привлекательности. Смотрите небольшой ликбез по отзывчивости и адаптивности в вебе. Зачем нужен отзывчивый дизайн?  Чтобы пользователи могли с одинаковым […]

Запись Мастер отзывчивого дизайна за 5 минут: 4 секретные техники впервые появилась Библиотека программиста.

22
Май
2019

8 самых распространенных ошибок веб-разработчика

Сложный и громоздкий проект чреват серьезными ошибками: это знает каждый. Смотрите наш ТОП-8 ошибок веб-разработчика и не совершайте их!

Не будем рассыпаться в описании причин, которые обязывают нас тестировать. Сразу к делу.

15
Май
2019

Масштабируемый WordPress-кластер почти бесплатно

Как директор по разработке Design Home, одной из ведущих мобильных игр Glu Mobile, я имею дело с действительно большими вопросами масштабируемости. Поэтому, когда я решил настроить свой собственный блог Effective Programmer, используя WordPress, для меня было естественным создать что-то, что можно масштабировать для работы с сотнями тысяч пользователей в сутки.