4

I'm displaying tile numbers using CSS counter and content. I want to display these number at left top corner of the tile. The following code shows it correctly in Chrome but not in FF or IE 11 (haven't checked on other browsers).

What changes do I need in CSS to consistently show the number at left top corner?

Chrome: this is how I want:

Chrome - this is how I want

Firefox: numbers aligned to left ... but not top:

Firefox - numbers aligned to left ... but not top

.tiles {
  /* flex properties as container (tiles level 1, 2 & 3) */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: strech;
  align-content: strech;
  /* flex properties as content (tiles level 2 & 3) */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: strech;
}

.tiles.level1 {
  flex-direction: column;
  flex-grow: 0;
  width: 600px;
  height: 300px;
  counter-reset: tileNum;
}

.tiles.level2 {
  flex-direction: row;
}

.tiles.level3 {
  flex-direction: row;
}

.tiles .title {
  align-self: center;
  font-size: 42px;
}

.tile {
  border: 1px solid black;
  background-color: white;
  width: 1px;
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: auto;
  /* auto = use width & height values if available */
  font-size: 24px;
}

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

.centerContent {
  /* flex-grow: 1;
 flex-shrink: 1;
 align-self: center;*/
}

.tile:before {
  counter-increment: tileNum;
  content: counter(tileNum);
  align-self: flex-start;
  flex-grow: 0;
  font-size: 16px;
}

.tile:after {
  content: ' ';
  align-self: flex-end;
  flex-grow: 0;
  font-size: 16px;
}

.brand {
  text-decoration: underline;
  font-variant: small-caps;
}
<section class="section static">
  <div class="tiles level1">
    <span class="title">
   <span class="brand">So</span>mething
    </span>
    <div class="tiles level2">
      <div class="tiles level3">
        <span class="tile t1 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t2 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
      <div class="tiles level3">
        <span class="tile t3 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t4 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
    </div>
    <div class="tiles level2">
      <div class="tiles level3">
        <span class="tile t5 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t6 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
      <div class="tiles level3">
        <span class="tile t7 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t8 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
    </div>
  </div>
</section>

Note:

  1. I'm using flex box to display tiles and will prefer solution with flexbox only
  2. I'm looking for CSS only solution. (I'm pretty sure that it will be possible but I'm missing out on something related to flexbox properties.)
  3. Nesting of .tiles is needed because: I want to show 4 tiles in a row when page is viewed on PC or mobile in landscape mode but want to show only 2 tiles in a row if viewed on mobile in portrait mode. I'm OK to have some alternative for this.
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Vivek Athalye
  • 2,974
  • 2
  • 23
  • 32

2 Answers2

4

The source of the problem is align-content here:

.centerContainer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    align-content: center; <-- causing the problem
    flex-direction: row;
    flex-wrap: wrap;
}

When you tell the lines in a flex container to be centered, this collapses all extra space, packing all lines in the center of the container. That's what align-content: center does.

So your counter pseudo-element, which the browsers consider a flex item, should not move to the top of the container. The align-self: flex-start you have specified should fail to achieve your goal because the item is confined to the centered flex line, along with its siblings.

So Firefox has this right, in terms of adherence to the spec.

Chrome, as it often does (see here and here for examples), appears to be factoring in logical user behavior to improve the user experience (they call this an intervention).

Anyway, once you remove align-content: center, the stretch default value takes over again, and your flex items can move freely along the entire height of the container.

.tiles {
  /* flex properties as container (tiles level 1, 2 & 3) */
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: strech;
  align-content: strech;
  /* flex properties as content (tiles level 2 & 3) */
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: strech;
}

.tiles.level1 {
  flex-direction: column;
  flex-grow: 0;
  width: 600px;
  height: 300px;
  counter-reset: tileNum;
}

.tiles.level2 {
  flex-direction: row;
}

.tiles.level3 {
  flex-direction: row;
}

.tiles .title {
  align-self: center;
  font-size: 42px;
}

.tile {
  border: 1px solid black;
  background-color: white;
  width: 1px;
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: auto;
  /* auto = use width & height values if available */
  font-size: 24px;
}

.centerContainer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  /* align-content: center; <-- REMOVE */
  flex-direction: row;
  flex-wrap: wrap;
}

.centerContent {
  /* flex-grow: 1;
 flex-shrink: 1;
 align-self: center;*/
}

