CSS keep menu in container and expand background to full screen - css

The picture below shows what I would like to get.
It is a menu within a container, where the menu may wrap to multiple lines when the window/screen gets too narrow for all menu items to fit in. At the same time I would like the menu to have a background which expands to full screen in width, while expanding in height with the menu when it gets wrapped to multiple lines. Currently I think this is not possible with CSS, but I am also just a CSS amateur. My current solution involves #media queries to set the height of the menu background for resolutions where wrapping appears. This does not take into account that font-size could change, thus making each line of menu higher.
Here is a jsFiddle with a basic setup, which does NOT what I want:
https://jsfiddle.net/n3jmyq2f/3/ (Edited, was not the final version)
Here is the code:
<div class="container">
<div class="menu_wrap">
<div class="menu_bg"></div>
<div class="menu">
<ul>
<li>item 1</li>
<li>item2</li>
<li>item3</li>
<li>item4</li>
<li>item5</li>
<li>item6</li>
</ul>
</div>
</div>
<div class="content">It's me, Mario!</div>
CSS:
.container {
width:50%;
margin: 0 auto;
background:lightgreen;
height:300px;
}
.menu_bg{
position: absolute;
background: #afafaf;
width: 100%;
left:0;
height:30px;
z-index: -1;
}
ul {
height:30px;
background: #afafaf;
}
li {
display:inline-block;
}

The first option is the simplest.
Stop thinking of the .container as something that must contain everything. It's just a class that can be reused as and when required.
If you take the menu div out of the "container" but put a .container div inside you get the effect you are looking for.
JSfiddle Demo
*,
body {
padding: 0;
margin: 0;
}
.container {
width: 50%;
margin: 0 auto;
background: lightgreen;
}
.menu {
background: #afafaf;
}
ul {
border: 1px solid green;
}
li {
display: inline-block;
}
.content {
height: 300px;
}
<div class="menu">
<div class="container">
<ul>
<li>item 1
</li>
<li>item2
</li>
<li>item3
</li>
<li>item4
</li>
<li>item5
</li>
<li>item6
</li>
</ul>
</div>
</div>
<div class="container">
<div class="content">It's me, Mario!</div>
</div>
2nd Option
Use a pseudo-element
*,
body {
margin: 0;
padding: 0;
}
.container {
width: 50%;
margin: 0 auto;
background: lightgreen;
height: 300px;
}
ul {
background: #afafaf;
position: relative;
border: 1px solid green;
}
ul:before {
content: '';
position: absolute;
height: 100%;
background: inherit;
width: 100vw;
left: 50%;
transform: translateX(-50%);
z-index: -1
}
li {
display: inline-block;
}
<div class="container">
<div class="menu">
<ul>
<li>item 1
</li>
<li>item2
</li>
<li>item3
</li>
<li>item4
</li>
<li>item5
</li>
<li>item6
</li>
</ul>
</div>
<div class="content">It's me, Mario!</div>
</div>
JSfiddle Demo

