-1

I'm building my NavBar in ReactJS using bootstrap 4.

I would like to take some element at the center of the navbar and others on the right.

In this particular case I would like to have the logout icon on the right.

This is the current situation:

current situation

This is the current code:

render () {
        return (
            <nav className="navbar navbar-dark bg-primary fixed-top">
                <Link className="navbar-brand" to="/">
                    App
                </Link>

                {
                    !localStorage.getItem('token') &&
                    <button className="btn btn-dark" onClick={this.loginClicked}>Login</button>
                }
                {
                    localStorage.getItem('token') &&
                    <div className="mx-auto order-0">
                        <button className="btn btn-primary btn-lg navbar-btn">
                            <i class="fas fa-file-invoice-dollar fa-lg"></i>
                            <sup className="notification-badge"><span class="badge badge-success">1</span></sup>
                        </button>
                        <button className="btn btn-primary btn-lg navbar-btn">
                            <i class="fas fa-envelope fa-lg"></i>
                        </button>
                        <button className="btn btn-primary btn-lg navbar-btn">
                            <i class="fas fa-cogs fa-lg"></i>
                        </button>
                        <button className="btn btn-outline-danger btn-lg" onClick={this.logoutClicked}>
                            <i class="fas fa-sign-out-alt fa-lg"></i>
                        </button>
                    </div>

                }
            </nav>
        );
    }

And this is what I would like to have:

what I want

Dave
  • 1,912
  • 4
  • 16
  • 34
  • 1
    look into flexbox and its justify-content: space-between functionality: https://yoksel.github.io/flex-cheatsheet/#justify-content – DigitalJedi May 19 '19 at 12:52
  • @DigitalJedi I have to use space between also if I need to move only one element to the right (flex-end)? – Dave May 19 '19 at 13:10
  • no you could also do a `justify content: flex-end;`for the right element, but you need to set your parent width then. and have your left items in another parent. – DigitalJedi May 19 '19 at 13:13
  • @DigitalJedi, so with space-between is it simpler (minor changes)? – Dave May 19 '19 at 13:14
  • I have added an answer please accept it if you think it suites your needs. – DigitalJedi May 19 '19 at 13:23
  • @DigitalJedi His/her problem is the `margin: 0 auto` class he/she has added. Bootstrap nav comes with the flex & space-around properties by default - we don't have to overwrite it. – Avanthika May 19 '19 at 13:26
  • 1
    @Avanthika thats why i upvoted your answer, I just wanted to show how stuff is done, even when not relying on the bootstrap css – DigitalJedi May 19 '19 at 13:27
  • okay :) Sounds cool! – Avanthika May 19 '19 at 13:29

3 Answers3

2

Here's what you will have to do:

  1. You don't even have to over-write the flex properties. The bootstrap nav comes with display flex & space-around property by default.
  2. Group your html content as shown - A. navbar-brand B. a parent div that contains the elements you want in the center C. your logout button
  3. Remove the margin auto class(mx-auto order-0) classes from your code. This is the culprit.

Change your react code to:

render() {
  return (
    <nav className="navbar navbar-dark bg-primary fixed-top">
      <Link className="navbar-brand" to="/">
        App
      </Link>

      {!localStorage.getItem("token") && (
        <button className="btn btn-dark" onClick={this.loginClicked}>
          Login
        </button>
      )}
      {localStorage.getItem("token") && (
        <React.Fragment>
          <div className="first-part">
            <button className="btn btn-primary btn-lg navbar-btn">
              <i class="fas fa-file-invoice-dollar fa-lg" />
              <sup className="notification-badge">
                <span class="badge badge-success">1</span>
              </sup>
            </button>
            <button className="btn btn-primary btn-lg navbar-btn">
              <i class="fas fa-envelope fa-lg" />
            </button>
            <button className="btn btn-primary btn-lg navbar-btn">
              <i class="fas fa-cogs fa-lg" />
            </button>
          </div>
          <div className="second-part">
            <button
              className="btn btn-outline-danger btn-lg"
              onClick={this.logoutClicked}
            >
              <i class="fas fa-sign-out-alt fa-lg" />
            </button>
          </div>
        </React.Fragment>
      )}
    </nav>
  );
}

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.min.css" />
<nav class="flex-container navbar navbar-dark bg-primary fixed-top">
    <a class="navbar-brand" to="/"> App
    </a>
    <div class="first-part">
        <button class="btn btn-primary btn-lg navbar-btn">
        <i class="fas fa-file-invoice-dollar fa-lg"></i>
        <sup class="notification-badge"><span class="badge badge-success">1</span></sup>
        </button>
        <button class="btn btn-primary btn-lg navbar-btn">
        <i class="fas fa-envelope fa-lg"></i>
        </button>
        <button class="btn btn-primary btn-lg navbar-btn">
        <i class="fas fa-cogs fa-lg"></i>
        </button>
    </div>
    <div class="second-part">
        <button class="btn btn-outline-danger btn-lg">
        <i class="fas fa-sign-out-alt fa-lg"></i>
        </button>
    </div>
