Styling the first item in a css column

I have a list that appears in multiple columns. Each of the elements of the list is a block element (display: block) and has some style attached to it (1px border at the bottom). Currently, it looks like this:

List item List item List item --------- --------- --------- List item List item List item --------- --------- --------- List item List item --------- --------- 

I would like to add an identical border to the top of the first element in each column, for example.

 --------- --------- --------- List item List item List item --------- --------- --------- List item List item List item --------- --------- --------- List item List item --------- --------- 

I tried: first-line and :: first-line, none of which seem to be anything in this instance (perhaps because it doesn't work on block elements?)

The list can vary in length, so I cannot determine how many elements will be in each column, so I can not use user: nth-of-type ().

Does anyone know if this can be done (or vice versa if it definitely cannot?)

My html

 <ul> <li><a href="">List item</a></li> <li><a href="">List item</a></li> <li><a href="">List item</a></li> ... </ul> 

My css

  ul { list-style: none; padding: 21px; -moz-column-count: 4; -webkit-column-count: 4; column-count: 4; -moz-column-gap: 21px; -webkit-column-gap: 21px; column-gap: 21px; } li { display: block; -moz-column-break-inside: avoid; -webkit-column-break-inside: avoid; -mx-column-break-inside: avoid; column-break-inside: avoid; padding: 1em 0; border-bottom: 1px dotted #000; } 
+7
css
source share
4 answers

Change after viewing the code and after 1 hour: DONE! With pure CSS!

It took me a while since I did not want to use javascript. Here is a demo of what is really going on behind the scenes http://jsfiddle.net/mEtF6/1/ , and here's the working version: http://jsfiddle.net/mEtF6/2/ . If you do not understand anything, do not hesitate to ask about it, as it is not very well documented. I had to actually add a div wrapping 'ul' because overflow: hidden on ul will not behave as border-top is outside the element. This is the working code:

 <div> <ul> <li><a href="">List item 1</a></li> <li><a href="">List item 2</a></li> <li><a href="">List item 3</a></li> <li><a href="">List item 4</a></li> <li><a href="">List item 5</a></li> <li><a href="">List item 6</a></li> <li><a href="">List item 7</a></li> <li><a href="">List item 8</a></li> <li><a href="">List item 9</a></li> </ul> </div> 

And css:

 div { /* This will hide the white space at the right (blue in the explanation) */ overflow: hidden; } ul { position: relative; /* Needed to place the :before pseudo element in the proper position */ list-style: none; border-top: 1px dotted #000; padding: 0; margin: 0; -moz-column-count: 4; -webkit-column-count: 4; column-count: 4; -moz-column-gap: 20px; -webkit-column-gap: 20px; column-gap: 20px; } /* This 'cuts' the top margin of ul so it displayed in the same way as the other */ ul:before { content: " "; position: absolute; display: block; width: 100%; height: 1px; /* Put the gaps on the <ul> top margin */ top: -1px; /* Background-size = 1/4 of the width + 1/4 of the space between columns */ background-size: calc(25% + 5px) 1px; /* Or it will hide the border-top of the ul */ background-color: transparent; /* The actual white gaps at the top */ background-image: linear-gradient( 90deg, transparent calc(100% - 20px), /* All the <li> width minus the gap is transparent */ red 20px); /* Those 20px are white */ } li { -moz-column-break-inside: avoid; -webkit-column-break-inside: avoid; -mx-column-break-inside: avoid; column-break-inside: avoid; padding: 0; border-bottom: 1px dotted #000; } /* This will hide the top margin of the last columns without elements */ li:last-child:before { position: absolute; /* You want to place the top */ margin-left: calc(25% + 5px); content: " "; display: block; background-color: blue; width: 10px; height: 1px; top: -1px; width: 100%; } /* Make the <a> fill the whole space of the <li> */ li a { display: block; padding: 1em 0; } 

Note. I added the correct support for <a> tags, making the entire block clickable, and not just the text inside it. You can cancel it.

Note 2: tested only with FIREFOX . You may need to add some other -webkit gradients to make it a cross browser. Sorry, but I will leave this dirty work to you (; . I found an obvious error and asked a question here in SO about this .

Working demo again: http://jsfiddle.net/mEtF6/2/ .

+4
source share

add border-top: 1px dotted #000; margin-bottom: -1px; border-top: 1px dotted #000; margin-bottom: -1px; in your style li

fiddle

+3
source share

If the same ul that are associated with multiple columns, and the number of elements in the columns may vary. Then I see no way to do this. Not with CSS at least.

I would make the columns a fixed number of elements and use :nth* pseudo selector or split the columns into different ul tags and create the first li .

If you want to use jQuery or the like, you can focus on the first li , find its top and iterate over others, and if the position is top , add a border.

Edit

This JSFiddle is one solution, but it uses jQuery:

http://jsfiddle.net/8ZRkG/

With four columns: enter image description here

With three columns: enter image description here

+2
source share

The way to use the CSS3 multi-column model is to create a new type of container between the content and the content called the column column .

Unfortunately, the current specification clearly indicates:

Cannot set properties / values โ€‹โ€‹in columns. For example, the background of a specific column cannot be set, and the column field has no concept of padding, margin, or border.

Therefore, at the moment there is no selector for column columns or elements inside, although on the same page there is a possibility that such a thing may be included in the future (why they did not think to include it in the present specification, outside of me).

Since you are claiming that you cannot edit the output on the server side, you need to use Javascript. I see that one solution already offers, although I do not agree with the approach to calculating the top position of li:first-child . Instead, I suggest the following:

 var liNum = $('ul.columns li').length; // This computes the number of list items var colNum = 4; // This is the number of columns you want $('ul.columns li').each(function(i) { if ( i % Math.ceil(liNum/colNum) === 0 ) { $(this).addClass('top'); } }); 

Working demo

Of course, this is a little longer, but does not rely on the calculated top position (which is a visual property) or on li is :first-child . Instead, it relies on the number of items that are on the list, which in my opinion is an important number.

Of course, this assumes that you know how many columns you have (as you said, you do). If you want to not rely on this piece of information, you can simply calculate what CSS is instead:

 var colNum = $('ul.columns').css('column-count') 

Also, if you just want to add a border to the top and donโ€™t want to style something, I would probably edit css directly through .css() instead of adding a class. If you need to customize the top element for more styles or other purposes (e.g. JS), I would add a class. But this is really a matter of preference.

+1
source share

All Articles