Seleccionar página

SCSS – Extender clases dentro de media queries

Para extender una clase dentro de una media query, el problema con el que nos encontramos es:

.small-btn {
  padding: 5px;
  &:hover {
    background-color: white;
    color:black;
  }
}

@media (max-width: 768px) {
  button {
    @extend .small-btn;
  }
}

Arroja el error

Error: You may not @extend an outer selector from within @media.
       You may only @extend selectors within the same directive.
       From "@extend .small-btn" on line 7 of src/scss/main.scss

Solución:

La respuesta es un  @mixin. Con un @mixin podemos importar todas las las reglas que queramos facilmente. Lo que podríamos hacer es poner el código de la clase que queremos extender, dentro de un @mixin. Entonces, tanto la clase como la sección dentro del mediaquery usarán el @mixin

@mixin small-btn-mixin() {
  padding: 5px;
  &:hover { 
    background-color: white;
    color:black;
  }
}

.small-btn {
  @include small-btn-mixin();
}

@media (max-width: 768px) {
  button {
    @include small-btn-mixin();
  }
}

La limitación es que hay que indicar explícitamente las clases que van a ir tanto dentro del media query como fuera de ella

En definitiva…

En vez de extender @extend, coloca el código que quieras reproducir dentro de un @mixin

 @mixin small-btn-mixin() {
   padding: 5px;
   &:hover {
     background-color: white;
     color:black;
   }
 }

 @media (max-width: 768px) {
   button {
     @include small-btn-mixin();
   }
 }


Agregar breakpoints a BootStrap 4

Las variables de breakpoints deben ser definidas justo antes de llamar a bootstrap.scss:

//Definir previamente las variables que serán usadas en el @import de bootstrap
// Grid breakpoints
//
// Define the minimum dimensions at which your layout will change,
// adapting to different screen sizes, for use in media queries.
 $grid-breakpoints: (
   xxs: 0px,
   xs: 321px,
   sm: 576px,
   md: 768px,
   lg: 992px,
   xl: 1200px,
   xxl: 1440px
 ); //Tener en cuenta que NO LLEVA la palabra reservada !default porque es una variable que predominará sobre la que se defina en "bootstrap" (https://robots.thoughtbot.com/sass-default)

 // Grid containers
 //
 // Define the maximum width of .container for different screen sizes.
$container-max-widths: (
xs: 321px,
sm: 540px,
md: 720px,
lg: 960px,
xl: 1140px,
xxl: 1390px
); //Tener en cuenta que NO LLEVA la palabra reservada !default porque es una variable que predominará sobre la que se defina en "bootstrap" (https://robots.thoughtbot.com/sass-default)
//Importar bootstrap
@import "node_modules/bootstrap/scss/bootstrap";

//Mi código personalizado - overrides
body
{
.....
}

Javascript para logear los Breakpoints

/**
 * Mediaqueries para BS4: https://github.com/JacobLett/IfBreakpoint/blob/master/if-b4-breakpoint.js
 */

// Create global variables that can be used elsewhere

// set variables  
var bs4xxs;
var bs4xs;
var bs4sm;
var bs4md;
var bs4lg;
var bs4xl;
var bs4xxl;
var bs4breakpoint;

// Checks if the span is set to display lock via CSS
function bs4checkIfBlock (target) {
	var target = $(target).css('display') == 'block';
	return target;
}

// function to check the sizes
function bs4checkSize (){
  // Set some variables to use with the if checks below
  bs4xxs = bs4checkIfBlock('.breakpoint-check .xxs');
  bs4xs = bs4checkIfBlock('.breakpoint-check .xs');
  bs4sm = bs4checkIfBlock('.breakpoint-check .sm');
  bs4md = bs4checkIfBlock('.breakpoint-check .md');
  bs4lg = bs4checkIfBlock('.breakpoint-check .lg');
  bs4xl = bs4checkIfBlock('.breakpoint-check .xl');
  bs4xxl = bs4checkIfBlock('.breakpoint-check .xxl');

  var todasClases = 'xxs xs sm md lg xl xxl';

	// add the breakpoint to the console
	if( bs4xxs == true) {
		bs4breakpoint = "xxs";
	} 

	if( bs4xs == true) {
		bs4breakpoint = "xs";
	} 

	if( bs4sm == true) {
		bs4breakpoint = "sm";
	} 

	if( bs4md == true) {
		bs4breakpoint = "md";
	} 

	if( bs4lg == true) {
		bs4breakpoint = "lg";
	} 

	if( bs4xl == true) {
		bs4breakpoint = "xl";
	} 

	if( bs4xxl == true) {
		bs4breakpoint = "xxl";
	} 
	console.log("bs4breakpoint",bs4breakpoint);
	$("body").removeClass(todasClases).addClass( bs4breakpoint );

} 
// end check size

$(document).ready(function(){
 	// Add some invisible elements with Bootstrap CSS visibile utility classes
 	$( "body" ).append( 
 		"<div style='none;' class='breakpoint-check'>"
 		+"<span class='xxs d-block d-xs-inline'>XXS&nbsp</span>"
 		+"<span class='xs d-xs-block d-sm-inline'>XS&nbsp</span>"
 		+"<span class='sm d-sm-block d-md-inline'>SM&nbsp</span>"
 		+"<span class='md d-md-block d-lg-inline'>MD&nbsp</span>"
 		+"<span class='lg d-lg-block d-xl-inline'>LG&nbsp</span>"
 		+"<span class='xl d-xl-block d-xxl-inline'>XL&nbsp</span>"
 		+"<span class='xxl d-xxl-block'>XXL</span>"
 		+"</div>"
 		);

 	bs4checkSize();

 });

// Reload demo on  window resize
$( window ).resize( function(){
	bs4checkSize();
}); 

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Ver
Privacidad