I have created a dropdown menu. The basic process has been:
I put the dropdown link and submenus inside a div.
Using flexbox I put all the links inline and the submenus in a column.
With the visibility property I make the submenus appear.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main_container {
width: 500px;
margin: 20px auto;
border: solid 2px green;
display: flex;
height: 400px;
}
div {
width: 110px;
display: flex;
flex-direction: column;
height: 40px;
}
a {
text-decoration: none;
color: white;
width: 90px;
text-align: center;
padding: 10px;
height: 40px;
background-color: red;
}
a {
flex-grow: 1;
}
div a {
width: 110px;
flex-grow: 0;
}
a:hover {
font-weight: bold;
background: blue;
}
.hidden {
visibility: hidden;
}
div:hover .hidden {
visibility: visible;
}
<nav class="main_container">
Enlace1
Enlace2
<div>
Enlace 3
Enlace 3.1
Enlace 3.2
Enlace 3.3
</div>
Enlace 4
</nav>
The key is to reduce the height of the div to 40px, because if you don't, hovering under "Link 3" will still cause the submenu to appear in a weird effect.
Well, when the div is reduced, in height, a value less than the height of the "Link 3" and submenus, curiously the height of these is reduced by 2px as you can see at the bottom of "Link 3".
Can this be avoided?
EDIT:
Changing your .hidden class to use the display property instead of visiblity is also a good idea here. visibility still allows the element to render and take up space on the page, which is why it can still be hovered why not visible. However, using display: none; makes it so the element does not render and cannot take up space on the page or be hovered.
Typically if you want to show/hide elements on a page you should use display: none;. visibility can have its uses, typically if you want there to an empty space/void where an element should be. Most of the time you actually want to use display instead.
Additionally, I added a :hover action to the div CSS so that it sets the height property to auto only when hovered. This avoids any unusual hover effects from the <div> taking up more space.
*{
margin: 0;
padding: 0;
box-sizing:border-box;
}
.main_container{
width:500px;
margin:20px auto;
border:solid 2px green;
display:flex;
height:400px;
}
div{
width:110px;
display:flex;
flex-direction:column;
height: 40px;
}
a{text-decoration:none;
color:white;
width:90px;
text-align:center;
padding:10px;
height:40px;
background-color:red;
}
a{flex-grow:1;}
div a{
width:110px;
flex-grow:0;
}
a:hover{
font-weight: bold;
background:blue;
}
.hidden{
display: none;
}
div:hover .hidden{
display: inline;
}
div:hover { height: auto; }
<nav class="main_container">
Enlace1
Enlace2
<div>
Enlace 3
Enlace 3.1
Enlace 3.2
Enlace 3.3
</div>
Enlace 4
</nav>
inside your css do this to your a element:
a {
text-decoration: none;
color: white;
width: 90px;
text-align: center;
padding: 10px;
background-color: red;
min-height: 40px;
max-height: 40px;
}
add a min-height and max-height and set it to 40px
You can try this. You need to use div {height:100%;}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.main_container {
width: 500px;
margin: 20px auto;
border: solid 2px green;
display: flex;
height: 400px;
}
div {
width: 110px;
display: flex;
flex-direction: column;
height: 100%;
}
a {
text-decoration: none;
color: white;
width: 90px;
text-align: center;
padding: 10px;
height: 40px;
background-color: red;
}
a {
flex-grow: 1;
}
div a {
width: 110px;
flex-grow: 0;
}
a:hover {
font-weight: bold;
background: blue;
}
.hidden {
visibility: hidden;
}
div:hover .hidden {
visibility: visible;
}
<nav class="main_container">
Enlace1
Enlace2
<div>
Enlace 3
Enlace 3.1
Enlace 3.2
Enlace 3.3
</div>
Enlace 4
</nav>
Related
Considering the following DOM distribution. I have a flexbox container with two children, one of them has a fixed size while the other shrinks with an overflow: hidden. I was wondering, however, if there is a way for the overflown content to remain visible without any impact on the flow of the DOM.
Fleshed out Example at Codepen
ul.current {
list-style: none;
display: flex;
width: 40%;
margin: 0 auto;
}
li {
overflow: hidden;
}
li:last-child {
flex-shrink: 0;
}
li div {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
li:last-child {
margin-top: 2rem;
}
li:last-child div {
background: red;
}
/* GOAL */
section {
margin: 0 auto;
width: 40%;
}
.item {
position: absolute;
}
.item:last-child {
margin-top: 2rem;
margin-left: 5rem;
}
.content {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
.item:last-child .content {
background: red;
}
<h3>Shrink the viewport to get an idea of what's the intended scenario</h3>
<ul class="current">
<li><div></div></li>
<li><div></div></li>
</ul>
<h3>Visual representation of the overlap behavior</h3>
<section>
<div class="item"><div class="content"></div></div>
<div class="item"><div class="content"></div></div>
</section>
What I want, basically, is for the images to "overlap" each other in a flexible context, meaning, a solution that would work on N cases.
Your issue may be more clear to resolve if you didn't use quite as much inline style. I added classes and css to your code to make it easier to read.
By adding flex-wrap:wrap; to the display:flex; on the section, the images wrap. I set the images to background-images, and the bg-size to cover. If you wish the first-listed image to display second, simply switch the divs.
Hope this helps
#imagedisp {
display: flex;
flex-wrap: wrap;
}
#div1 {
flex-shrink: 1;
/* overflow: hidden;*/
border: 1px dashed;
background-image: url("https://s3-media4.fl.yelpcdn.com/bphoto/xFlymSQW0weBqXjwZM6Y2Q/ls.jpg");
}
#div2 {
margin-bottom: 40px;
border: 1px dashed;
background-image: url("https://s3-media3.fl.yelpcdn.com/bphoto/_-U30Zk2XbUKe2fcdtEXLQ/o.jpg");
}
#div1,
#div2 {
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
div {
min-width: 300px;
/*width:300px;*/
height: 100px;
}
<section id="imagedisp">
<div id="div1">
<!-- <img />-->
</div>
<div id="div2">
<!-- <img />-->
</div>
</section>
In order to have an overlap you have to either use positioned elements (which is not the best solution if you want to keep the element in-flow) or use negative margin.
Let's consider negative margin. The trick is to find a way to adjust the margin in order to create the overlap when the parent container will shrink.
Here is a basic example:
section {
max-width: 300px;
border: 1px solid;
animation:change 2s linear infinite alternate;
}
#keyframes change {
from {max-width: 300px;}
to {max-width: 100px;}
}
.item{
height: 80px;
min-width: 80px;
background:blue;
display: inline-block;
vertical-align:top;
margin-right:calc((100% - 200px)/2);
}
.item:last-child {
margin-top: 2rem;
background: red;
}
<section>
<div class="item">
</div>
<div class="item">
</div>
</section>
As you can see, the trick is to define the margin considering the width of the container (100%) and we will have two cases:
When the width is bigger than Xpx we have a positive margin and a normal behavior with spacing
When the width is smaller than Xpx we will have a negative margin and will have the overlap effect without wrapping.
We need to simply find the good way to define the margin in order to obtain the needed behavior. We may also consider media query in case we want a different behavior like having no margin and then overlapping:
section {
border: 1px solid;
font-size:0;
}
.item{
height: 80px;
min-width: 80px;
background:blue;
display: inline-block;
vertical-align:top;
}
.item:nth-child(odd) {
margin-top: 2rem;
background: red;
}
#media all and (max-width:350px) {
.item{
margin-right:calc((100% - 320px)/4)
}
}
<section>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
<div class="item">
</div>
</section>
Another idea that work with nested element (like your intial code) is to keep the overflow visible and force the outer element to shrink using min-width:0.
ul.current {
list-style: none;
display: flex;
width: 40%;
margin: 0 auto;
animation:change 2s infinite linear alternate;
}
#keyframes change {
from {width:100%}
to {width:40%}
}
li {
min-width:0;
}
li div {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
li:nth-child(odd) {
margin-top: 2rem;
}
li:nth-child(odd) div {
background: red;
}
/* GOAL */
section {
margin: 0 auto;
width: 40%;
}
.item {
position: absolute;
}
.item:last-child {
margin-top: 2rem;
margin-left: 5rem;
}
.content {
border: 1px solid black;
background: green;
width: 10rem;
height: 10rem;
}
.item:last-child .content {
background: red;
}
<ul class="current">
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
<li><div></div></li>
</ul>
I have a flex container, with few li elements inside. While adding more li elements inside, the container scretches together in above and down sides. I don't want it to move any further in up, only in down direction.
You can check it on my JSfiddle
Try to add few li elements, you will see that container is scretching. How to block it?
Try this out and see if it is what you are going for. If not I may need some additional info.
.mainContainer {
width: 100vw;
height: 100vh;
display: block;
align-items: center;
justify-content: center;
}
.content {
min-height: 350px;
width: 300px;
border-radius: 5px;
background: #f2f2f2;
border: 1px #ccc solid;
position:relative;
margin:0 auto;
display:block;
top:50%;
margin-top:-25%;
}
First of all, I am using some Jquery here for adding new elements:
So I removed min-height for content
Reset the ul margin-bottom to zero.
The new items are added via JS and are positioned absolutely:
ul.list-group {
margin-bottom: 0;
position: relative;
}
ul .list-group-item.counter{
position:absolute;
width: 100%;
}
The new items are listed one below the other giving the margin-top property:
$('.list-group').append("<li class='list-group-item counter' style='margin-top:" + newItems * 100 + "px'>x</li>");
Let me know your feedback on this. Thanks!
var newItems = 0;
$('.fixed_btn').click(function(event) {
$('.list-group').append("<li class='list-group-item counter' style='margin-top:" + newItems * 100 + "px'>x</li>");
newItems++;
});
* {
padding: 0;
margin: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
body {
-webkit-font-smoothing: antialiased;
font-family: Raleway;
}
.mainContainer {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.content {
/*min-height: 350px;*/
width: 300px;
border-radius: 5px;
background: #f2f2f2;
border: 1px #ccc solid;
}
.list-group-item {
height: 100px;
}
ul.list-group {
margin-bottom: 0;
position: relative;
}
.fixed_btn {
position: fixed;
top: 0;
left: 0;
}
ul .list-group-item.counter{
position:absolute;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<div class="mainContainer">
<div class="content">
<ul class='list-group'>
<li class='list-group-item'>x</li>
<li class='list-group-item'>x</li>
<li class='list-group-item'>x</li>
</ul>
</div>
</div>
<button class="btn fixed_btn">+ Add</button>
If you change your .mainContainer CSS so that the height is auto. Now the list will not move up, but only will move down as you wanted as the height is flexible depending on the content:
.mainContainer {
width: 100vw;
height: auto;
display: flex;
align-items: center;
justify-content: center;
}
Also, if you change the .content CSS so that the min-height is auto it seems to look nicer when there are fewer li elements:
.content {
min-height: auto;
width: 300px;
border-radius: 5px;
background: #f2f2f2;
border: 1px #ccc solid;
}
Updated (again) Fiddle, try to add more li elements
If your looking for the list to stay in position, but when more elements are added to have a scroll but still be fixed see this other Fiddle
I have the following CSS and HTML:
body { background-color: #c0c0c0; }
.title-bar, { background-color: #999; color: white; float: left; overflow: hidden; }
.title-bar {
border-bottom: 1px solid white;
height: 128px;
width: 100%;
}
.logo, .user-info { box-sizing: content-box; height: 100%; width: 128px; }
.logo{
align-items: center;
background-color: #369;
border-right: 1px solid white;
display: flex;
float: left;
font-size: 2em;
font-kerning: none;
justify-content: center;
}
.user-info {
align-items: center;
border-left: 1px solid white;
display: flex;
float: right;
justify-content: space-between;
flex-flow: column nowrap;
}
.user-info .circle {
border: 2px solid #369;
border-radius: 50%;
display: inline-block;
flex: 0 0 auto;
height: 32px;
margin: 8px 8px;
overflow: hidden;
transition: border 0.15s ease-out;
width: 32px;
}
.user-info .circle:hover { border-width: 4px; }
.user-info .container {
border-top: 1px solid white;
display: flex;
justify-content: center;
margin-top: 6px;width: 100%;
}
.hor-nav { background-color: #404040; }
.option { display: inline-block; position: relative; }
.hor-nav .option:hover {background-color: #369; }
.option a {
color: white;
display: inline-block;
font-size: 1em;
padding: 14px;
text-align: center;
transition: background-color 0.15s ease-out;
}
.option .dropdown { display: none; position: absolute; }
.option:hover .dropdown{ display: block; }
.dropdown a {
display: block;
text-align: left;
width: 100%;
}
<div class="title-bar">
<a class="logo" href="#">
</a>
<div class="user-info">
<span>User name</span>
<div class="container">
</div>
</div>
<div class="hor-nav">
<div class="option">
OPTION 1
<div class="dropdown">
ITEM 1
</div>
</div>
</div>
</div>
as you can see, the hor-nav bar's color spills onto the user-info area.
I have researched this and found that if I set overflow-x: hidden; it will not do this (see this article).
I have tried that and it is true - the nav bar does not spill into the user-info but, when you hover over one of the nav bar options, the dropdown does not come down but instead the vert-nav gives you a scroll bar (see this jsfiddle).
Additionally, if you do overflow-y: hidden; there is no scroll bar at all.
I am trying to get it so that the background-color of the hor-nav does not spill into other div's, but also allows the dropdown to be activated and work
thank you.
The easiest way to to this with least code change is to just give the user-info area a background color. Since the hor-nav section is lower on the z-index this will give the visual affect you want although the bar will still be under the user-info section it won't appear to be and the drop down will funtion as it does now.
Per your inquiry, you could do this another way by using percentage based widths for all 3 elements so they don't overlap eachother. Please see this fiddle for code change (note I change the markup order slightly, widths, and added box sizing css property)
The way I see it, you have 3 options
You can try adding margin-left/right to the hor-nav.
.hor-nav {
margin: auto 128px;
}
Another option is to set a certain width to the .hor-nav. Or practically cut the width of it.
.hor-nav {
width: calc(100% - 128px);
}
And third, is to add a background color to the .user-info
Before you roll your eyes and move on, I know how to solve this problem by using a fixed height and absolution positioning with top: and bottom:, but I want to solve it without using fixed heights. I want to learn more about CSS so I'm trying to solve this a different way.
I have set up a typical navbar running across the top, and then a scrolling content div below.
However! How do I fit the bottom scrolling div container to the remaining space without using absolute coordinates? I can't do position: absolute, because then I'd need to know the height of the navbar to set "top:". And I can't do "bottom: 0" because I'd have to specify a height.
Here's the JS filddle:
http://jsfiddle.net/8dugffz4/1/
The class of interest is ".result". I currently have the height fixed, which I don't want.
Thanks, y'all.
PT
CSS:
* {
font-family: Helvetica, Sans;
border: 0px;
margin: 0px;
padding: 0px;
}
.navBar {
width: auto;
overflow: auto;
border-bottom: 1px solid #bbb;
}
.pageBar {
float: right;
}
.pager {
cursor: pointer;
float: left;
border: 1px solid #bbb;
width: 2em;
height: 2em;
line-height: 2em;
text-align: center;
margin: 5px;
margin-left: 0px;
background: #eee;
color: #bbb;
}
.pager:hover {
background: #777;
border: 1px solid black;
color: white;
}
.fliph {
-ms-transform:scale(-1,1); /* IE 9 */
-moz-transform:scale(-1,1); /* Firefox */
-webkit-transform:scale(-1,1); /* Safari and Chrome */
-o-transform:scale(-1,1); /* Opera */
}
.results {
background: gray;
width: 100%;
height: 200px;
overflow: scroll;
}
.line {
height: 10em;
line-height: 10em;
border: 1px solid red;
}
HTML:
<body>
<div class='navBar'>
<div class='pageBar'>
<div class='pager'>◁</div>
<div class='pager'>1</div>
<div class='pager fliph'>◁</div>
</div>
</div>
<div class='results'>
<div class='line'>Line1</div>
<div class='line'>Line2</div>
<div class='line'>Line3</div>
<div class='line'>Line4</div>
</div>
</body>
Here's a solution that uses display: table and can actually achieve fluid heights:
http://jsfiddle.net/8dugffz4/8/
And a minimalistic snippet in case you want to see specifically what I did:
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
#table {
display: table;
height: 100%;
width: 100%;
}
#table > div {
display: table-row;
}
#navbar {
height: 45px;
opacity: .5;
}
#navbar > div {
height: 100%;
background: black;
}
#results {
height: 100%;
}
#results > div {
height: 100%;
overflow: auto;
background: green;
}
<div id="table">
<div id="navbar">
<div></div>
</div>
<div id="results">
<div></div>
</div>
</div>
If you're just looking for an alternative to the position: absolute method, you could use the height: 100% method:
html, body { height: 100%; }
body { box-sizing: border-box; padding-top: 45px; }
.navBar { height: 45px; margin-top: -45px; }
.results { height: 100%; }
Like so: http://jsfiddle.net/8dugffz4/7/
I have following HTML for a heading. The .left and .right are empty spans. I have specific width for the .left and but the .text width is not always same. I want to set the background for the .left (fixed width) and the .right. The .right should get all the remaining space in the parent element (h1). How that can be done?
<h1>
<span class="left"></span>
<span class="text">Text</span>
<span class="right"></span>
</h1>
I'm trying following CSS which does not work:
.left{
background: yellow;
width: 30px;
height: 20px;
display: inline-block;
}
.right{
display: inline-block;
background: blue;
}
Here's the JSFiddle link:
http://jsfiddle.net/jMR8u/
Here's what I'm trying to get:
The idea is to set a background image in h1 except the .text span and the problem is that I can not set the background for the .text, otherwise it would be easier.
This version will stretch to fit the contents of .text and should be cross-browser.
You can fake the blue (right) background by making it a border of .text:
.text { border-right: 1000px solid; }
Then, shift .right to the left by 1000px:
.right { margin-left: -1000px; }
Give a width to .left, make each element inline-block, hide the extra blue border on the right, and make sure .text and .right do not wrap to a new line:
.left { width: 200px; }
.left, .text, .right { display: inline-block; }
h1 { overflow: hidden; white-space: nowrap; }
And give it color!
body { background: green; }
.left { background: red; }
.text { border-color: blue; }
Here is a JSFiddle demonstration:
if i interpret your image correct .. this is the answer http://jsfiddle.net/jMR8u/4/
h1{
border: 1px solid red;
position: relative;
}
.left{
background: yellow;
width: 30px;
height: 20px;
display: inline-block;
}
.right{
display: inline-block;
background: blue;
position: absolute;
z-index: 99;
height: 20px;
width: 100%;
}
.text {
height: 20px;
width: 150px;
display: inline-block;
position: relative;
z-index; 101;
}
ok, then use layers .. with z-index and positioning
You could use flexbox (but use the new syntax). Sadly, it only works on Chrome and Opera for now, so this has limited usefulness:
h1 { display: -webkit-flex; display: flex; }
.left { width: 30px; }
.right { flex: 1; -webkit-flex: 1; } /* This makes it fluid. */
.left { background: yellow; }
.right { background: blue; }
Here is a JSFiddle demonstration: http://jsfiddle.net/FN7vQ/
if you can set width to the .text span and h1 element.
body{
background:green;
}
h1{
border: 1px solid red;
display:table;
width:100%;
}
.left{
background: yellow;
width: 30px;
display: table-cell;
}
.right{
display: table-cell;
background: blue;
}
.text {
display:table-cell;
width: 150px;
}
If I understood your requirement correctly. you should change your markup a little bit as below
h1 {
background: #660000;
padding-left: 30px;
line-height: 1.1;
}
h1 span {
background: #fff;
padding: 0 3px;
color: #600;
}
<h1>
<span>
Lorem, ipsum dolor. you are doing great
</span>
</h1>
and CSS goes here below