13

For a navigation section, I want it to use space-between justification. For smaller displays where the navigation might have to wrap, I'd like the items to center themselves, as opposed to sticking to the left when alone on a row.

nav {
  display: flex;
  width: 100%;
  flex-flow: row wrap;
  justify-content: space-between;
}
<nav>
  <div class='item'>
    Item 1 is alone on its row if the window is small, but is not centered.
  </div>
  <div class='item'>
    Item 2 is very much like item 1.
  </div>
</nav>

Codepen demo: https://codepen.io/anon/pen/MmdOMP?editors=1100#0

Jakob
  • 479
  • 5
  • 12
  • You'll need a media query to accomplish that. https://codepen.io/anon/pen/dWEJqW – Asons May 28 '17 at 18:28
  • I thought of it and it's a workable solution in some cases, but this is for a theme for Hexo (static site generator). A user may have a nav small enough to fit on one row on mobile, or one large enough to not fit in one row on desktop. – Jakob May 28 '17 at 18:31
  • The main problem here is that flexbox containers/items does not know when they break line, hence can't change their behavior based on that. If media query won't do it, you'll need a script executed on a window resize event and manually check if they broke into two lines – Asons May 28 '17 at 18:35
  • Yeah, that's quite true. I'm trying a bit with a separator element between the children. Changing the justification to `space-around`, one can use `flex-grow` on the separator to get the same result in a single-row view, but it sticks on the same row as another element unless it's set to a large width, in which case it breaks the single row view (and still requires an arbitrary width specification). – Jakob May 28 '17 at 18:59
  • 1
    Consider using *space-around* instead of *space-between*. https://stackoverflow.com/a/36487987/3597276 – Michael Benjamin May 28 '17 at 22:21
  • @Michael_B presumably the reason the OP has chosen space-between is because the first non-wrapped element in a row needs to be left-aligned to the margin and the last element in a row needs to be right-aligned. – clayRay Jul 21 '17 at 07:20

2 Answers2

3

There can be 2 solutions from my point of view:

  1. Use CSS media queries or;
  2. JS solution, explained below:

When item is wrapped it takes 100% width, what you need to do is to check on window resize event the width of the item, and if it is 100% relative to the parent element that means it was wrapped, you can add a class at this point and remove it when the statement is false:

function justifyCenter() {
    var navWidth = $("nav").width();
    var itemWidth = $(".item:first-child").width();

    if (navWidth === itemWidth ) {
        $("nav").addClass('justify-center');
    } else {
        $("nav").removeClass('justify-center');
    }
}

Codepen demo: https://codepen.io/anon/pen/WzgpLw

Ursu Alexandr
  • 308
  • 3
  • 8
0

LGSon's comment makes sense to me, but presumably OP wants the ability to modify dynamic text that may or may not fit in a container, regardless of flexbox config or media query.

Look into JS that detects line wraps, then triggers an action (e.g. centering the text).

For example: https://github.com/xdamman/js-line-wrap-detector

Or, JS that automatically resizes text to fit within a container. Useless for all kinds of situations.

For example: http://www.fittextjs.com

Kalnode
  • 9,386
  • 3
  • 34
  • 62