# Breakpoints
Переменные-брекпоинты лучше называть более интуитивно-понятно.
~/src/stylus/utils/_variables.styl
// Breakpoints
//////////////////////////////////////////////////////
$breakpoints = {
tablet: 768px,
desktop: 1025px,
}
$breakpoints["mobile--max"] = $breakpoints.tablet - 1
$breakpoints["tablet--max"] = $breakpoints.desktop - 1
WARNING
Основные точки перехода: в стилевой базе препроцессора в px
и в константах скриптов библиотеки в Number
- должны соответствовать друг-другу.
@/src/utils/сonstants.js
// Design constants
//////////////////////////////////////////////////////
export const DESIGN = {
BREAKPOINTS: {
tablet: 768,
desktop: 1025,
},
};
В препроцессоре - мощнейшее, очень удобное средство - построенные на брекпоинтах примеси принимающие контент:
// 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}
Использование в любом блоке стилей SFC:
.selector
+$desktop()
// styles only for desktops
+$tablet()
// styles only for tablet
+$mobile()
// styles only for mobile
TIP
В строгой традиции запрещается использование любых глобальных классов со стилями, за исключением анимаций для Vue и вынужденных кастомизаций действительно необходимых сторонних модулей где «классический ад с !important
»))). Мы стараемся минимизировать количество зависимостей и «точечно» закрываем самые «дорогие», неподъемные по ресурсам проблемные места.
Точки перехода скриптов обрабатываются специальным модулем-помощником для экрана через matchMedia:
@/src/utils/screen-helper.js
// Viewport utils module
//////////////////////////////////////////////////////
import { DESIGN } from './constants.js';
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';
};
const getPixelRatio = () => {
// eslint-disable-next-line prettier/prettier
return (
window.devicePixelRatio ||
window.screen.deviceXDPI / window.screen.logicalXDPI
);
};
return {
isMobile,
isTablet,
isDesktop,
getOrientation,
getPixelRatio,
};
})();
export default ScreenHelper;
Для того чтобы компоненты могли всегда верно определять типоразмер устройства предоставлена общая функциональность обновляющая переменные в событии ресайза. Этот миксин может быть невероятно полезен и на этапе конечной сборки адаптивных видов - в дочерних проектах.
@/src/mixins/resize.js
import ScreenHelper from '../utils/screen-helper.js';
export default {
data() {
return {
isMobile: null,
isTablet: null,
isDesktop: null,
};
},
mounted() {
window.addEventListener('resize', this.onWindowResizeCommon, false);
this.onWindowResizeCommon();
},
beforeDestroy() {
window.removeEventListener('resize', this.onWindowResizeCommon, false);
},
methods: {
onWindowResizeCommon() {
// console.log('onWindowResizeCommon!!!!');
this.isMobile = ScreenHelper.isMobile();
this.isTablet = ScreenHelper.isTablet();
this.isDesktop = ScreenHelper.isDesktop();
},
},
};
На любых компонентах или видах в библиотеке:
<template>
<Component v-show="isDesktop" />
<div v-if="isDesktop" />
</template>
<script>
import resize from '../../../src/mixins/resize.js';
export default {
name: 'ComponentName',
mixins: [resize],
};
</script>
В проектах:
<script>
import resize from 'ui-library-starter/src/mixins/resize.js';
export default {
name: 'Test',
mixins: [resize],
};
</script>
Test component:
<template>
<div>
<div>Responsive Stylus mixins test:</div>
<div class="visible--desktop">The block is visible only on desktops</div>
<div class="visible--tablet">The block is visible only on tables</div>
<div class="visible--mobile">The block is visible only on mobiles</div>
<br />
<div>Resize javasript mixin test:</div>
<div v-if="isDesktop">The block is present in the DOM only on desktops</div>
<div v-if="isTablet">The block is present in the DOM only on tablets</div>
<div v-if="isMobile">The block is present in the DOM only on mobiles</div>
</div>
</template>
<script>
import resize from '../../../../src/mixins/resize.js';
export default {
name: 'TestBreakpoints',
mixins: [resize],
};
</script>
<style lang="stylus" scoped>
@import "~/src/stylus/_stylebase.styl";
.visible
&--desktop,
&--tablet,
&--mobile
display none
&--desktop
+$desktop()
display block
&--tablet
+$tablet()
display block
&--mobile
+$mobile()
display block
</style>
← Colors Typography →