Dropping middle flex item

When browser window is resized (reduced) and when content is reached (width of menu links (no media queries)) , menu links div should go below header (and then menu div should have width=100%)…

Picture will explain best:


HTML structure should not be changed because of keyboard tabbing (or if changed - tabbing should go from LOGOTYPE to MENU LINKS and then to ICONS)… Maybe flex is not solution? Please no javascript, no tables…

HTML

<div class="wrapper">
    <div class="logo"><a href="">LOGOTYPE</a></div> 
        <div class="menu"><a href="">MENU-LINK-1</a> <a href="">MENU-LINK-2</a> <a href="">MENU-LINK-3</a>
        </div>
    <div class="icons"><a href="">ICONS</a></div>
</div>

CSS

.wrapper {
    height: 60px;
    display: flex;
    background-color: #4f3cbd;
    max-width: 900px; 
    flex-wrap: wrap;
}
.logo {
    flex: 0 0 200px; /* do not grow, do not shrink, 200px */
    height: 60px; 
    line-height: 60px; 
    position: relative; 
    text-align: center;
    background-color: #a292be;
}
.menu {
    flex: 1; 
    height: 60px; 
    line-height: 60px; 
    position: relative; 
    text-align: center; 
    background-color: #4eda49; 
}
.icons {
    flex: 0 0 200px; 
    height: 60px;
    line-height: 60px;
    position: relative; 
    text-align: center;
    background-color: #c77a7a;
}

ONLINE CODEPEN LINK

Thanx in advance

Hi there skulptron,

here is a possible solution…

<!DOCTYPE HTML>
<html lang="en">
<head>

<meta charset="utf-8">
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">

<title>Untitled document</title>

<!--
The internal CSS should be transferred to an external file
<link rel="stylesheet" href="screen.css" media="screen">
-->

<style media="screen">
body {
    background-color: #f0f0f0;
    font: normal 1em / 1.5em sans-serif;
 } 
.wrapper {
    display: grid;
    grid-template-rows: [first] 3.75em;
    grid-template-columns: [first] 12.5em auto 12.5em;
    grid-template-columns: [second] 1;
    background-color: #4e2ec0;
 }
.wrapper div {
    line-height: 3.75em;
    text-align: center;
 }
.logo {
    background: #a090bf;
 }
.menu{
    background: #72dc3c;
 }
.icons {
    background: #be7a7b;
 }
@media ( max-width:47em ) {
.logo{
    grid-column-start: 1;
    grid-column-end: 2;	
  }
.icons{
    grid-column-start: 3;
    grid-column-end: 4;	
  }
.menu {
    grid-column-start: 1;
    grid-column-end: 4 ;
    grid-row-start: row2-start;
    grid-row-end: 3;	
  }	
 }
@media ( max-width:26em ) {
.wrapper {
    grid-template-columns: [first] 50% auto 50%;	
  }
 }
</style>

</head>
<body>

 <div class="wrapper">
  <div class="logo">
  	<a href="">LOGOTYPE</a>
  </div> 
  <div class="menu">
  	<a href="">MENU-LINK-1</a> 
  	<a href="">MENU-LINK-2</a> 
  	<a href="">MENU-LINK-3</a>
  </div>
  <div class="icons">
  	<a href="">ICONS</a>
  </div>
</div>

</body>
</html>

You can also view it here…

https://codepen.io/coothead/full/JjErrjO

coothead

2 Likes

Mr. Coothead I really appreciate your effort and I would not like to be ungrateful, but I mentioned that this should be achieved without media queries … Maybe that note did not turn out to be the clearest? My english is poor.
Thanks a lot for the help.
Also, I forgot to mention that the wrapper must have a max-width.

Let me know what else you believe could trigger the required change? :rofl:

Add this to .wrapper code

max-width: 50em; /* adjust to suit */
margin: auto;

coothead

1 Like

My first thoughts are that you won’t be able to do this without changing the order of the html which means you’d have to set the tabbing order manually.

If you change the order of the html then you can do something like this.

However you would still need a media query when you get down to 400px wide so that you can break the menu into smaller pieces.

There are probably other ways using the re-arranged html but that was my first try.

I don’t believe you can achieve what you want without using media queries and even if it can be done it will require some trickery and magic number fixes that will most likely render it fragile.

I’d probably stick with something like @coothead has already shown. :slight_smile:

2 Likes

Thax PaulOB, that’s what I was hoping could be achieved.
As for media queries, this is just part of the menu functionality I making and applies to large viewport devices … For small viewport devices I use media queries for the hamburger menu.

When I complete the code, I will post a link on the forum so that you can rate it and give suggestions for improvements.

Now, I still have to find a solution for re-arranged HTML. As far as I have read tabindex positive value is not recommended.

Once again, I apologize for the insufficiently explained question.

Please explain, what needs to be solved?

Flex can re-order how content appears, which won’t change the order that the elements are actually in, in the document, so should not change the tab order. Though you will need a query to trigger a change for different screens.

