user4994625
user4994625

Reputation:

How can I skip the media-query in a Stylus function?

I have a function in Stylus like this:

fn($margin, $padding)
  width 100%
  margin $margin
  padding $padding
  @media (min-width: 500px)
    width 50%
    float left

It works well until I want to use a second media query changing the values of the function:

div
  fn(3px, 5px)
  @media (min-width: 700px)
    fn(6px, 25px)

I get this css:

div {
  width: 100%;
  margin: 3px;
  padding: 5px;
}
@media (min-width: 500px) {
  div {
    width: 50%;
    float: left;
  }
}
@media (min-width: 700px) {
  div {
    width: 100%;
    margin: 6px;
    padding: 25px;
  }
}
@media (min-width: 700px) and (min-width: 500px) {
  div {
    width: 50%;
    float: left;
  }
}

Obviously this is not what I want because the media query of the function overwrites some properties of the new media query.

Would there be any way to skip that part of the function when I call the function from a media query?

EDIT (expand the explanation):

For example a user writes: grid (3, 10px) and a grid of three columns is generated with 10px gutter. That grid is responsive, with less than 500px there is only one column. At the same time the user might want to make their own breakpoints, for example:

div
   grid(3, 10px)
   @media (min-width: 700px)
     grid(4, 20px)

What I want is to keep the media query 500px by default without the user having to define it, so I have put it in the function.

Upvotes: 1

Views: 658

Answers (2)

user4994625
user4994625

Reputation:

I found a solution. It doesn't work with block mixins that I use for media-queries but with media-queries in normal syntax works fine. Just have to use the current-media() function, if empty continue, if not skip de block. That easy :).

Stylus code:

fn($margin, $padding)
  width 100%
  margin $margin
  padding $padding
  if current-media() is ''
    @media (min-width: 500px)
      width 50%
      float left

div
  fn(3px, 5px)
  @media (min-width: 700px)
    fn(6px, 25px)

CSS output:

div {
  width: 100%;
  margin: 3px;
  padding: 5px;
}
@media (min-width: 500px) {
  div {
    width: 50%;
    float: left;
  }
}
@media (min-width: 700px) {
  div {
    width: 100%;
    margin: 6px;
    padding: 25px;
  }
}

Upvotes: 1

thepio
thepio

Reputation: 6263

You could use it like this:

fn($width, $margin, $padding)
  width $width
  margin $margin
  padding $padding
  float: left

@media (min-width: 500px)
  div 
    fn(50%, 3px, 5px)

@media (min-width: 700px)
  div 
    fn(100%, 6px, 25px)

Which will result in the following css:

@media (min-width: 500px) {
  div {
    width: 50%;
    margin: 3px;
    padding: 5px;
    float: left;
  }
}
@media (min-width: 700px) {
  div {
    width: 100%;
    margin: 6px;
    padding: 25px;
    float: left;
  }
}

And even clearer way would be to define the common attributes at first and then use the media queries like this:

fn($width, $margin, $padding)
  width $width
  margin $margin
  padding $padding

div 
  float: left

@media (min-width: 500px)
  div 
    fn(50%, 3px, 5px)

@media (min-width: 700px)
  div 
    fn(100%, 6px, 25px)

EDIT based on your comment:

In the case you mentioned you could use a mixin like this:

media_queries = {
  small  : "(min-width: 500px)",
  medium  : "(min-width: 700px)"
}

for_breakpoint(breakpoints)
  conditions = ()
  for breakpoint in breakpoints
    push(conditions, media_queries[breakpoint])
  conditions = join(", ", conditions)
  @media conditions
    {block}

fn($width, $margin, $padding)
  width $width
  margin $margin
  padding $padding

div
  float left
  +for_breakpoint(small)
    fn(50%, 3px, 5px)
  +for_breakpoint(medium)
    fn(100%, 6px, 25px)

The outcome of this would be:

div {
  float: left;
}
@media (min-width: 500px) {
  div {
    width: 50%;
    margin: 3px;
    padding: 5px;
  }
}
@media (min-width: 700px) {
  div {
    width: 100%;
    margin: 6px;
    padding: 25px;
  }
}

You can obviously add as many breakpoints as you want and you cant even include more statements like for example small : "only screen and (min-width: 500px) and (max-width: 700px)", in your breakpoints.

See it in action: Stylus online editor

Upvotes: 1

Related Questions