Responsive

Magento UI library provides a strong approach for working with media queries. It`s based on recursive call of .media-width() mixin defined anywhere in project but invoked in one place in lib/web/css/source/lib/_responsive.less. That's why in the resulting styles.css we have every media query only once with all the rules there, not a multiple calls for the same query.

To see the media queries work resize window to understand which breakpoint is applied.

.example-responsive-block {
    padding: 10px;
}

.media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__m) {
    .example-responsive-block {
        background: #ffc;
    }
    .example-responsive-block:before {
        content: 'Mobile styles ';
        font-weight: bold;
    }
}

.media-width(@extremum, @break) when (@extremum = 'min') and (@break = @screen__m) {
    .example-responsive-block {
        background: #ccf;
    }
    .example-responsive-block:before {
        content: 'Desktop styles ';
        font-weight: bold;
    }
}

Responsive mixins usage

For grouping style rules in certain media queries .media-width() mixin used.

 .media-width(<@extremum>, <@break>);

@extremum: max|min - sets whether to use min-width or max-width in media query condition
@break: value - sets the value of breakpoint to compare with in media query condition.
For example

  .media-width(@extremum, @break) when (@extremum = 'max') and (@break = @screen__s) {
      your styles
  }

It will be complied to

  @media only screen and (max-width: 640px) {
      your styles
  }

 

Media query style groups separation variables

@media-common: true|false - sets whether to output common styles. For common styles every time you want to add some styles you should use

  & when (@media-common = true) {
      your styles
  }

@media-target: all|desktop|mobile - Sets target device for styles output

  & when (@media-target = 'mobile'),
  (@media-target = 'all') {
     @media only screen and (max-width: (@screen__xs - 1)) {
         .media-width('max', @screen__xs);
     }
 }

Gathering

Everything that you include in collector mixins above will go in place where they declarated. As example all

  .media-width(@extremum, @break) {
      your code
  }

Will go to

  .media-width(@extremum, @break));

By default you can find it _responsive.less file in li  

Responsive breakpoints

In Magento UI library there are predefined variables for breakpoints.

  @screen__xxs: 320px;
  @screen__xs: 480px;
  @screen__s: 640px;
  @screen__m: 768px;
  @screen__l: 1024px;
  @screen__xl: 1440px;

 

"+a.textContent):g=m,f.setAttribute("src",g);var i=function(){f.contentDocument.body.innerHTML=this.value,h(f,"getHeight")};a.addEventListener("keypress",i),a.addEventListener("keyup",i),a.parentNode.insertBefore(d,a)},p=function(a){var b=document.createElement("div");b.className="preview-code",b.style.position="absolute",b.style.left="-9999px",j.appendChild(b);var c=parseInt(window.getComputedStyle(a).getPropertyValue("max-height"),10),d=function(a){b.textContent=this.value+"\n";var d=b.offsetHeight+2;d>=c?this.style.overflow="auto":this.style.overflow="hidden",this.style.height=b.offsetHeight+2+"px"};a.addEventListener("keypress",d),a.addEventListener("keyup",d),d.call(a)},q=function(){var b=j.getElementsByClassName("settings")[0],c=j.getElementsByClassName("resizeable"),d=30,e=function(b){document.cookie="preview-width="+b,a(c,function(a){b==="auto"&&(b=a.parentNode.offsetWidth),a.style.width=b+"px",h(a.getElementsByTagName("iframe")[0],"getHeight")})},i=f(document.cookie)["preview-width"];if(i){e(i),g(b.getElementsByClassName("is-active"),"is-active");var k=b.querySelector('button[data-width="'+i+'"]');k&&k.classList.add("is-active")}window.addEventListener("message",function(a){if(a.data==null||!a.source)return;var b=a.data,c=document.getElementsByName(a.source.name)[0];b.height!=null&&c&&(c.parentNode.style.height=b.height+d+"px")},!1),b&&c.length>0&&(b.hidden=!1,b.addEventListener("click",function(a){var c=a.target.tagName.toLowerCase(),d;if(c==="button")d=a.target;else{if(c!=="svg")return;d=a.target.parentNode}a.preventDefault(),g(b.getElementsByClassName("is-active"),"is-active"),d.classList.add("is-active");var f=d.dataset.width;e(f)}))}}()})()