Pixeltramp
Pixeltramp

Reputation: 197

Is there a CSS method to style only the first row of wrapping elements?

Say you have a responsive-width container full of inline-block elements. Some of these elements hit the edge of the container and drop to new lines. This is great! ...Unless for some reason you want to apply style rules to only the FIRST line of the elements.

http://jsfiddle.net/nshdnazw/1/

HTML

<div class="container">
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div> 
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
  <div class="thinger"></div>
</div>  

CSS

.container {
  width: 50%;
  background-color: #ababab;
}

.thinger {
  display: inline-block;
  background-color: #666666;
  width: 100px;
  height: 100px;
  margin-top: 10px;
  margin-right: 10px;
}

In the fiddle above, say for instance I want the top line of items to be slightly darker, or I wanted to remove the top margin. I could apply a negative margin to the container, but then the container moves. It's a hack instead of a fix. I can't think of a CSS solution for changing the color, though.

Text has a solution, using the ::first-line pseudoselector. Is there a similar method for inline blocks?

Upvotes: 4

Views: 417

Answers (3)

Rick Hitchcock
Rick Hitchcock

Reputation: 35670

Here's a solution using your existing HTML.

It moves the default background color to a ::before pseudo element, and the background for the first row to an ::after pseudo element.

See code comments for explanation.

.container {
  width: 50%;
  background-color: #ababab;
  position: relative;
  z-index: -2;        /* behind pseudo elements */
}

.thinger {
  width: 100px;
  height: 100px;
  margin-top: 10px;
  margin-right: 10px;
  display: inline-block;
  vertical-align: top;
}

.thinger::before, .thinger::after {
  content: '';
  display: block;
  position: absolute;  /* positioned relative to .container */
  z-index: -1;         /* to prevent covering any text */
  width: 100px;        /* same width as .thinger */
  height: 100px;       /* same height as .thinger */
}

.thinger::before {
  background: #666;    /* default background */
}

.thinger::after {
  top: 10px;           /* top row only  (.thinger's margin-top is 10px.)  */
  background: brown;   /* background of top row only */
}

Fiddle

Upvotes: 3

Chaphasilor
Chaphasilor

Reputation: 51

I don't think there isn't any way CSS could check for elements wich have a specific position, so my best CSS solution, that could fit for your problem, is to just change the background color in the section of the first line. For example take an empty div-element, scale it up so it covers the whole first row/line (width is responsive too of course) and fix its position above the first row. Now you can simply work with the z-index and background color to make a fixed or absolute, colored underlayer for the first line.

Something like this (z-index sadly don't seem to work):

.container {
  width: 50%;
  background-color: #ababab;
}

.thinger {
  background-color: #666666;
  width: 100px;
  height: 100px;
  margin-top: 10px;
  margin-right: 10px;
  display: inline-block;
  z-index: 2;
}

div.background {
  position: absolute;
  top: 15px;
  left: 8px;
  width: 48%;
  height: 105px;
  background-color: #98bf21;
  z-index: 1;
}
 <div class="background"></div>

<div class="container">
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
  <span class="thinger">
  </span>
</div>  

PS: You know that if you put text in the boxes they move around?

Upvotes: 0

c-smile
c-smile

Reputation: 27470

Even CSS has ::first-line pseudo-element you cannot style elements contained in first line. That's because contained elements are children of the container but not that first-line pseudo-element.

Upvotes: 2

Related Questions