0

I have created a list of settings for a certain app. The container for all the settings is a flex element, and the flex direction is set to column. Now, I created a div with the class .option, and put an h2 and a <select>. I set the .option container to display as flex and set the direction to row, but it doesn't work! They stack up!

I tried making the h2 and the <select> inline-blocks, I tried setting the width of each one to 50%, nothing. I will attach a labelled screenshot, plus an html and css snippet of the relevant code.

#SettingsOverlay {
  display: block;
  position: fixed;
  z-index: 3;
  width: 100%;
  height: 100%;
  background-color: rgba(48, 48, 48, 0.7);
  background-size: cover;
}

#SettingsOverlay div {
  width: 80%;
  height: 80%;
  background-color: purple;
  margin: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
}

#Options {
  display: flex;
  flex-direction: column;
}

.option {
  display: flex;
  flex-direction: row;
}

.option h2 {
  display: inline-block;
  width: 50%;
}

.option select {
  display: inline-block;
  width: 50%;
}
<div id='SettingsOverlay'>
  <div>
    <h1>Settings</h1>
    <div id='Options'>
      <div class='option'>
        <h2>Timezone</h2>
        <select>
          <option value="GMT-12">GMT-12</option>
          <option value="GMT-11">GMT-11</option>
          <option value="GMT-10">GMT-10</option>
          <option value="GMT-9">GMT-9</option>
          <option value="GMT-8">GMT-8</option>
          <option value="GMT-7">GMT-7</option>
          <option value="GMT-6">GMT-6</option>
          <option value="GMT-5">GMT-5</option>
          <option value="GMT-4">GMT-4</option>
          <option value="GMT-3">GMT-3</option>
          <option value="GMT-2">GMT-2</option>
          <option value="GMT-1">GMT-1</option>
          <option value="GMT">GMT</option>
          <option value="GMT+1">GMT+1</option>
          <option value="GMT+2">GMT+2</option>
          <option value="GMT+3">GMT+3</option>
          <option value="GMT+4">GMT+4</option>
          <option value="GMT+5">GMT+5</option>
          <option value="GMT+6">GMT+6</option>
          <option value="GMT+7">GMT+7</option>
          <option value="GMT+8">GMT+8</option>
          <option value="GMT+9">GMT+9</option>
          <option value="GMT+10">GMT+10</option>
          <option value="GMT+11">GMT+11</option>
          <option value="GMT+12">GMT+12</option>
        </select>
      </div>
    </div>
  </div>
</div>

Picture of UI not working

  • Setting the display to none for your outermost element seems to defeat the purpose of posting an example – j08691 Mar 06 '19 at 16:31
  • Oh Crap! That was for when you click a button it appears on the website, I forgot to remove that, sorry –  Mar 06 '19 at 16:36
  • Sorry, but I didn't know that the problem was specifity, that is why I didn't find the answers that you guys provided –  Mar 07 '19 at 16:53

4 Answers4

2

Your rule .option is overwritten by #SettingsOverlay div, turn it into #SettingsOverlay > div or increase css specifity of .option using also the parent ID #SettingsOverlay .option

https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

Specificity is the means by which browsers decide which CSS property values are the most relevant to an element and, therefore, will be applied. Specificity is based on the matching rules which are composed of different sorts of CSS selectors.

How is specificity calculated?

Specificity is a weight that is applied to a given CSS declaration, determined by the number of each selector type in the matching selector. When multiple declarations have equal specificity, the last declaration found in the CSS is applied to the element. Specificity only applies when the same element is targeted by multiple declarations. As per CSS rules, directly targeted elements will always take precedence over rules which an element inherits from its ancestor.

#SettingsOverlay {
 /* display: none;*/
  position: fixed;
  z-index: 3;
  width: 100%;
  height: 100%;
  background-color: rgba(48, 48, 48, 0.7);
  background-size: cover;
}

#SettingsOverlay div {
  width: 80%;
  height: 80%;
  background-color: purple;
  margin: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
}

#Options {
  display: flex;
  flex-direction: column;
}

#SettingsOverlay  .option {
  display: flex;
  flex-direction: row;
}

.option h2 {
  display: inline-block;
  width: 50%;
}

.option select {
  display: inline-block;
  width: 50%;
}
<div id='SettingsOverlay'>
  <div>
    <h1>Settings</h1>
    <div id='Options'>
      <div class='option'>
        <h2>Timezone</h2>
        <select>
          <option value="GMT-12">GMT-12</option>
          <option value="GMT-11">GMT-11</option>
          <option value="GMT-10">GMT-10</option>
          <option value="GMT-9">GMT-9</option>
          <option value="GMT-8">GMT-8</option>
          <option value="GMT-7">GMT-7</option>
          <option value="GMT-6">GMT-6</option>
          <option value="GMT-5">GMT-5</option>
          <option value="GMT-4">GMT-4</option>
          <option value="GMT-3">GMT-3</option>
          <option value="GMT-2">GMT-2</option>
          <option value="GMT-1">GMT-1</option>
          <option value="GMT">GMT</option>
          <option value="GMT+1">GMT+1</option>
          <option value="GMT+2">GMT+2</option>
          <option value="GMT+3">GMT+3</option>
          <option value="GMT+4">GMT+4</option>
          <option value="GMT+5">GMT+5</option>
          <option value="GMT+6">GMT+6</option>
          <option value="GMT+7">GMT+7</option>
          <option value="GMT+8">GMT+8</option>
          <option value="GMT+9">GMT+9</option>
          <option value="GMT+10">GMT+10</option>
          <option value="GMT+11">GMT+11</option>
          <option value="GMT+12">GMT+12</option>
        </select>
      </div>
    </div>
  </div>
