Тег: пример

Условные комментарии для Internet Explorer в React

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

В моем текущем проекте нам нужно было поддерживать css медиа-запросы в IE9. Для этого было решено использовать библиотеку media-match.

Что может быть проще? Пара строк кода с условным комментарием:

<!--[if lte IE 9]>
   <script src="/public/media.match.js">
<![endif]-->

Но все оказалось намного сложнее, так как мы используем React.js и делаем изоморфное одностраничное приложение. Кто бы знал, что React не рендерит на странице комментарии, помещенные в .jsx-файлы. Показынный ниже способ не работает:

renderHead: function() {
  return (
    <head>
      <!--[if lte IE 9]>
      <script src="/public/media.match.js"/>
      <![endif]-->
    </head>
  );
}

Единственный способ, который мне удалось найти – dangerouslySetInnerHTML для head, внутрь которого я поместил комментарий и все заработало:

renderHead: function() {
  return (
    <head dangerouslySetInnerHTML={{__html: '<!--[if lte IE 9]><script src="/public/media.match.js"></script><![endif]-->'}}>
    </head>
  );
}

Следует также отметить, что тэг script должен быть закрыт отдельно <script></script>, так как сокращение <script /> не работает в React.

Последняя, но, при этом, большая проблема – если надо поместить несколько таких комментариев в head. Конечно, можно все просто написать в одну строку, но это выглядит «убого».

Поэтому я, да простят меня парсерсы HTML в браузерах, положил условные комментарии внутри тэга meta:

renderHead() {
  return (
    var comment = '<!--[if lte IE 9]><script src="/public/media.match.js"></script><![endif]-->';
    <head>
      <title>Website title</title>
      <meta name="react-comment-hack" 
          dangerouslySetInnerHTML={{__html: comment}}>
      </meta>
    </head>
  );
}

Успешного «реакта».

© Автор Maks Nemisj

07 мая 2015
3.4 тыс.
1 мин

CSS стилизация checkbox и radio для мобильных устройств

Сделать чекбоксы input[type="checkbox"] и радиокнопки input[type="radio"] красивыми – задача не сложная. Однако, чаще всего, за этим следует добавление новых элементов, а следовательно и усложнение DOM-структуры документа.

Для современных мобильных браузеров, а также декстопных браузеров на основе WebKit и Blink (Chrome, Opera, Vivaldi и т.д.), для некоторых типов инпутов можо создавать псевдо-элементы after и before.

06 февраля 2015
5.3 тыс.
3 мин

Placeholder с поведением в стиле Material Design

Кто видел Material Design от Google, тот знает, что там есть довольно забавное поведение placeholder-а для поля ввода. Я решил попробовать сделать такое на CSS, но столкнулся с некоторыми проблемами (легко решаются с JavaScript).

Давайте посмотрим, что у меня получилось – ДЕМО.

04 февраля 2015
4.9 тыс.
2 мин

Переосмысление отзывчивого SVG

Отличная статья Ильи Пухальского:

Если вы ещё не знакомы с техникой отзывчивых иконок Джо Харрисона, то, скорее всего, будете впечатлены так же сильно, как и я, когда впервые открыл её для себя. В этой статье я бы хотел исследовать, что мы можем делать с SVG, кроме традиционной практики замены PNG. В частности, мы можем рассматривать SVG как независимый модуль, который включает в себя CSS для кастомизации вариантов отображения; также как и правила для отзывчивого поведения, SVG может содержать в себе JavaScript для логики взаимодействий. Теперь давайте рассмотрим эту технику детальнее.

31 января 2015
4 тыс.
12 мин

Всплывающее уведомление (popup) на CSS без JavaScript

Продолжу серию статей о том, что принято делать на JavaScript, но можно сделать на чистом CSS с использованием чекбоксов. Расскажу как сделать всплывающее окно popup.

ДЕМО.

Немного комментариев к коду.

HTML:

<div class="popup-wrapper">
  <input type="checkbox" class="popup-checkbox" id="popupCheckboxOne">
  <div class="popup">
    <div class="popup-content">
      <label for="popupCheckboxOne" class="popup-closer">&#215;</label>
      Popup text
    </div>
  </div>
