0

Most guides recommend designing mobile first. I.e. adding css-rules for mobile as default and putting tablet/desktop rules into media queries:

.class1 {
   width: 100px
}

@media only screen and (min-width: 800px) {
  .class1 {
     width: 200px
  }
}

the argument there is that mobile design is the simplest one and desktop would just add elements above it most of the time. It made 100% sense for me, until I tried it.
My problem is that I need to hide elements on mobile all the time. So the code ends up like this:

.class2 {
   display: none
}

@media only screen and (min-width: 800px) {
  .class2 {
     display: block
  }
}

and this is very hard to manage, since not always I need display to be block, sometimes it's flex or something else, which can be defined in a completely different class, which I mix with the class, which does the hiding. I.e. I get conflicts all the time, results depends on the order I put my classes into stylesheet, and it's very easy to make a mistake. Since everyone recommends Mobile First I'm sure there is a work around this problem. I.e. a way to hide the element by default (on mobile) and undo the hiding w/o making a conflict. What is this way?

If I simply use unset it unset property in all classes on the element:

    
.flex {
  display: flex;
  background: yellow;
}

.class2 {
  display: none;
  background: red;
}

.class2 {
  display: unset;
}
<div class="class2 flex">I am not flex</div>
<div class="flex">I am flex</div>

Edit: people are asking why I'm using two classes: I do it to separate responsibilities with, BEM. For example, you mix two classes, one is responsible for stuff inside your element (i.e. color, fonts, and whether it is flexbox or block). Another for the position of the element on your page and whether to show it. The class which desides what to do with your element as a whole should not know whether this element uses flexbox or block layout.

klm123
  • 12,105
  • 14
  • 57
  • 95
  • Personally I use JS to handle a lot of my conditional rendering. In the example above, since CSS is read top to bottom, the conflict you're dealing with is that `display: unset;` is the only truth it knows. – DragonInTraining Nov 11 '21 at 09:35
  • Why do you use just a single class to hide stuff on mobile? Top-to-bottom is just how CSS works. Use this for your advantage. – lupz Nov 11 '21 at 09:35
  • @lupz, it's just example, there are a ton of cases where you put two classes on one element. One of them can be responsible for site layout and for hiding elements, another class is responsible for the stuff inside the element and what to define it as flexbox. – klm123 Nov 11 '21 at 09:41
  • But since CSS is read top to bottom, putting two classes on one element is not an issue and there are definitely cases where it has its merits. The issue is that you attempt to handle the same property in both classes in the given example, and because of CSS being read the way it does, the latter one will override any other mentions prior to that. – DragonInTraining Nov 11 '21 at 09:49
  • @DragonInTraining, exactly! so how do you hide an element with Mobile First, without changing it's internal structure and conflicting with display: flex property? Or Mobile First simply doesn't work with BEM, for example? – klm123 Nov 11 '21 at 09:50
  • 1
    I think this might answer your question a bit and I agree with the answer [css vs bem](https://stackoverflow.com/questions/37968973/how-to-structure-css-using-bem-methodology-for-adaptive-web-pages) – DragonInTraining Nov 11 '21 at 10:07

1 Answers1

0

I would do something like this. Creating classes for what you need, say i want my .something hidden on phone we would hide it by default and give it a class like md-flex to become display-flex at breakpoint md (md can be anything you like ofcourse, maybe medium-flex).

this way you dont need to add everything into media queries, just these few classes to handle the display and maybe positions. leaving the queries in the bottom of the css files and working top side of the website == top side in css file works fine. for example

  • header before
  • header
  • header after
  • content
  • sidebar
  • footer before
  • footer
  • footer after

.something {
  display: none;
  background: yellow;
}
/*this could be md for example*/
@media only screen and (min-width: 900px){
  .md-flex{
    display: flex;
  }
  .md-inline{
    display: inline-block;
  }
}
/*this could be lg for example*/
@media only screen and (min-width: 1280px){
  .lg-block{
    display: block;
  }
}
<div class="something md-flex">I am hidden on phone</div>
<div class="something lg-block">I am hidden on phone</div>
<div class="something md-inline">I am hidden on phone</div>
Ramon de Vries
  • 1,312
  • 7
  • 20
  • The problem is that it doesn't really allows you to separate responsibilities. With, BEM, for example, you mix two classes, one is responsible for sutff inside your element (i.e. color, fonts, and whether it is flexbox or block). Another for the position of the element on your page and whether to show it. The class which desides what to do with your element as a whole should not know whether this element uses flexbox or block layout. – klm123 Nov 11 '21 at 09:45
  • well you could make a class like `hide` or `lg-hide` and give it `display: none!important`, that way in the media rule you place it it will just hide it, no matter the display it had before, and if the media rule doesn't apply anymore. it will go back to its original state – Ramon de Vries Nov 11 '21 at 09:50
  • If it's in a media query `!important` is not neccessary as the rule will override the initial value of the property by their sequence of declaration alone. – DragonInTraining Nov 11 '21 at 09:51
  • @RamondeVries, how do you make it work with Mobile first? you write `display: none!important` by default, not in media rules. – klm123 Nov 11 '21 at 09:56