Position an element in CSS relative to two other elements

Can an element be positioned horizontally in relation to one element and vertically to another using only CSS? I am attempting to include a dropdown menu in my navbar. However, the submenu is not aligning correctly. I want to position element A so that its left edge aligns with element B's left edge, but I want element A's top edge to align with element C's bottom edge.

In essence, I want it positioned under the header, aligned with a list element (image edited):

I have the following code:

#header{
  padding: 0.125em;     
  background: #eee;         /* Styling for clarity */
}
nav{
  display: inline;          /* Makes nav inline */
}
h1{
  display: inline;          /* Makes the main title inline */
}
#header ul{
  padding:0;                /* Clears the space around the list */
  display: inline;          /* Makes lists inline */
}
#header li{
  display: inline;          /* Makes list items inline */
  list-style-type: none;    /* Removes bullets */
}
#header ul>li>.submenu>li{
  display: block;           /* Makes submenu list items behave normally */
}
#header ul>li>.submenu{
  display: none;            /* Hides the submenu */
  position: absolute;       /* Enables positioning */
  top: 100%;                /* Position directly under - SHOULD BE UNDER HEADER */
  left: 0;                  /* Align left edge - SHOULD BE ALIGNED WITH ANCESTOR LIST ITEM */
  background: #ccc;         /* Styling for clarity */
}
#header ul>li:hover>.submenu{
  display: block;           /* Shows the submenu */
}
<header id="header">
  <nav>
    <ul>
      <li>
        <a>
          <h1>
            <img>TITLE
          </h1>
        </a>
      </li>
      <li>
        <a>PAGE</a>
      </li>
      <li>
        <a>PAGE</a>
        <ul class="submenu">
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
        </ul>
      </li>
      <li>
        <a>PAGE</a>
      </li>
    </ul>
  </nav>
</header>

To achieve the desired positioning, I need to select the element relative to which the positioning will be done. However, if I do this with the list element, the submenu will be too high up because it is positioned under the list element, and the header has some padding.

#header li {
    position: relative; /* Positioning will be relative to the ANCESTOR LIST ITEM */
}

#header{
  padding: 0.125em;     
  background: #eee;         /* Styling for clarity */
}
nav{
  display: inline;          /* Makes nav inline */
}
h1{
  display: inline;          /* Makes the main title inline */
}
#header ul{
  padding:0;                /* Clears the space around the list */
  display: inline;          /* Makes lists inline */
}
#header li{
  display: inline;          /* Makes list items inline */
  list-style-type: none;    /* Removes bullets */
  position: relative;       /* Positioning will be relative to the ANCESTOR LIST ITEM */
}
#header ul>li>.submenu>li{
  display: block;           /* Makes submenu list items behave normally */
}
#header ul>li>.submenu{
  display: none;            /* Hides the submenu */
  position: absolute;       /* Enables positioning */
  top: 100%;                /* Position directly under - SHOULD BE UNDER HEADER */
  left: 0;                  /* Align left edge - SHOULD BE ALIGNED WITH ANCESTOR LIST ITEM */
  background: #ccc;         /* Styling for clarity */
}
#header ul>li:hover>.submenu{
  display: block;           /* Shows the submenu */
}
<header id="header">
  <nav>
    <ul>
      <li>
        <a>
          <h1>
            <img>TITLE
          </h1>
        </a>
      </li>
      <li>
        <a>PAGE</a>
      </li>
      <li>
        <a>PAGE</a>
        <ul class="submenu">
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
        </ul>
      </li>
      <li>
        <a>PAGE</a>
      </li>
    </ul>
  </nav>
</header>

This is the result: aligned with list element

If I use the header as the reference for positioning, the submenu will align with the left of the entire header, which is not what I desire.

#header {
    position: relative; /* Positioning will be relative to the HEADER */
}

