Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Having ".hidden-sm hidden-md" only hides content for medium and not for small devices #8883

Closed
egzplicit opened this issue Jul 31, 2013 · 23 comments

Comments

@egzplicit
Copy link

In 3.0.0-rc1 having an element with the hidden-sm hidden-md classes will only hide it for medium devices and not for small ones as well.

@egzplicit
Copy link
Author

The problem seems to be in responsive-utilities.less, lines 52 and 55 where .hidden-md and .hidden-lg have the .responsive-visibility(); mixin by default. The later media queries apply only for tablets & small desktops and desktops meaning that for mobile phones anything having "hidden-md" and "hidden-sm" at the same time will actually be visible (hidden-sm will apply responsive-invisibility() but the later hidden-md will re-apply responsive-visibility() and the element will become visible).

Either (1) .hidden-lg and .hidden-md should not be declared at all on line 52 and 55 or (2) the order should be swapped so that you have .hidden-lg first, then .hidden-md and .hidden-lg.

I'd go with 1 and just remove the hidden-md and hidden-lg (lines 52 & 55) definitions from the mobile (default) version since they don't actually do anything anyway, apart from causing this bug.

@mattruma
Copy link

mattruma commented Aug 1, 2013

I am seeing this same issue.

@pietheinstrengholt
Copy link

Glad to see that I'm not the only one with this issue. Same problem here as well.

@eratzlaff
Copy link
Contributor

Quick Fix or possible work around.
hidden-sm hidden-md = visible-lg
hidden-sm hidden-lg = visible-md
hidden-md hidden-lg = visible-sm

@mbleigh
Copy link

mbleigh commented Aug 5, 2013

@eratzlaff that's not a workaround, that's the intent as far as I know. I don't think the hidden and visible classes were ever designed to be mixed.

@eratzlaff
Copy link
Contributor

@mbleigh the use of two hidden-* togeter don't work as expected
try it

<div>Using hidden</div>
<div class="hidden-sm hidden-md">hidden-sm hidden-md</div>
<div class="hidden-sm hidden-lg">hidden-sm hidden-lg</div>
<div class="hidden-md hidden-lg">hidden-md hidden-lg</div>
<div>Theoretical equivalent using visible</div>
<div class="visible-lg">hidden-sm hidden-md</div>
<div class="visible-md">hidden-sm hidden-lg</div>
<div class="visible-sm">hidden-md hidden-lg</div>

@mbleigh
Copy link

mbleigh commented Aug 5, 2013

@eratzlaff right, because they aren't meant to be used in combination. The documentation never alludes to being able to apply multiple hidden classes and since there are only three sizes, the visible classes provide the exact same functionality. I'm saying it's not a bug, it's the intent of the library to work this way.

@eratzlaff
Copy link
Contributor

@mbleigh As long there are only three sizes. If you add a 4 size xl or xs this must be fixed.
I think this is an issues but not a big one. Its easy to use the class in another way to have the same result.

@mdo
Copy link
Member

mdo commented Aug 12, 2013

We won't be changing anything here to account for this right now—they're not to be mixed. I'd be open to exploring how to fix this though, but right now I don't see an easy way. These utilities are meant for super quick access to toggling content as-needed. If you need something more advanced, roll your own until an elegant and straightforward solution can be found. I doubt we'll have that for the final v3 though.

@mdo mdo closed this as completed Aug 12, 2013
@eratzlaff
Copy link
Contributor

I think I got the solution for combination of 2 and 3 class together for hidden and visible.
I am not sure if it's elegant.
For example I make something like this.