if in .container you change
width:50%;
to
width:100%;
it will do it
fiddle
you could also use the .menu-wrap class (which I've seen in your markup) to do this

Related

css: sort divs/lis into two columns

Suppose there are two kinds of elements, let's say words and numbers. They should be sorted into two columns. For the example I'm using listitems, but I don't mind changing to divs or something else if that helps.
<div id="container">
<ul>
<li>foo</li>
<li>bar</li>
<li class="num">1</li>
<li class="num">2</li>
<li>baz</li>
</ul>
</div>
Right now I'm achieving this somewhat by using margins, with the following css:
#container {
width: 500px;
margin: auto;
}
li {
float: left;
width: 200px;
background-color: #eee;
margin-bottom: 2px;
margin-right: 300px;
}
.num {
float: right;
margin-right: 0px;
margin-left: 300px;
}
resulting in
http://jsfiddle.net/he13vug4/
What would be a more elegant way to achieve this?
How could I make the numbers "start" (in terms of vertical position) already besides "bar" or even "foo"? (The next word should, however, only start below the numbers). That is, I'd like
or
instead of
They should be sorted into two columns, side by side
Do you need support for older browsers? If not, CSS Grid could help you
Result
#container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-auto-flow: dense;
gap: 10px;
width: 500px;
margin: auto;
list-style: none;
}
li {
background-color: #eee;
}
.word {
grid-column: 1;
}
.num {
grid-column: 2;
}
<ul id="container">
<li class="word">foo</li>
<li class="word">bar</li>
<li class="num">1</li>
<li class="num">2</li>
<li class="word">baz</li>
</ul>
And same code on JSFiddle
Use only left floating and play with clear and margin like below:
#container {
width: 500px;
margin: auto;
}
ul {
list-style:none;
}
li {
float: left;
width: 200px;
background-color: #eee;
margin-bottom: 2px;
}
li + li:not(.num) {
clear:both;
}
li + li.num {
margin-left:10px;
}
li.num + li.num {
margin-left:210px;
}
<div id="container">
<ul>
<li>foo</li>
<li>bar</li>
<li class="num">1</li>
<li class="num">2</li>
<li>baz</li>
<li>baz</li>
<li class="num">1</li>
<li class="num">2</li>
<li class="num">3</li>
<li>baz</li>
<li>baz</li>
</ul>
</div>

How to display an element behind a fixed parent?

Illustrated: how to display a logo contour (children of logo) behind a menu background?
The logo is part of a centered menu but not necessarily at the middle (depends of menu item names), so for me best solution is to still the contour inside the logo div like this:
<img src="background-image.jpg">
<div class="menu">
<ul>
<li>Menu 1</li>
<li>Menu 2</li>
<li>
<div class="logo">
<div class="contour"></div>
</div>
</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
</div>
What I have:
What I want:
I have browsed dozens of solutions for similar issues offered on stackoverflow but none seems to fit… At this point, I tried to set z-index, to move div.contour out of div.logo, to set .contour as pseudo-class :before or :after, to set a position: absolute for .contour or to play with overflow: hidden. Is there a CSS solution (without using JS)?
JSFiddle Sample here
My preferred solution would be working with one background SVG for the dark and light green shape and the orange contour. That background would be centered via CSS.
That whole "contour partially around two different shaped elements" looks to me undoable with normal browser (perhaps some mask magic via CSS...)
Well, you could always trick it, adding first a before pseudoelement to hide the top part of your circle and then add after pseudoelement to cover your circle with another one without border.
like this:
* {
position: relative;
}
body {
width: 100%;
margin: 0;
padding: 0;
}
.menu {
width: 100%;
height: 50px;
position: fixed;
top: 0;
background: darkcyan;
border-bottom: 5px solid orange;
text-align: center;
z-index: 99;
}
.menu ul li {
display: inline-block;
margin: 0 10px;
vertical-align: top;
}
.logo {
width: 100px;
height: 100px;
border-radius: 100px;
background: cadetblue;
}
.anotherclass:before {
content:"";
display:block;
background-color:darkcyan;
height:50px;
width:110px;
position:absolute;
top: -16px;
left: -5px;
}
.anotherclass:after {
content:"";
display:block;
background-color:trasparent;
width: 100px;
height: 100px;
border-radius: 100px;
background: cadetblue;
position:absolute;
top:0px;
left:0px;
}
.contour {
border: 5px solid orange;
left: -5px;
top: -5px;
z-index: -1;
}
<img src="https://images.freeimages.com/images/large-previews/0b3/burning-tree-1377053.jpg" width="100%">
<div class="menu">
<ul>
<li>Menu 1</li>
<li>Menu 2</li>
<li>
<div class="logo anotherclass">
<div class="logo contour"></div>
</div>
</li>
<li>Menu 3</li>
<li>Menu 4</li>
</ul>
</div>
Notice I added another class to your html as you have 2 "logo" classes (parent and child). You may correct this if you like.
If you have problems with the image of your logo now, you could place it trough background-image as a property in the after pseudoelement or if you use html <img> z-index should work probably fine to place it above after pseudoelement.