#header{
  padding: 0.125em;     
  background: #eee;         /* Styling for clarity */
  position: relative;       /* Positioning will be relative to the HEADER */
}
nav{
  display: inline;          /* Makes nav inline */
}
h1{
  display: inline;          /* Makes the main title inline */
}
#header ul{
  padding:0;                /* Clears the space around the list */
  display: inline;          /* Makes lists inline */
}
#header li{
  display: inline;          /* Makes list items inline */
  list-style-type: none;    /* Removes bullets */
}
#header ul>li>.submenu>li{
  display: block;           /* Makes submenu list items behave normally */
}
#header ul>li>.submenu{
  display: none;            /* Hides the submenu */
  position: absolute;       /* Enables positioning */
  top: 100%;                /* Position directly under - SHOULD BE UNDER HEADER */
  left: 0;                  /* Align left edge - SHOULD BE ALIGNED WITH ANCESTOR LIST ITEM */
  background: #ccc;         /* Styling for clarity */
}
#header ul>li:hover>.submenu{
  display: block;           /* Shows the submenu */
}
<header id="header">
  <nav>
    <ul>
      <li>
        <a>
          <h1>
            <img>TITLE
          </h1>
        </a>
      </li>
      <li>
        <a>PAGE</a>
      </li>
      <li>
        <a>PAGE</a>
        <ul class="submenu">
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
        </ul>
      </li>
      <li>
        <a>PAGE</a>
      </li>
    </ul>
  </nav>
</header>

This is how it appears: under header

Therefore, I aim for "top: 100%;" to be related to the whole header and "left: 0;" to be linked to the list element where the submenu is nested.

I hope my inquiry was comprehensible. Since this is my first question here, I apologize for any limitations regarding images or additional links due to lack of reputation.

Thank you for taking the time to consider my question. I look forward to a prompt resolution!

Answer №1

Check out the code snippet here: http://jsfiddle.net/td6Las4x/

To improve the layout, simply include "position:relative" in the styling for "#header", eliminate "left:0" from "#header ul > li > .submenu", and remove "display: inline-block;" from "#header li"

#header li {
    display: inline-block;
}

Answer №2

If you want to position the .submenu relative to the header, you can utilize the behavior of left: auto.

In this scenario, the .submenu will be an absolutely positioned element with all its properties like left, width, and right set to auto.

According to §10.3.7,

When 'left', 'width', and 'right' are all set to 'auto': Begin by setting any 'auto' values for 'margin-left' and 'margin-right' to 0. Then, if the 'direction' property of the containing block is 'ltr', set 'left' to the static position and apply further rules.

The static position is defined as

The static position for 'left' refers to the distance from the left edge of the containing block to the left margin edge of a hypothetical box that would have been the first box of the element if its 'position' was 'static' and 'float' was 'none'. This value is negative if the hypothetical box would be to the left of the containing block.

If we remove position: absolute and analyze:

#header{
  padding: 0.125em;     
  background: #eee;         
  position: relative;       
}
nav{
  display: inline;          
}
h1{
  display: inline;          
}
#header ul{
  padding:0;                
  display: inline;          
}
#header li{
  display: inline;        
  list-style-type: none;    
}
#header ul>li>.submenu>li{
  display: block;           
}
#header ul>li>.submenu{
  display: none;            
  position: static;
  top: 100%;                
  background: #ccc;         
}
#header ul>li>.submenu{
  display: block;           
}
<header id="header">
  <nav>
    <ul>
      <li>
        <a>
          <h1>
            <img>TITLE
          </h1>
        </a>
      </li>
      <li>
        <a>PAGE</a>
      </li>
      <li>
        <a>PAGE</a>
        <ul class="submenu">
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
          <li><a>PAGE</a></li>
        </ul>
      </li>
      <li>
        <a>PAGE</a>
      </li>
    </ul>
  </nav>
</header>

With these changes, the .submenu will now be in the desired static position for the left side.

To summarize, by setting display: inline-block for #header li and resetting left: auto for #header ul > li > .submenu, you can achieve the intended layout.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Preventing blank text entries in a task management application

Is there a way to determine if the text input provided by the user is empty or contains some text? I'm in the process of developing a TO-DO app and I'd like it so that if a user fails to enter anything into the text area and clicks on "add", the ...

How can I display pure HTML in a Pyramid view?

I am completely new to Pyramid (and relatively inexperienced with web frameworks in general). My goal is to reach a point where I can retrieve raw HTML from a view in order to format data fetched from my mongoDB database. The __init__.py in my Pyramid pr ...

The mysterious behavior of HTML 5 causing images to mysteriously add a 3px margin at the

Whenever I update my website to <!DOCTYPE HTML> Each img element enclosed within a DIV mysteriously acquires a 3px bottom margin, even though no CSS rule defines it. To clarify, there are no style attributes responsible for this 3px bottom margin. & ...

Implementing a Collapse and Expand All feature within an Accordion Component