</div>

<label for="popupCheckboxOne" class="popup-shower">Show Popup</label>

Все просто, на странице есть блок popup-wrapper, в котором лежит чекбокс popup-checkbox, рядом с ним всплывающее окно, а в конце кнопка-ссылка для вызова это окна. Сделана она на основе label.

CSS для всплывающего окна и кнопок открытия и закрытия «попапа»:

.popup-checkbox, .popup {
  display: none;
}

.popup {
  position: fixed;
  z-index: 10;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
}

.popup:before {
  display: block;
  content: ' ';
  position: absolute;
  z-index: 1;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  background-color: #000;
  opacity: .5;
}

.popup-content {
  width: 200px;
  height: 200px;
  position: absolute;
  z-index: 2;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  background-color: #fff;
  border: 1px solid #ddd;
  border-radius: 6px;
  padding: 20px;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.popup-shower {
  color: #00f;
  cursor: pointer;
  text-decoration: underline;
}

.popup-shower:hover {
  color: #00a;
  text-decoration: underline;
}

.popup-closer {
  position: absolute;
  top: 5px;
  right: 5px;
  color: #999;
  font-size: 20px;
  border: 1px solid #999;
  display: block;
  width: 20px;
  height: 20px;
  line-height: 20px;
  text-align: center;
  border-radius: 50%;
  cursor: pointer;
}

.popup-closer:hover {
  background-color: #eee;
}

И чекбокс и всплывающее окно спрятаны (чекбокс никогда и не появится).

Теперь CSS-стиль, который непосредственно влияет на отображение всплывающего окна:

.popup-checkbox:checked + .popup {
  opacity: 1;
  display: block;
}

Здесь все банально, если чекбокс выбран - показать «попап».

30 января 2015
19.9 тыс.
2 мин

CSS, вертикальное выравнивание текста с Flexbox

Люди уже давно летают в космос, но до сих пор не умеют нормально выравнивать текст по вертикали в CSS.

Казалось бы, во времена таблиц и ячеек это было легко, присваиваешь атрибуту valign значение middle и в ячейке текст выровнен. Затем пришли эти, так любимые всеми div-ы и пришлось начать использовать костыли. Но время, вроде как, не стоит на месте и скоро всех нас ждет радость и облегчение – мы начнем использовать Flexbox.

Как же выравнять блоки по вертикали? Все просто:

HTML:

<div class="flexbox-wrapper">
    <div>Lorem ipsum dolor sit...</div>
    <div>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ad rem redeamus; Quamquam non negatis nos intellegere quid sit voluptas, sed quid ille dicat. Non quam nostram quidem, inquit Pomponius iocans; Laelius clamores sofòw ille so lebat Edere compellans gumias ex ordine nostros.</div>
</div>

CSS:

.flexbox-wrapper {
    display: -webkit-flex;
    display: -ms-flex;
    display: flex;
    -webkit-align-items: center;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
}

.flexbox-wrapper > div {
  width: 50%;
}

Ну и ДЕМО для порядка.

26 января 2015
31.9 тыс.
1 мин

Всплывающие подсказки на CSS

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

Многие для такого рода функцилнала используют различные JavaScript библиотеки. Но зачем? Достаточно только CSS с псевдо-элементами и использования значения аттрибутов в них.

Сразу скажу, что поддержка у всех этих фич есть, начиная с Internet Explorer 8.

Теперь код.

<abbr 
    data-title="Белорусская Федерация Компьютерного Спорта" 
    class="popover">
        БФКС
</abbr>

В данном примере я использовал тэг abbr, но использовать можно абсолютно любой, какой вам нравится.

В аттрибуте data-title хранится текст всплывающей подсказки, а класс popover необходим для написания стилей.

abbr {
  font: 16px 'Trebuchet MS';
  border-bottom: 1px dashed #666;
}
.popover {
  position: relative;
}
.popover:after {
  display: inline-block;
  font-size: 8px;
  content: '?';
  vertical-align: top;
  margin-left: 10px;
}
.popover:before {
  display: none;
  position: absolute;
  left: 0;
  top: 100%;
  background-color: #000;
  color: #fff;
  content: attr(data-title);
  padding: 5px;
  border-radius: 4px;
}
.popover:hover:before{
  display: block;
}

Здесь внимания заслуживает только вот этот псевдо-элемент .popover:before, а конкретнее строка content: attr(data-title). В не мы указываем, что хотим, чтобы содержимым content нашего :before было значение аттрибута data-titleattr(data-title);

05 декабря 2014
3.9 тыс.
1 мин

JavaScript: изображения в base64, имея только url

Периодически возникает необходимость дать пользователю работать с веб-сайтом / веб-аппом без интернета. Тут на помощь разработчику приходят всякие браузерные хранилища: localStorage, WebSQL, IndexedDB. И если хранить текстовую информацию легко, то как быть с изображениями? Зачастую из API приходит только ссылка на фотографию или картинку. Один из способов конвертировать изображение в base64 и хранить это код, вставляя его потом в аттрибут src нашего тега img. Вот небольшая функция, которая делает такую конвертацию:

function saveImage(url) {
    var img = document.createElement("img");
    img.src = url;
    img.onload = function() {
        var key = encodeURIComponent(url),
            canvas = document.createElement("canvas");

        canvas.width = img.width;  
        canvas.height = img.height;  
        var ctx = canvas.getContext("2d");  
        ctx.drawImage(img, 0, 0);
        localStorage.setItem(key, canvas.toDataURL("image/png"));
    }
}

Она конвертирует изображения в base64-код, используя canvas, затем сохраняет его в localStorage с ключем key. key – это наш адрес изображения (url). Теперь в любой момент мы можем достать нашу картинку из локального хранилища и показать пользователю. Интернет для этого не нужен.

18 ноября 2014
9.2 тыс.
1 мин

Как определить доступен ли интернет, с помощью JavaScript

Иногда возникает необходимость с помощью JavaScript определить online/offline статус. Например, для того, чтобы показывать эту информацию пользователю или загружать какие-то данные из offline-хранилища. Вот как выглядит эта проверка в JS:

if(navigator.onLine) {
    // Устройство в интернете
} else {
    // Устройство не подключено к интернету
}

Это свойство поддерживается всеми современными браузерами кроме Opera Mini.

08 ноября 2014
5.5 тыс.
18 сек

«Аккордеон» для сайта без JavaScript

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

Давайте сделаем наш аккордеон без Javascript на чистом CSS. Как всегда, сначала ДЕМО.

HTML:

    <div class="wrapper clearfix">
        <ul class="accordion clearfix">
            <li>
                <input type="radio" name="accordion" checked="checked" id="id1">
                <label for="id1">Option 1</label>

                <div class="content">
                    1 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
                </div>
            </li>


            <li>
                <input type="radio" name="accordion" id="id2">
                <label for="id2">Option 2</label>

                <div class="content">
                    2 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
                </div>
            </li>


            <li>
                <input type="radio" name="accordion" id="id3">
                <label for="id3">Option 3</label>

                <div class="content">
                    3 Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
                </div>
            </li>
        </ul>
    </div>

Итак, у нас список ul.accordion с тремя элементами. У каждого элемента есть input[type="radio"] для определения отображать контент или нет; label, где мы храним заголовок и div.content с нашим текстом и/или графикой.

CSS:

.wrapper {
    width: 100%;
    min-width: 320px;
}

.clearfix:before, .clearfix:after {
    display: table;
    content: ' ';
}

.accordion {
    list-style: none;
    padding: 0;
    margin: 0;
    display: block;
    position: relative;
}

.accordion li {
    display: block;
}

.accordion li label {
    padding: 10px;
    background-color: #eee;
    display: block;
    font-weight: 700;
    cursor: pointer;
}

.accordion li .content {
    display: none;
    padding: 10px;
}

.accordion li input {
    display: none;
}

.accordion li input:checked ~ label {
    background-color: #fff;
}
.accordion li input:checked ~ .content {
    display: block;
}

Наши инпуты делаем невидимыми, а с помощью input:checked ~ .content показываем только тот контент, input, для которого выбран.

И еще раз ДЕМО.

27 октября 2014
3.3 тыс.
3 мин