</nav>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
Avanthika
  • 3,984
  • 1
  • 12
  • 19
  • Hi, thanks for the answer. Maybe with ReactJS it is different? Because I can't obtain the same result as yours. In ReactJS I have to wrap `first-part` and `second-part` into an enclosing tag. Doing this I get the logout button on a second row and aligned to the right... – Dave May 19 '19 at 13:28
  • try adding `flex-wrap: nowrap` to your .navbar class – Avanthika May 19 '19 at 13:30
  • Unfortunatly not works... I get two rows aligned to the right. One with first-part and the second one with the logout button :( – Dave May 19 '19 at 13:33
  • This also makes the center icons relative to the width of the other items – Carol Skelly May 19 '19 at 13:44
  • 1
    @JoKeRxbLaCk I got you, you must have used a `
    ` to enclose them into single tag, instead, use `React.Fragment` as shown. I've updated my answer. Just checked in my local too.
    – Avanthika May 19 '19 at 13:49
0

You can use display: flex, and align-content: space-between like so:

.wrapper{
 width: 100%;
}
.mid_to_right{
 padding-left: 50%;
 background-color: red;
 display: flex;
 flex-flow: row nowrap;
 flex-basis: 100%;
 justify-content: space-between;
}

.left{
 display: flex;
flex-flow: row nowrap;
}

.icon{
 width: 50px;
 height: 50px;
 background-color: yellow;
}

.left .icon{
 background-color: green;
}
<div class="wrapper">
  <div class="mid_to_right">
    <div class="left">
      <div class="icon">
      </div>
      <div class="icon">
      </div>
      <div class="icon">
      </div>
    </div>
    <div class="right">
      <div class="icon">
      </div>
    </div>
  </div>
</div>
DigitalJedi
  • 1,577
  • 1
  • 10
  • 29
0

As explained here and here you have to consider the width of adjacent flexbox items to ensure the center content is actually centered in the viewport.

The simplest method using Bootstrap 4 would be to use the w-100 utility classes to ensure the 3 separate flexbox children always fill the width equally, and then align as desired...

<nav class="navbar navbar-dark bg-dark fixed-top navbar-expand">
    <a class="navbar-brand w-100" to="/">
        App
    </a>
    <div class="d-flex">
        <div class="text-nowrap">
            <button class="btn btn-primary btn-lg navbar-btn">
                <i class="fas fa-star fa-lg"></i>
            </button>
            <button class="btn btn-primary btn-lg navbar-btn">
                <i class="fas fa-envelope fa-lg"></i>
                <sup><span class="badge badge-success">1</span></sup>
            </button>
            <button class="btn btn-primary btn-lg navbar-btn">
                <i class="fas fa-cogs fa-lg"></i>
            </button>
        </div>
    </div>
    <div class="w-100 text-right">
        <button class="btn btn-outline-danger btn-lg" onclick="{this.logoutClicked}">
            <i class="fas fa-sign-out-alt fa-lg"></i>
        </button>
    </div>
</nav>

https://www.codeply.com/go/SRy82V3M76

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624