Hey there! I've been attempting to implement a Collapse All feature on my accordion but am having trouble figuring it out. The resource I've been referencing is this one. I've searched around and noticed that this accordion setup is a bit d ...

Why does my CSS attribute selector fail to update when the property's value changes?

Context: I'm working on a React-based web app that utilizes traditional CSS loaded through an import statement. In order to create a slider functionality, I have applied a CSS selector on the tab index attribute. Challenge: The issue I am facing is t ...

Ways to effectively go through local storage using a loop

I'm currently working on enhancing my navbar by adding links based on searches made by users and their favorite selections. My goal is to avoid duplicate entries in the "past searched" section if the current search already exists in the list. I'm ...

Creating and implementing a HTML template from scratch, devoid of any frameworks

Is there a way to create a quiz where all questions follow the same format and only one question is displayed at a time, without duplicating code? Perhaps using a template would be the ideal solution in this scenario. I appreciate your help. ...

How can I add a drop-down list to a cell within a table?

Can a drop-down list be added into a table cell? Thank you! Here is an excerpt of the code: $sql_query="SELECT nameOfwarning FROM warnings"; $sodss=mysqli_query($d,$sql_query); if (mysqli_num_rows($result)<1) ?> <select name = "warnings"> ...

Is it possible to update an anchor tag using BeautifulSoup directly?

I am aiming to retrieve all anchor tags from an HTML document, regardless of their location or depth within the structure. Once these links have been gathered, I intend to manipulate them and create new links. My goal is to update the original HTML conten ...

Tips for delivering a variable to a React Native Stylesheet

Is there a way to pass a variable to the "shadowColor" property in my stylesheet from an array declared in the code above? I keep encountering a "Can't find name" error. Attempting to use a template literal has not resolved the issue. Any assistance w ...

Adjust the HTML content prior to displaying it to prevent any flickering

Is there a way to run code before the page is rendered, such as updating dates or converting text to HTML, without causing flickering when reloading multiple times? How can I ensure the code runs as it's drawn instead of waiting until the end to redra ...

Align the bottom of an image with the top of text to achieve perfect vertical alignment

My goal is to arrange numerous images in a row, with text displayed below each image. Each block of text may consist of multiple lines and should be centered. While the heights of the images may vary, their widths will remain consistent. It is important th ...

Best Way to Eliminate "#" Symbol from URL Address in UI-Router

My website URL is structured as follows: This is the index page where I utilize Angular UI-Router to navigate to different views, however, the URL retains the hash symbol (#) like this: Query: I am looking for a way to eliminate/remove the hash tag from ...

Creating a dynamic dropdown menu using jQuery animation

I am looking to add animation to my top navigation bar. Currently, the dropdown menus just appear suddenly when hovering over the links in the top nav. Development site: I have attempted the following: <script> jQuery(document).ready(function() { ...

Having trouble with setting an image as a background in CSS for Nativescript on iOS?

In my NativeScript app, I am trying to set an image as the background using the CSS property background-image: url("res://ic_more"). It works perfectly on Android, but unfortunately, it does not display on iOS devices. I have confirmed that the image is l ...

Clicking the save button in the modal updates the text on both the current tab and any previously clicked tabs

I'm looking to implement tabs that, when clicking on the edit icon, open a modal for editing the content of each tab. The issue I'm currently encountering is that if I open the editor for one tab, close it without saving, then open the editor fo ...

Insert text into the cursor location within Summernote using JQuery

Currently, I am working on a flutter application where I have implemented the summernote editor using JQuery. ClipboardData data = await Clipboard.getData(Clipboard.kTextPlain); String txtIsi = data.text .replaceAll("'", '\&bsol ...

Comparing CSS rules: the faster option between specifying multiple IDs or not

Recently, I have been heavily involved in working with Concrete5. It has come to my attention that the default theme contains numerous CSS rules that are defined in this manner: #page #central #sidebar p{line-height:24px} Considering that "sidebar" is an ...

Insert this HTML table along with radio buttons into an Excel spreadsheet

My HTML table contains rows with a variety of content, including plain text characters and elements like radio buttons and lists. I want users to be able to copy-paste the table into MS Excel as plain text and have the radio button values replaced with "c ...

What is the best way to showcase two data frames side by side in an HTML template or webpage without using frames?

Is there a way to showcase two data frames side by side in an html template? <h3> TITLE </h3> {{stat1 | safe}}. {{stat | safe}} I attempted the above solution, but unfortunately it only displays the data frames vertically stacked instead of ...