ShellRox
ShellRox

Reputation: 2602

Element width to match horizontal position of other element

Let's say we have a navigation div which contains elements. Below navigation div there is some bar that must expand to the width where it matches one of the navigation elements (3rd one in this case).

<div id="main_navigator">
        <div id="main_navigator_upper">          
            <a id="main_navigator_logo" src="/"></a>
            <ul id="main_navigator_r1">
                <li>
                    <a class="main_nav_btn">BTN 1</a>
                </li>
                <li>
                    <a class="main_nav_btn">BTN 2</a>
                </li>
                <li>
                    <a class="main_nav_btn">BTN 3</a>
                </li>
                <li>
                    <a class="main_nav_btn">BTN 4</a>
                </li>
                <li id="main_navigator_l1">
                    <div id="main_navigator_s1"></div>
                </li>
        <li>
          <ul id="main_navigator_regbox">
            <li>
              <p id="regbox_signin">sign in</p>
            </li>
            <li>
              <div id="main_navigator_regbox_s1"></div>
            </li>
            <li>
              <a id="regbox_signup" href="sign_up">sign up</a>
            </li>
          </ul>
                  </li>
            </ul>
        </div>
        <div id="main_navigator_bottom">
            <div id="main_navigator_progression"></div>
              </div>
    </div>

From this code, main_navigator_progression div must expand its width so it matches BTN 3.

You can see the concept here.


I've written a simple JS code, but it doesn't seem to be neat and doesn't always work:

function initializeProgressorPos() {
    document.getElementById("main_navigator_progression").setAttribute("style", ("width: " + (document.getElementsByClassName("main_nav_btn")[2].getBoundingClientRect().x - document.getElementsByClassName("main_nav_btn")[2].getBoundingClientRect().width) + "px"))
}
initializeProgressorPos();
$(window).resize(function() {
    initializeProgressorPos();
});

Is there any way to create such a function that works even when browser is scaled? What could be wrong with my code? Is there any chance that this can be done with pure css?

Upvotes: 0

Views: 698

Answers (2)

Rounin
Rounin

Reputation: 29453

This is a proof of concept.

You can use a combination of a custom HTML5 data-* attribute and an ::after pseudo-element on your navigation menu (and a dash of javascript) to indicate which menu item you have most recently selected.

Despite the dash of javascript, most of the work is done using CSS.

Working Example:

var menu = document.querySelector('nav ul');
var menuItems = [... menu.getElementsByTagName('li')];

function selectMenu() {

    menu.dataset.selectedMenu = (menuItems.indexOf(this) + 1);

}

for (var i = 0; i < menuItems.length; i++) {

    menuItems[i].addEventListener('click', selectMenu, false);

}
nav ul {
display: flex;
position: relative;
margin: 0;
padding: 0;
}

nav li {
flex: 0 0 60px;
padding: 12px 12px 24px;
color: rgb(255, 255, 255);
background-color: rgb(255, 0, 0);
list-style-type: none;
cursor: pointer;
}

nav ul::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
height: 12px;
background-color: rgba(0, 0, 0, 0.5);
transition: width 0.6s linear;
}

nav ul[data-selected-menu="1"]::after {
width: 80px;
}

nav ul[data-selected-menu="2"]::after {
width: 160px;
}

nav ul[data-selected-menu="3"]::after {
width: 240px;
}

nav ul[data-selected-menu="4"]::after {
width: 320px;
}

nav ul[data-selected-menu="5"]::after {
width: 400px;
}
<nav>
<ul data-selected-menu="1">
<li class="active">Menu 1</li>
<li>Menu 2</li>
<li>Menu 3</li>
<li>Menu 4</li>
<li>Menu 5</li>
</ul>
</nav>

Upvotes: 1

Ali Sheikhpour
Ali Sheikhpour

Reputation: 11045

As you have floatted the element to the right, first you have to get the width of document, then exclude the width from left of document to the right of element from that amount:

function initializeProgressorPos() {
     var elementRight=$(document).width()- $('.main_nav_btn:eq(2)').offset().left - $('.main_nav_btn:eq(2)').width();
    $("#main_navigator_progression").css({"width": elementRight + "px"});
}
    initializeProgressorPos();

$(window).resize(function() {
    initializeProgressorPos();
});
body {
	margin: 0;
	overflow-y: scroll;
}

#main_navigator {
	position: fixed;
	background-color: black;
	width: 100%;
}
#main_navigator_upper {
	position: relative;
	display: flex;
	flex-direction: row;
}
#main_navigator_logo {
	width: 416px;
	height: 120px;
	background-color: white;
}
#main_navigator_r1 {
	display: flex;
	flex-direction: row;
	align-items: center;
	flex-grow: 1;
	flex-shrink: 1;
	padding: 0;
	padding-right: 5%;
	text-align: center;
	margin-top: 0px;
	height: 98px;
	list-style-type: none;
}
#main_navigator_r1 li {
	flex-grow: 1;
	flex-shrink: 1;
	/* flex-basis: 0; */
  flex-basis: auto; /* new */
}
#main_navigator_l1 {
	flex-grow: 0.1 !important;
}
#main_navigator_r1 li .main_nav_btn {
	color: white;
	display: block;
	height: 100%;
	font-family: "nexa_bold";
	font-size: 0.9em;
	text-decoration: none;
}
#main_navigator_s1 {
	display: inline-block;
	width: 2px;
	height: 35px;
	background-color: #B28039;
}
#main_navigator_regbox {
	position: relative;
	display: flex;
	flex-direction: row;
	justify-content: center;
	align-items: center;
	list-style-type: none;
	margin: 0px;
	padding: 0px;
}
#main_navigator_regbox li {
	display: inline-block;
	flex-grow: 0.1;
	flex-shrink: 0.1;
}
#regbox_signin {
	display: block;
	cursor: pointer;
	white-space: nowrap;
	text-decoration: none;
	color: #B28039;
	font-size: 0.9em;
	font-family: "nexa_light";
}
#regbox_signup {
	display: block;
	white-space: nowrap;
	text-decoration: none;
	color: white;
	font-size: 0.9em;
	font-family: "nexa_light";
}
#main_navigator_regbox_s1 {
	display: inline-block;
	width: 1.4px;
	height: 13.5px;
	background-color: white;
}
#main_navigator_bottom {
	background-color: black;
	height: 24px;
}
#main_navigator_progression {
	position: relative;
	background-color: #B28039;
	height: 100%;
	width: 416px;
	float: right;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
    <html lang="en">
    	<body>
    		<div id="main_navigator">
                <div id="main_navigator_upper">          
                    <a id="main_navigator_logo" src="/"></a>
                    <ul id="main_navigator_r1">
                        <li>
                            <a class="main_nav_btn">BTN 1</a>
                        </li>
                        <li>
                            <a class="main_nav_btn">BTN 2</a>
                        </li>
                        <li>
                            <a class="main_nav_btn">BTN 3</a>
                        </li>
                        <li>
                            <a class="main_nav_btn">BTN 4</a>
                        </li>
                        <li id="main_navigator_l1">
                            <div id="main_navigator_s1"></div>
                        </li>
                <li>
                  <ul id="main_navigator_regbox">
                    <li>
                      <p id="regbox_signin">sign in</p>
                    </li>
                    <li>
                      <div id="main_navigator_regbox_s1"></div>
                    </li>
                    <li>
                      <a id="regbox_signup" href="sign_up">sign up</a>
                    </li>
                  </ul>
                          </li>
                    </ul>
                </div>
                <div id="main_navigator_bottom">
                    <div id="main_navigator_progression"></div>
			          </div>
            </div>
    	</body>
    </html>

Upvotes: 1

Related Questions