Selector for the first and last inline-block element on a new line
Asked Answered
C

2

14

I'm trying to build a navigation with dynamic elements which may break onto two lines at small screen sizes, and I'd like to be able to style the first and last elements on each line.

Heres some example scss that breaks at small screen sizes (the rounded corners should be on the first and last element on each line):

<ul>
    <li>First page</li>
    <li>Second page</li>
    <li>Third page</li>
    <li>Fourth page</li>
    <li>Another example page</li>
    <li>This could be the last page</li>
    <li>But its not</li>
    <li>This is actually the last page</li> 
</ul>

ul {
    list-style:none;
    font-size:0px;
    li {
        font-size:18px;
        display:inline-block;
        padding:10px 30px;
        border:1px solid black;
        margin:10px -1px 10px 0;
        &:first-child {
            border-top-left-radius:5px;
            border-bottom-left-radius:5px;
        }
        &:last-child {
            border-top-right-radius:5px;
            border-bottom-right-radius:5px;
        }
    }        
}

With relevent jsfiddle: http://jsfiddle.net/tbw4f23g/1/

Is it possible to get a selector for the first and last inline-block element that runs onto a new line or are there any other (non-javascript) approaches for this effect?

Cyclotron answered 18/12, 2014 at 4:13 Comment(4)
Why can't you use the example that you have provided?Circulate
Can you include your HTML so people can see your syntax? Thanks :)Negligee
@AdityaPonkshe Because :first-child and :last-child refer to the position in the DOM, not the position on the line.Sheree
@torazaburo My bad I didn't understand the question.Circulate
M
7

There is no CSS-only way. I have added the JavaScript solution in your fiddle.

As a workaround, you can assign fixed percentage widths to list items, and use CSS media queries to increase/decrease the widths based on screen size. This way you will know exactly how many items fit on a line which in turn allow you to style specific elements. SASS could make writing repetitive CSS easier. Rough outline (open full page and resize the browser):

ul {
  margin: 0;
  padding: 0;
  list-style-type: none;
}
li {
  float: left;
  box-sizing: border-box;
  margin-bottom: .5em;
  border: thin solid #EEE;
  padding: 1em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background-color: #CEF;
}
li:first-child {
  border-top-left-radius: 1em;
  border-bottom-left-radius: 1em;
}
li:last-child {
  border-top-right-radius: 1em;
  border-bottom-right-radius: 1em;
}
@media (min-width: 600px) and (max-width: 799px) {
  /* 4 items per row */
  li {
    width: 25%;
  }
  /* match 4, 8, 12, ...*/
  li:nth-child(4n+4) {
    border-top-right-radius: 1em;
    border-bottom-right-radius: 1em;
  }
  /* match 5, 9, 13, ... */
  li:nth-child(4n+5) {
    border-top-left-radius: 1em;
    border-bottom-left-radius: 1em;
  }
}
@media (max-width: 599px) {
  /* 3 items per row */
  li {
    width: 33.3333%;
  }
  /* match 3, 6, 9, ... */
  li:nth-child(3n+3) {
    border-top-right-radius: 1em;
    border-bottom-right-radius: 1em;
  }
  /* match 4, 7, 10, ... */
  li:nth-child(3n+4) {
    border-top-left-radius: 1em;
    border-bottom-left-radius: 1em;
  }
}
<ul>
  <li>Praesent ultricies libero</li>
  <li>Aenean in velit vel</li>
  <li>Ut consequat odio</li>
  <li>Integer convallis sapien</li>
  <li>Fusce placerat augue</li>
  <li>Vestibulum finibus nunc</li>
  <li>Nulla consectetur mi</li>
  <li>Ut sollicitudin metus</li>
  <li>Maecenas quis nisl sit</li>
  <li>Vivamus eleifend justo</li>
  <li>Duis ut libero pharetra</li>
</ul>
Mclaurin answered 18/12, 2014 at 6:5 Comment(1)
Is there a way to do it today (in 2017)?Argali
S
4

Is it possible to get a selector for the first and last inline-block element that runs onto a new line or are there any other (non-javascript) approaches for this effect?

No, there are no such selectors. CSS provides no access to information about where lines break (with the limited exception of the :first-line pseudo-element). No, there are no other non-JavaScript approaches for this effect.

If you are willing to use JS, you can iterate over the elements whenever the layout might have changed, examine the position of each vis-a-vis its parent container, judge whether it's up against the left or right side, then apply your border radius.

Another possible JS solution is to perform your own line-breaking calculations by accumulating widths and figuring out where the break must be occurring.

You may want to examine libraries such as Masonry to see if they provide hooks allowing you to access the internal layout configuration, which could make this easier.

Sheree answered 18/12, 2014 at 4:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.