.tile:before {
  counter-increment: tileNum;
  content: counter(tileNum);
  align-self: flex-start;
  flex-grow: 0;
  font-size: 16px;
}

.tile:after {
  content: ' ';
  align-self: flex-end;
  flex-grow: 0;
  font-size: 16px;
}

.brand {
  text-decoration: underline;
  font-variant: small-caps;
}
<section class="section static">
  <div class="tiles level1">
    <span class="title">
   <span class="brand">So</span>mething
    </span>
    <div class="tiles level2">
      <div class="tiles level3">
        <span class="tile t1 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t2 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
      <div class="tiles level3">
        <span class="tile t3 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t4 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
    </div>
    <div class="tiles level2">
      <div class="tiles level3">
        <span class="tile t5 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t6 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
      <div class="tiles level3">
        <span class="tile t7 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
        <span class="tile t8 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span>
        </span>
      </div>
    </div>
  </div>
</section>

jsFiddle demo

For a more complete explanation, see this post:

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • Thanks for the explanation (+1). This works fine in Firefox. But in IE it still doesn't show the numbers at left top. Any idea how to fix that? – Vivek Athalye Jul 12 '17 at 03:01
  • Which IE? Your question said IE11. I tested [**the code in my answer**](https://jsfiddle.net/t0ygbvxf/2/) in IE11 and it works fine. – Michael Benjamin Jul 12 '17 at 15:30
  • I wonder why I didn't get that version when I have "Install new versions automatically" selected. :( – Vivek Athalye Jul 13 '17 at 16:45
1

You can use absolute positioning for the numbers:

.tiles {
 /* flex properties as container (tiles level 1, 2 & 3) */
 display: flex;
 flex-wrap: wrap;
 justify-content: center;
 align-items: strech;
 align-content: strech;

 /* flex properties as content (tiles level 2 & 3) */
 flex-grow: 1;
 flex-shrink: 1;
 flex-basis: strech;

}
.tiles.level1 {
 flex-direction: column;
 flex-grow:0;
 width: 600px;
 height: 300px;
 
 counter-reset: tileNum;
}
.tiles.level2 {
 flex-direction: row;
}
.tiles.level3 {
 flex-direction: row;
}

.tiles .title {
 align-self: center;
 font-size: 42px;
}

.tile {
 border: 1px solid black;
 background-color: white;
 width: 1px;
 flex-grow: 1;
 flex-shrink: 1;
 flex-basis: auto; /* auto = use width & height values if available */
 font-size: 24px;
 position:relative;
}

.centerContainer {
 display: flex;
 justify-content: space-between;
 align-items: center;
 align-content: center;
 flex-direction: row;
 flex-wrap: wrap;
}
.centerContent {
 flex-grow:1;
 flex-shrink:1;
 align-self:center;
 text-align:center;
}

.tile:before {
 counter-increment: tileNum;
 content: counter(tileNum);
 align-self: flex-start;
 flex-grow:0;
 font-size: 16px;
 position:absolute;
 top:0;
}
.tile:after {
 content: ' ';
 align-self: flex-end;
 flex-grow:0;
 font-size: 16px;
}

.brand {
 text-decoration: underline;
 font-variant: small-caps;
}
  <section class="section static">
 <div class="tiles level1">
  <span class="title">
   <span class="brand">So</span>mething
  </span>
  <div class="tiles level2">
   <div class="tiles level3">
    <span class="tile t1 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
    <span class="tile t2 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
   </div>
   <div class="tiles level3">
    <span class="tile t3 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
    <span class="tile t4 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
   </div>
  </div>
  <div class="tiles level2">
   <div class="tiles level3">
    <span class="tile t5 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
    <span class="tile t6 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
   </div>
   <div class="tiles level3">
    <span class="tile t7 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
    <span class="tile t8 centerContainer"><span class="centerContent"><span class="brand">So</span>mething</span></span>
   </div>
  </div>
 </div>
  </section>
APAD1
  • 13,509
  • 8
  • 43
  • 72
  • This works fine in Firefox. In IE it shows the numbers at left top but distorts the tile layout. Also adds a horizontal scroll .. a huge one. :( – Vivek Athalye Jul 12 '17 at 02:59
  • IE11 only has partial support for flexbox, if you need to support IE, you shouldn't be using flex. – APAD1 Jul 12 '17 at 19:43