4 Likes

Just for fun and if you don’t mind nesting the logo in a div then you can achieve the effect without needing to directly set the tab order as the html will be in logical tabbing order.

I’m not seeing any other solution that doesn’t involve changing the order of the html or using media queries. There indeed may be a solution but I’m just not seeing it :slight_smile:

2 Likes

Yes you did, I just mended your solution a bit to keep the div order:

<!DOCTYPE HTML><html lang="en"><head><meta charset="utf-8">
<title>Title</title>
<meta name="viewport" content="width=device-width,height=device-height,initial-scale=1">
<style>
.wrapper {
    max-width: 900px; 
    position: relative;
    background-color: #4f3cbd;
    text-align: center; 
}
.wrapper:before {
    float: right;
    width: 200px;
    height: 60px; 
    content: "";
}
.logo {
    float: left;
    width: 200px;
    height: 60px; 
    background-color: #a292be;
    line-height: 60px; 
}
.menu {
    display: table;
    background-color: #4eda49; 
    line-height: 60px;
    white-space: nowrap;
}
.menu a {
    display: table-cell;
    width: 1%;
}
.icons {
    position: absolute;
    top: 0;
    right: 0;
    width: 200px;
    height: 60px; 
    background-color: #c77a7a;
    line-height: 60px;
}
</style>
</head><body>

 <div class="wrapper">
    <div class="logo"><a href="">LOGOTYPE</a></div> 
    <div class="menu"><a href="">MENU-LINK-1</a> <a href="">MENU-LINK-2</a> <a href="">EXTRA-LONG-MENU-LINK-3</a></div>
    <div class="icons"><a href="">ICONS</a></div>
</div>

</body></html>

Flex-box, too fancy, I resorted to the old table-cell width trick to get the menu links spaced even.

3 Likes

How did I miss that :slight_smile:

Thanks Erik.

2 Likes

As per Erik’s comments I have updated the previous codepen to lose the nested div so the html is untouched from the original now. :slight_smile:

4 Likes

Yes I find it funny that even in 2021 we are using tricks from 2001 to achieve layouts that grid and flexbox still can’t do. :slight_smile: Grid and flexbox are great but they are still rigid and block orientated. More thought should have gone into the behaviour that people want and use (e.g. selecting which item should wrap when the page is squeezed). Some of the simplest things are still impossible to achieve in a cross browser way. :slight_smile:

3 Likes

Totally agree. :slight_smile:

Though in my example, the table-cell width trick could be replaced with a flex-box justify-content: space-around;

2 Likes

I am very grateful to you PaulOB, Erik_J, SamA74, coothead, you helped me find a solution that I would never have been able to do on my own (and I have been looking for it for days). I hope that your efforts will also benefit to other forum visitors …

The solution that fits into the navigation menu I am making is the following:

CODEPEN

CSS

.wrapper {
  position: relative;
  display: block;
  margin: auto;
  max-width: 1100px;
  min-height: 60px;
  background-color: #4f3cbd;
}
.logo {
  position: relative;
  float: left;
  width: 200px;
  min-height: 60px;
  line-height: 60px;
  text-align: center;
  background-color: #a292be;
}
.menu {
  display: flex;
  min-width: max-content;
  text-align: center;
  background-color: #4eda49;
  justify-content: center;
}
.menu a {
  min-height: 60px;
  line-height: 60px;
  margin: 0 8px;
}
.iconmask {
  position: relative;
  float: right; 
  width: 200px;
  min-height: 60px;
  line-height: 60px;
  background-color: #ffffff;
}
.icons {
  position: absolute;
  top: 0;
  right: 0;
  width: 200px;
  min-height: 60px;
  line-height: 60px;
  text-align: center;
  background-color: #c77a7a;
}

HTML

<div class="wrapper">
    <div class="logo"><a href="">LOGOTYPE</a></div>
    <div class="iconmask">mask</div>
    <div class="menu"><a href="">MENU-LINK-1</a> <a href="">MENU-LINK-2</a> <a href="">MENU-LINK-3</a> <a href="">MENU-LINK-4</a> <a href="">MENU-LINK-5</a></div>
    <div class="icons"><a href="">ICONS</a></div>
  </div>

PaulOB, your previous link

CODEPEN

in Firefox does not display as in Chrome … Does my Firefox have an error or …?

Best wishes

On my box, Firefox 84.0.2 display exactly as Chromium 87.0.4280, both Linux versions. Viewport and zoom resized.

What difference do your Firefox display?

2 Likes

Yes mine seem to look the same as well unless I’m missing something :slight_smile:

1 Like

I’v checked on my son PC, there everything is OK… I suppose I have some bad add-on on my Firefox…

Thanx for help… I must refresh my Firefox.

1 Like

I think you have set like 120% zoom in that screenshot.

Try press Ctrl+0 and report back. :thinking:

2 Likes

:rofl: :+1:

1 Like