Mouseenter event on parent when a child is absolute positioned

I'm tring to make a simple drop-down menu, which would be triggered on hover event over some element and stay active as long as the cursor is over that element or is over the dropdown list.
Sample code:
HTML
<div class="header">
<div class="items">
<div class="item">
<span>Caption</span>
</div>
<ul class="items_hidden">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
</div>
<input type="text">
CSS
.items {
float: right;
position: relative;
}
.item {
text-align: right;
}
.items_hidden {
display: none;
margin-top: 7px;
list-style: none;
z-index: 2000;
width: 80px;
border: 1px solid #f2f2f2;
text-align: left;
padding: 10px;
color: #333;
line-height: 30px;
border-bottom: 3px solid #f2f2f2;
}
input {
width: 100%;
}
JS
$(function() {
$('.items').on('mouseenter', function(e) {
$('.items_hidden').show();
});
$('.items').on('mouseleave', function(e) {
$('.items_hidden').hide();
});
});
I got that working, when the dropdown list is positioned relative, but the problem is once the list is displayed, it causes all following content to move down.
Here is an example: https://jsfiddle.net/2ya06aLo/
Another way would be to position the list absolute, so it wouldn't affect the content below. But in that case the list disappears as soons as I move the cursor out of 'Caption' (in contrast with the first fiddle).
Here is the second example https://jsfiddle.net/8L6ojqLm/
What would be a solution to make the list behave like in 1 and at the same time do not affect the rest of the content like in 2 ?
You can don't use JS
Example
.items {
float: right;
position: relative;
}
.item {
text-align: right;
padding: 10px;
}
.items_hidden {
position: absolute;
right: 0;
top: 20px;
display: none;
margin-top: 7px;
list-style: none;
z-index: 2000;
width: 80px;
border: 1px solid #f2f2f2;
text-align: left;
padding: 10px;
color: #333;
line-height: 30px;
border-bottom: 3px solid #f2f2f2;
}
input {
width: 100%;
}
.items:hover .items_hidden{
display: block;
}
<div class="header">
<div class="items">
<div class="item">
<span>Caption</span>
</div>
<ul class="items_hidden">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
</div>
<input type="text">
Live JSFiddle - https://jsfiddle.net/grinmax_/8L6ojqLm/1/
Couldn't it be done via pure css?
https://www.w3schools.com/howto/howto_css_dropdown.asp
Maybe this would help.
.navigation {
width: 100%;
}
.mainmenu, .submenu {
list-style: none;
padding: 0;
margin: 0;
}
.mainmenu a {
}
.mainmenu a:hover {
background-color: #D90000;
}
.mainmenu li:hover .submenu {
display: block;
max-height: 400px;
}
.submenu{
max-height: 400px;
}
.submenu a {
background-color: #FF4D4D;
}
.submenu a:hover {
background-color: #D90000;
}
.submenu{
overflow:hidden;
display:none;
}
<nav class="navigation"><!-- pocetak navigacije -->
<ul class="mainmenu">
<li>Link</li>
<li class="start">Link
<ul class="submenu">
<li>Link</li>
<li>Link</li>
<li>Link</li>
</ul>
</li>
<li>Home</li>
</ul>
</nav>
To take up the comment of CBroe: The problem seems to be the "gap" between the and the element. To remove it you could either
give the "item"-Element a height so that it "reaches down" to the ul-element or
or remove the margin-top of the ul-element

How to lay my nav bar over image? [duplicate]

