0

I have many varied cases where I would like a DIV containing an inline-block menu element - typically an anchor - to act as if vertically justifying the elements, when an element overflows on to multiple lines.

I will use one example case to explain what I would like to achieve:

See my codepen: http://codepen.io/anon/pen/wBRpqJ?editors=110

Output: Image 1 - 100% width

What happens is that if the browser resizes to a smaller size, then the final inline-block Anchor element falls down onto a new line, see screenshot (at width ~725px):

Output: image 2 - 725px width

That's fine, in itself, but what I would like it to do is to split the elements within the DIV equally, as it's on two lines, to then be equally dispersed over two lines and therefore be roughly justified, If you resize the codepen to approximately 500px wide you will see how I'd like it to look if the elements can not all stay on one line. So the image below would be would I would like to see if any line breaking occurs within the parent DIV element.

Output:

image 3 - desired layout format

I realise that the term equally is an exact term for an inexact situation but to justify the elements in a block so that each row in the block has the same number of elements +/- 1 (for odd counts).

Is this something that can be done with CSS?

P.S> The contents of these elements are dynamic and varied and the situations any solution would be useful for would also be dynamic and varied so solutions specifically for this case will probably not help.

Edit: Flexbox has been suggested as a solution, how would I use Flexbox to achieve the desired result?

Edit 2: Criteria -- The elements in the menu are centre aligned and are each separate inline-blocks . Justifying them all it does is screw up the centre alignment and add extra spacer lines around the Anchor elements in the NAV container.

Edit 3: I will put my code here, used on the codepen example:

CSS:

.mainbox {
        width:90%;
        max-width:1200px;
        min-width:400px;
        margin:0.4em auto;
        font-family: Arial, Helvetica, sans-serif;
        font-size: 1em;
        border: 1px solid #006;
    }

nav {
    background-color: rgba(204,204,204,0.4);
    padding:5px 5px 0px 5px;
    text-align:center;
    position: absolute;
    /* bottom increased from zero to make example clearer on codepen */
  bottom:1em;
    margin:auto;
    width:90%; 
  /* width adjusted from 100% for codepen layout */
}
nav a {
    font-size: 0.9em;
    font-weight: bold;
    text-decoration: none;
    padding:2px 4px;
    color: #000;
    border: 1px solid #000;
    line-height: 1.1em;
    background-color: #DDDDDD;
    margin:0 3px 3px 3px;
    display:inline-block;
}
nav a:hover, nav a:focus {
    background-color: #FFFFFF;
    color:#000000;
    text-decoration: none;
}

HTML:

<div class="mainbox">
  <header>
  <nav>
           <a href="#cal" title="Cottage Availbility">Availability</a>
<a href="#tariff" title="Tariff">Tariff</a>
<a href="#" title="Make A Booking ">Make A Booking</a>
<a href="http://www.website.com/AccessStatement.pdf" title="Access Statement" target="_blank">Access Statement</a>
<a href="http://www.website.com/TandCs.pdf" title="T&amp;Cs" target="_blank">T&amp;Cs</a>
<a href="#contact" title="Contact the owners">Contact</a>
<a href="http://www.elsewhere.co.uk" title="Visit the website">
Parent Site</a>
        </nav>
  </header>
  </div>
Stickers
  • 75,527
  • 23
  • 147
  • 186
Martin
  • 22,212
  • 11
  • 70
  • 132
  • 1
    Have you tried flexbox? – Chrillewoodz Mar 20 '15 at 17:15
  • Is flexbox fairly straightforward to implement? No, I've not heard of flex box :-( – Martin Mar 20 '15 at 17:16
  • I've only used it once to try it out and it can be a bit tricky at first but from what I've seen on complete examples you can do exactly what you're looking for with it. – Chrillewoodz Mar 20 '15 at 17:17
  • @Chrillewoodz I am reading about flexbox, it is additional rules for CSS? I was about to ask for an example to get started but see your second comment – Martin Mar 20 '15 at 17:19

4 Answers4

2

You have to use the :after pseudo element hack. Basically it works like you're justifying text. In order to get the last line to justify, you have to force a fake line using :after to get the browser to justify the last line. Just think about how justify works, it never justifies the last line.

.menu {
  margin: 0;
  padding: 0;
  text-align: justify;
  font-size: 0;
}
li {
  display: inline-block;
  font-size: 24px;
  width: auto;
  background-color: #ccc;
  text-align: center;
  padding: 0 10px;
  border: 1px solid black;
  margin:10px;
}
ul:after {
  display: inline-block;
  width: 100%;
  content: '';
}
<ul class="menu">
  <li>Item 12341231</li>
  <li>Item 123462346</li>
  <li>Item 234523</li>
  <li>Item 34563457</li>
  <li>Item 456756</li>
  <li>Item 567856</li>  
  <li>Item 678969</li>
  <li>Item 7453456</li>
  <li>Item 8234523</li>
</ul>
Jeff
  • 2,293
  • 4
  • 26
  • 43
  • Sorry Jeff, this solution doesn't work for me, it adds spacing around the elements within the container and does not *vertically* justify them. – Martin Mar 20 '15 at 17:33
1

One trick might be to use media queries:

@media (max-width: 725px) {
    .parent-div {
        width: 500px;
    }
}

Not perfect, but setting these will wrap everything just the way you want it.

beautifulcoder
  • 10,832
  • 3
  • 19
  • 29
  • I have tried this approach the thing is there is a shading background on the menu that would need to stay in place so I would need to put a DIV in the NAV. media queries and manual adjustments are an option but I was looking for a more elegant solution. Thanks though. – Martin Mar 20 '15 at 17:27
  • @Chrillewoodz's recommendation above might be the more elegant approach. I haven't delved too deep into flexbox myself. Good luck! – beautifulcoder Mar 20 '15 at 17:30
  • I would like to learn more about flexbox, it may be the solution. Cheers Beautifulcoder. – Martin Mar 20 '15 at 17:33
1

This workaround is also based on @media, but using a pseudo element to make line break.

@media screen and (max-width: 750px) {
    nav span:nth-of-type(4)::after {
        content: "";
        display: table;
        height: 10px;
    }
}

Note: I added a <span> tag around each <a> in order to make it happen.

Demo: http://jsfiddle.net/s88381hb/1/

Stickers
  • 75,527
  • 23
  • 147
  • 186
  • cheers, does it have to apply to an inline element, hence has to be a span rather than the anchors? – Martin Mar 20 '15 at 18:44
0

You can use CSS to do this but you can use javascript to enforce the CSS whichmight be more beneficial