.visible-lg {
  @media (max-width: @screen-phone-max) {
    .responsive-invisibility();
  }
  &.visible-xs {
    @media (max-width: @screen-phone-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-invisibility();
  }
  &.visible-sm {
    @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-invisibility();
  }
  &.visible-md {
    @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-large-desktop) {
    .responsive-visibility();
  }
}

What do you think about @mdo??
I test it with all kind of combination and its work fine for me.

@eratzlaff
Copy link
Contributor

@mdo If you think it's ok I make the pull request.

@iagdotme
Copy link

We're not far off making this work. There are 8 responsive classes, we just need to add another 6 to give all possibilities. How about this?:

responsive-classes

@eratzlaff
Copy link
Contributor

@iagdotme If you want to cover all the possibilities you need to add another 4 more.
For example:
visible-xs+visible-sm+visible-md I know its equal hidden-lg
This is my complete code for visible and its work for ALL possible combination of visible-*
example use class="visible-xs visible-sm"

.visible-xs {
  @media (max-width: @screen-phone-max) {
  .responsive-visibility();
  }  
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-invisibility();
  }
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-invisibility();
  }
  @media (min-width: @screen-large-desktop) {
    .responsive-invisibility();
  }
}
.visible-sm {
  @media (max-width: @screen-phone-max) {
  .responsive-invisibility();
  }
  &.visible-xs {
    @media (max-width: @screen-phone-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-visibility();
  }
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-invisibility();
  }
  @media (min-width: @screen-large-desktop) {
    .responsive-invisibility();
  }
}
.visible-md {
  @media (max-width: @screen-phone-max) {  
  .responsive-invisibility();
  }
  &.visible-xs {
    @media (max-width: @screen-phone-max) {  
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-invisibility();
  }
  &.visible-sm {
    @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-visibility();
  }
  @media (min-width: @screen-large-desktop) {
    .responsive-invisibility();
  }
}
.visible-lg {
  @media (max-width: @screen-phone-max) {
  .responsive-invisibility();
  }
  &.visible-xs {
    @media (max-width: @screen-phone-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-invisibility();
  }
  &.visible-sm {
    @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-invisibility();
  }
  &.visible-md {
    @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
      .responsive-visibility();
    }    
  }
  @media (min-width: @screen-large-desktop) {
    .responsive-visibility();
  }
}

for hidden its the same idea.
let me know if its work for you.

@iagdotme
Copy link

@eratzlaff I haven't been able to test your code but it seems right.

The reason I listed only 14 classes as that gives you all the possibilities without duplication. There are pros and cons with both approaches. Yours gives you all possibilities of hidden and visible and makes more sense semantically. It does result in more code though. My example cuts down on the amount of code needed.

Personally I prefer your solution, but it's whether simplifying and reducing the amount of code is more important. I do feel implementing a full list of responsive utility classes for BS3 is very important, but I guess it depends where on the scale this lies.

@dstroot
Copy link

dstroot commented Aug 15, 2013

  1. KISS (keep it simpe)
  2. Original proposal by lagdotme is a very good solution
  3. We need some way to hide on smaller devices and show on bigger screens. If I can't double up, eg "hidden-xs" and "hidden-sm" then "hidden-xs-sm" is the way to go.

@turchenkoalex
Copy link

@eratzlaff that's my version of fix for subj with a little bit smaller code. May be useful for you

It's work like in your solution.. We can mix few or more classes of each subgroup (visible or hidden).

Example:

<div class="visible-xs visible-md">Visible on medium and extra small only</div>
<div class="hidden-xs hidden-md">Visible on small and large only</div>

Fix:

.visible-xs,
.visible-sm,
.visible-md,
.visible-lg {
  .responsive-invisibility();
}
.visible-xs {
  @media (max-width: @screen-tablet) {
    .responsive-visibility();
  }
}
.visible-sm {
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-visibility();
  }
}
.visible-md {
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-visibility();
  }
}
.visible-lg {
  @media (min-width: @screen-large-desktop) {
    .responsive-visibility();
  }
}

.hidden-xs,
.hidden-sm,
.hidden-md,
.hidden-lg {
  .responsive-visibility();
}
.hidden-xs {
  @media (max-width: @screen-tablet) {
    .responsive-invisibility();
  }
}
.hidden-sm {
  @media (min-width: @screen-tablet) and (max-width: @screen-tablet-max) {
    .responsive-invisibility();
  }
}
.hidden-md {
  @media (min-width: @screen-desktop) and (max-width: @screen-desktop-max) {
    .responsive-invisibility();
  }
}
.hidden-lg {
  @media (min-width: @screen-large-desktop) {
    .responsive-invisibility();
  }
}

@cloud1250x4
Copy link

@turchenkoalex can you compile a css file please :/ it would be greatly appreciated thank you ;)

@eratzlaff
Copy link
Contributor

@turchenkoalex Great 👍 its work fine. I prefer you code. It much much more easier to understand.
Clean code like @dstroot request.

@iagdotme All combination = 14 👍
the rest are in different order only.

@turchenkoalex
Copy link

@cloud1250000 Yep! It's already compiled and you can get it from https://github.com/TurchenkoAlex/bootstrap/tree/3.0.0-wip/dist/css

@iagdotme
Copy link

This is looking good!

@eratzlaff I was working in binary (my brain is funny like that!) -
0001,0010, 0011, 0100 etc...

@frewsxcv
Copy link

@mdo Why weren't the classes meant to be combined? What if I want something to show up only on mobile devices?

@mdo
Copy link
Member

mdo commented Aug 16, 2013

Punting for a 3.1 release, and tracking as part of #9397.

@evandam
Copy link

evandam commented Dec 23, 2014

Old post, but I recently had this problem and have a quick solution that avoids having to dig into any CSS. Instead of putting multiple .hidden-* classes in one element, make nested elements and assign each one its own class. This probably isn't best practice, but it gets the job done!

<div class="hidden-xs">
    <div class="hidden-sm">
        <span> I'm only visible for medium and large </span>
    </div>
</div>

<div class="hidden-md">
    <div class="hidden-lg">
        <span> I'm only visible for small and extra-small </span>
    </div>
</div>

As far as I can tell, this only behaves as expected with hidden-, not visible-

@twbs twbs locked and limited conversation to collaborators Jan 4, 2015
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests