Breakpoints

Переменные-брекпоинты лучше называть более интуитивно-понятно.

~/src/stylus/utils/_variables.styl

// Breakpoints
//////////////////////////////////////////////////////

$breakpoints = {
  tablet: 768px,
  desktop: 1025px,
}
$breakpoints["mobile--max"] = $breakpoints.tablet - 1
$breakpoints["tablet--max"] = $breakpoints.desktop - 1
1
2
3
4
5
6
7
8
9

WARNING

Основные точки перехода: в стилевой базе препроцессора в px и в константах скриптов библиотеки в Number - должны соответствовать друг-другу.

@/src/utils/сonstants.ts

// Design constants
//////////////////////////////////////////////////////

export const DESIGN = {
  BREAKPOINTS: {
    tablet: 768,
    desktop: 1025,
  },
};
1
2
3
4
5
6
7
8
9

В препроцессоре - мощнейшее, очень удобное средство - построенные на брекпоинтах примеси принимающие контент:

// Media
//////////////////////////////////////////////////////

$no-gadgets()
  @media only screen and (max-width $breakpoints.desktop--max)
    {block}

$desktop()
  @media only screen and (min-width $breakpoints.desktop)
    {block}

$gadgets()
  @media only screen and (max-width $breakpoints.tablet--max)
    {block}

$tablet()
  @media only screen and (min-width $breakpoints.tablet) and (max-width $breakpoints.tablet--max)
    {block}

$not-mobile()
  @media only screen and (min-width $breakpoints.tablet)
    {block}

$mobile()
  @media only screen and (max-width $breakpoints.mobile--max)
    {block}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

Использование в любом блоке стилей SFC:

.selector
  +$desktop()
    // styles only for desktops

  +$tablet()
    // styles only for tablet

  +$mobile()
    // styles only for mobile
1
2
3
4
5
6
7
8
9

TIP

В строгой традиции запрещается использование любых глобальных классов со стилями, за исключением анимаций для Vue и вынужденных кастомизаций действительно необходимых сторонних модулей где «классический ад с !important»))). Мы стараемся минимизировать количество зависимостей и «точечно» закрываем самые «дорогие», неподъемные по ресурсам проблемные места.

Точки перехода скриптов обрабатываются специальным модулем-помощником для экрана через matchMedia:

@/src/utils/screen-helper.ts

// Viewport utils module
//////////////////////////////////////////////////////

import { DESIGN } from './constants';

const ScreenHelper = (() => {
  const TABLET = DESIGN.BREAKPOINTS.tablet;
  const DESKTOP = DESIGN.BREAKPOINTS.desktop;

  const isMobile = () => {
    return window.matchMedia(`(max-width: ${TABLET - 1}px)`).matches;
  };

  const isTablet = () => {
    return window.matchMedia(
      `(min-width: ${TABLET}px) and (max-width: ${DESKTOP - 1}px)`,
    ).matches;
  };

  const isDesktop = () => {
    return window.matchMedia(`(min-width: ${DESKTOP}px)`).matches;
  };

  const getOrientation = () => {
    if (window.matchMedia('(orientation: portrait)').matches) {
      return 'portrait';
    }
    return 'landscape';
  };

  return {
    isMobile,
    isTablet,
    isDesktop,
    getOrientation,
  };
})();

export default ScreenHelper;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

Для того чтобы и компоненты библиотеки и дочерних проектов могли всегда верно определять типоразмер устройства с помощью модуля можно обновлять переменные в событии ресайза (в синтаксисе Options API):

import ScreenHelper from '../utils/screen-helper.ts'; // в компонентах библиотеки
// import ScreenHelper from 'ui-library-starter-2/src/utils/screen-helper.ts'; // в дочерних проектах

export default {
  data() {
    return {
      isMobile: null,
      isTablet: null,
      isDesktop: null,
    };
  },

  mounted() {
    window.addEventListener('resize', this.onWindowResize, false);
    this.onWindowResize();
  },

  beforeDestroy() {
    window.removeEventListener('resize', this.onWindowResize, false);
  },

  methods: {
    onWindowResize() {
      // console.log('onWindowResize!!!!');
      this.isMobile = ScreenHelper.isMobile();
      this.isTablet = ScreenHelper.isTablet();
      this.isDesktop = ScreenHelper.isDesktop();
    },
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
Last Updated:
Contributors: ushliypakostnik