This question already has answers here:
Position text over image
(4 answers)
Closed 6 years ago.
I am trying to lay my lay my nav bar (#media min width 50em) over my my mainimage. I have tried using mainimage as a background url to my navbar but it I cannot adjust the height. Is there a way to just push mainimage to the top of page and have my nav bar lay over the top of it?
Here is a link to my jsfiddle:
https://jsfiddle.net/shannonhart82/93ekqmhq/1/
<nav>
<ul>
<li>About </li>
<li>Menu</li>
<li><img class="logo" src="fjc.svg"></li>
<li>Gallery</li>
<li>Contact</li>
</ul>
</nav>
<img class="mainimage" src="http://www.andypost.com/media/original/Andy- Post-Food-Photography-Waffle-with-Syrup.jpg" width="100%">
nav li a {
display: inline-block;
background-color: #9CD5CF;
top: 0;
padding: 70px;
width: 150px;
text-decoration: none;
color: #000;
}
#nav-icon3 {
display: none;
}
nav {
display: block;
width: 100%;
position: relative;
top: 0;
left: 0;
}
nav li {
display: inline-block;
background-color: none;
color: black;
text-align: center;
vertical-align: middle;
}
nav ul {
text-align-last: center;
}
Here is what I am trying to do:
You could something like this with rest of your styles
.nav{
z-index: 2;
}
img{
z-index: 1;
}
try creating a div around the nav, and put this in css
html
<div class="divclass">
<nav>
<ul>
<li>About </li>
<li>Menu</li>
<li><img class="logo" src="fjc.svg"></li>
<li>Gallery</li>
<li>Contact</li>
</ul>
</nav>
</div>
css
.divclass {
height:200px;
background-image: url("http://www.andypost.com/media/original/Andy- Post-Food-Photography-Waffle-with-Syrup.jpg");
}

Relative css size to parent of parent

I am asking this because I saw very similar question to mine here.
having
<div id="grand">
<ul id="parent">
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
</ul>
</div>
Can one set css width of child relative ( in % unit ) to that of grand, completely ignoring value of parent's width. for example:
#child{ width: 25% of grand's width }
Some explanations added:
Consider this:
parent has 6 childs in it and we want to show just 4 of theme so that they should have 25% of grand's width.
#grand{
width: 900px;
overflow: hidden
}
#parent{
width: 9999px;
}
.child{
width: 900px;
width: 25% of grand's width
}
You could use % as well to size parent ;), so it is much easier to decide how much/many of child can be seen.
#grand {
width: 900px;/*update this to whatever : 100% to any other value/units */
overflow: hidden
}
#parent {
width: 1000%;
}
.child {
float: left;
box-shadow: inset 0 0 0 1px;
width: 2.5%;/* wich is here 25% of grand's width */
}
body {
margin: 0;
}
ul {
padding: 0;
list-style-type: none;
}
<div id="grand">
<ul id="parent">
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
<li class="child">Content</li>
</ul>
</div>
As a matter of fact, you can BUT it requires that the grandparent have position:relative and the absolutely positioning the grandchild.
I suspect this is an edge case but it is possible.
#grand {
padding: 5%;
width: 80%;
border: 1px solid red;
position: relative;
}
#parent {
height: 150px;
width: 60%;
background: red;
margin: auto;
}
#child {
height: 100px;
position: absolute;
width: 80%;
left: 50%;
transform: translateX(-50%);
background: blue;
color: white;
}
<div id="grand">Grand
<div id="parent">Parent
<div id="child">Child</div>
</div>
</div>
You could use em units. This doesn't require JavaScript or having to absolutely position.
Once you want to display some text content, reset the font-size back within a content span/div.
http://jsbin.com/xibocodaba/edit?html,css,output
div
{
height:100%;
}
#grand
{
font-size:300px;
border:1px solid blue;
width:1em;
height:30px;
}
#parent
{
border:1px solid red;
width:.1em;
}
#child
{
border:2px solid gold;
width:.25em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="grand">
<div id="parent">
<div id="child">
</div>
</div>
</div>
</body>
</html>

Resources