</div>
Community
  • 1
  • 1
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
0

The reason for the issue is because of the priority of css selectors. IDs take highest priority, followed by classes, attributes and pseudo-classes, then which elements and pseudo-elements.

Your #SettingsOverlay div css selector has a higher priority than both the #Options selector and the .option selector - and because it is impacting all div elements within the id of SettingsOverlay, it is putting a flex-direction of column upon every div.

To fix this, you can add a class to the div (which will reduce it's priority) and use that as a css selector in place of #SettingsOverlay div like the example below.

If you're ever unsure about what priority your css takes, you can use Keegan's Specificity calculator to check.

#SettingsOverlay {
  display: none;
  position: fixed;
  z-index: 3;
  width: 100%;
  height: 100%;
  background-color: rgba(48, 48, 48, 0.7);
  background-size: cover;
}

#Options {
  display: flex;
  flex-direction: column;
}

.option {
  display: flex;
  flex-direction: row;
}

.option h2 {
  display: inline-block;
  width: 50%;
}

.option select {
  display: inline-block;
  width: 50%;
}

.settingsOverlay {
  width: 80%;
  height: 80%;
  background-color: purple;
  margin: auto;
  padding: 10px;
  display: flex;
  flex-direction: column;
}
<div id='SettingsOverlay'>
  <div class="settingsOverlay">
    <h1>Settings</h1>
    <div id='Options'>
      <div class='option'>
        <h2>Timezone</h2>
        <select>
          <option value="GMT-12">GMT-12</option>
          <option value="GMT-11">GMT-11</option>
          <option value="GMT-10">GMT-10</option>
          <option value="GMT-9">GMT-9</option>
          <option value="GMT-8">GMT-8</option>
          <option value="GMT-7">GMT-7</option>
          <option value="GMT-6">GMT-6</option>
          <option value="GMT-5">GMT-5</option>
          <option value="GMT-4">GMT-4</option>
          <option value="GMT-3">GMT-3</option>
          <option value="GMT-2">GMT-2</option>
          <option value="GMT-1">GMT-1</option>
          <option value="GMT">GMT</option>
          <option value="GMT+1">GMT+1</option>
          <option value="GMT+2">GMT+2</option>
          <option value="GMT+3">GMT+3</option>
          <option value="GMT+4">GMT+4</option>
          <option value="GMT+5">GMT+5</option>
          <option value="GMT+6">GMT+6</option>
          <option value="GMT+7">GMT+7</option>
          <option value="GMT+8">GMT+8</option>
          <option value="GMT+9">GMT+9</option>
          <option value="GMT+10">GMT+10</option>
          <option value="GMT+11">GMT+11</option>
          <option value="GMT+12">GMT+12</option>
        </select>
      </div>
    </div>
  </div>
</div>
DKyleo
  • 806
  • 8
  • 11
0

#SettingsOverlay div has a specificity of (1, 0, 1) and .option has a specificity of (0, 1, 0) which means that the flex-direction in #SettingsOverlay div is taking precedence.

You can try changing #SettingsOverlay div to #SettingsOverlay > div, so that it will only be applied to its direct children (rather than anything in it). A best practice to avoid IDs is because of their strong specificity.

See https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity for more information on spcificity.

Shawn Patrick Rice
  • 800
  • 10
  • 17
0

your issue is due to the #SettingsOverlay div which indue unwanted behaviour on all descending div of the main #SettingsOverlay.

if you change the name of this rule, it should word as intended. Plus I add some parameters to the .option div.

#SettingsOverlay {
      /*display: none;*/
      position: fixed;
      z-index: 3;
      width: 100%;
      height: 100%;
      background-color: rgba(48, 48, 48, 0.7);
      background-size: cover;
    }

    #Options {
      width: 80%;
      height: 80%;
      background-color: purple;
      margin: auto;
      padding: 10px;
      display: flex;
      flex-direction: column;
    }

    #Options {
      display: flex;
      flex-direction: column;
    }

    .option {
      display: flex;
      flex-direction: row;
      justify-content: space-between;
      align-items: center;
    }

    .option h2,
    .option select {
     display: inline-block;
     width: 50%;
    }
<div id='SettingsOverlay'>
    <div>
      <h1>Settings</h1>
      <div id='Options'>
       <div class="option">
           <h2>Timezone</h2>


           <select>
             <option value="GMT-12">GMT-12</option>
             <option value="GMT-11">GMT-11</option>
             <option value="GMT-10">GMT-10</option>
             <option value="GMT-9">GMT-9</option>
             <option value="GMT-8">GMT-8</option>
             <option value="GMT-7">GMT-7</option>
             <option value="GMT-6">GMT-6</option>
             <option value="GMT-5">GMT-5</option>
             <option value="GMT-4">GMT-4</option>
             <option value="GMT-3">GMT-3</option>
             <option value="GMT-2">GMT-2</option>
             <option value="GMT-1">GMT-1</option>
             <option value="GMT">GMT</option>
             <option value="GMT+1">GMT+1</option>
             <option value="GMT+2">GMT+2</option>
             <option value="GMT+3">GMT+3</option>
             <option value="GMT+4">GMT+4</option>
             <option value="GMT+5">GMT+5</option>
             <option value="GMT+6">GMT+6</option>
             <option value="GMT+7">GMT+7</option>
             <option value="GMT+8">GMT+8</option>
             <option value="GMT+9">GMT+9</option>
             <option value="GMT+10">GMT+10</option>
             <option value="GMT+11">GMT+11</option>
             <option value="GMT+12">GMT+12</option>
           </select>

        </div>
      </div>
    </div>
  </div>
Dexter0015
  • 1,029
  • 9
  • 14