I am trying to develop multiselect from scratch. Of course I have to use relative-absolute for drop-down menu (I need to render it over other elements).
Because I also have mobile "sliding" menu I faced with problem: my multiselect render above my menu
Below you can see other conditions:
Menu:
.button-panel {
display: flex;
flex-direction: column;
width: 100%;
height: calc(100vh - 75px);
position: absolute;
top: 75px;
opacity: 1;
transition: all 0.5s ease-in-out;
background-color: transparent;
-webkit-backdrop-filter: blur(15px);
backdrop-filter: blur(15px);
padding-right: 0;
Input:
.input-area {
height: 40px;
width: 100%;
border: 1px solid;
border-color: var(--grey-light);
display: flex;
}
Drop-down:
.select-content {
height: 120px;
width: 100%;
border: 1px solid;
border-color: var(--grey-light);
overflow-y: scroll;
background-color: var(--pink-super-light);
}
How can I solve this? I have to use relative-absolute because I need render drop-down above other elements, but under side-menu. I tryed to use z-index inside menu and drop-down but didn't get any usful result. Probably I missed something.. Are there workarounds mb?
Objective: develop multiselect with drop-down which render above other elements but works correctly with side-menu.
Thank you for your time.
Your code and names are not clear ever for sorry, but I will try to help.
Let's clarify somethings in the positioning in css.
First, you need to know what exactly is the difference between the most used 3 types of positions in the market.
• Position Relative:
To move the element from its own place from its own sides.
• Position Absolute:
To move the element from the sides of his first positioned parent.
• Position Fixed:
To fix the element place from the window sides.
And now, let's analyze your code...
First, the menu needs to take the fixed position not the absolute, because it needs to has a specific place of the entire screen.
Second, the drop-down menu activation button needs the position relative so you can position the options absolute to it.
So what you must do is to have a parent for the whole drop-down menu input and content that has a relative position, and the children will be absolute.
These are some notes about positions..
But what about overlapping elements over each others?!
This is handled by the z-index property, and this property just takes numbers, so the higher the number value of the z-index the higher ordered the element on the screen.
But note that, the z-index property will not work on any element ever until the element takes a value for the position which can be absolute or others but not static, or the element takes any transform value which can be scale(1) for example.
Now I think your problem is very easy to solve yourself.
For z-index to work, your dropdown class will have to have a position element, so before adding z-index to select-content class add position absolute to it.
Related
I am playing around with a sort of pseudo masonry layout using grid.
So far it is doing exactly what I want... with one exception.
I want to be able to filter out certain types of bricks and bring them back. Now, I can do that just fine, except I want to animate the filtering because I have found users don't notice items are being filtered out. Likely, due to change blindness.
I have linked a jsfiddle that implements everything I am looking for, except that tiles don't fade out when they are removed
The code I provide in the jsfiddle is Vue.js, but that isn't super important. all you need to know is that whatever CSS properties need to be applied should probably happen in the class "cell-leave-active".
The class that allows bricks to transition into new positions is "cell-move".
What I am hoping to find is some css-grid property that will allow the same behaviour I have, but it keeps the bricks in position while they fade, but doesn't stop other bricks from moving into their position as they fade.
maybe Something along the lines of, "keep this element inside its current grid position but don't influence the position of other elements in the grid"... if such a thing exists. However, even that may not be the solution... because that would likely cause elements which are animating out to all overlap one another... So, I am kind of at a loss!
jsfiddle example
.cell-leave-active {
position: absolute;
visibility: hidden;
}
This class as it is, allows other bricks to move into the position of bricks that are currently being filtered out.
If we remove position: absolute; and visibility: hidden;
We get the fading behaviour I want, but other bricks do not transition into their new positions, until after the bricks have completely faded. In fact they don't transition at all, because their transitions are over
So, if you filter out some bricks and click the reset button I provide in the fiddle... That is the animation I want, but in reverse, as tiles get filtered out.
P.S. The way I am getting the elements to fit in the grid the way they are is by use of a dynamically created style, which you can find in the html.
grid-row-end : span <some dynamically determined int>
Edit:
I have considered having an entire second grid underneath, and performing the animations I don't get from this method on the underneath second grid... but I really don't want to do that. I would rather the elements didn't animate exactly the way I want, rather than double the number of bricks I am rendering and applying JavaScript to.
There are two separated issues here: One is how to keep the cells in place when using position: absolute and the other one is how to fade them out.
🔨 Keeping cells in place with position: absolute
To fix the former, you need to set some additional properties on all the excluded cells, apart from position: absolute, and position: relative on the parent:
.container {
position: relative;
}
.cell-leave-active {
position: absolute;
visibility: hidden;
width: 100%;
height: 100%;
box-sizing: border-box;
}
Then, you also need to specify the grid-area on each of them:
For example, for a cell that sits in the top-right corner and that takes one column and 2 rows, you would have grid-area: 1 / 1 / 2 / 3.
You can quickly test this solution on a single cell on your code using the Inspector, but here's a simpler example:
.grid {
position: relative;
display: grid;
grid-gap: 4px;
grid-template-columns: repeat(2, 50px);
grid-template-rows: repeat(2, 50px);
justify-content: center;
list-style: none;
padding: 0;
margin: 0;
}
.grid > li {
border: 1px solid black;
}
.grid > li:hover {
background: cyan;
}
#bigOne {
position: absolute;
width: 100%;
height: 100%;
grid-row: 1 / 2;
grid-column: 1 / 3;
box-sizing: border-box;
background: rgba(255, 0, 0, .25);
pointer-events: none;
}
<ul class="grid">
<li></li>
<li></li>
<li></li>
<li></li>
<li id="bigOne"></li>
</ul>
✨ Fading out the cells
The second issue is that visibility is not an animatable property, so you should be using opacity instead.
Then, you could add pointer-events: none to prevent mouse events (click, hover, ...) on them while they are disappearing.
Here's an example of a CSS tooltip. The author positions the toolip relatively.
.tooltip{
display: inline;
position: relative;
}
However, the tutorial says,
Relative. This type of positioning is probably the most confusing and
misused. What it really means is "relative to itself". If you set
position: relative; on an element but no other positioning attributes
(top, left, bottom or right), it will no effect on it's positioning at
all, it will be exactly as it would be if you left it as position:
static; But if you DO give it some other positioning attribute, say,
top: 10px;, it will shift it's position 10 pixels DOWN from where it
would NORMALLY be. I'm sure you can imagine, the ability to shift an
element around based on it's regular position is pretty useful. I find
myself using this to line up form elements many times that have a
tendency to not want to line up how I want them to.
There are two
other things that happen when you set position: relative; on an
element that you should be aware of. One is that it introduces the
ability to use z-index on that element, which doesn't really work with
statically positioned elements. Even if you don't set a z-index value,
this element will now appear on top of any other statically positioned
element. You can't fight it by setting a higher z-index value on a
statically positioned element. The other thing that happens is it
limits the scope of absolutely positioned child elements. Any element
that is a child of the relatively positioned element can be absolutely
positioned within that block. This brings up some powerful
opportunities which I talk about here.
What I understand is that, without modifiers like top, left etc. relative is equivalent to static and goes with the flow of the page. Then how's the tooltip being displayed at the correct position, i.e. above the hyperlink? Shouldn't it appear at the end of the page instead?
The CSS you provided for tooltip is not complete. I think you saw it in w3schools. But note that there are two elements for it: a parent element with .tooltip class and a child element (actual tooltip text) inside it with .tooltiptext class.
the parent element has position: relative without any top, left ... positions which acts as you said as a static element in its original (normal) place. But the child tooltiptext inside it has a position: absolute which is why it is seperated from normal text flow and put over them.
Here is a sample:
.tooltip {
/* this is just to add meaning for position:absolute of .tooltiptext */
position: relative;
color: navy;
}
.tooltip .tooltiptext {
/* Position the tooltip */
position: absolute;
z-index: 1;
top: 100%;
left: 10%;
/* style the tooltip */
min-width: 50px;
background-color: #ff9;
color: black;
font-size: 10pt;
border-radius: 3px;
padding: 3px 10px 6px;
white-space: nowrap;
visibility: hidden;
}
.tooltip:hover .tooltiptext {
visibility: visible;
}
<span>Sample: </span>
<span class="tooltip">Hover over me
<span class="tooltiptext">Tooltip text</span>
</span>
I am trying to understand the rules behind z-index and how it interacts with the overflow property.
I have this html:
<body>
<div class="cell">
Here is some text to keep things interesting
<div class="boxy"></div>
</div>
</body>
And this css:
.boxy {
position: absolute;
z-index: 9999;
top:70px;
width: 50px;
height: 50px;
background: #0FF;
}
.cell {
border: 2px solid #F00;
position: relative;
/* comment these two lines out and the box appears */
/* or change them both to 'visible' */
/* changing only one of them to 'visible' does not work */
overflow-y: auto;
overflow-x: auto;
}
I would have expected that the cyan box appears even though it is out of the size of the div.cell because its z-index and its position are set.
However, the only way to make the cyan box appear is to comment out the overflow-x and -y lines.
My question is: How can I make the cyan box appear on the screen while keeping the overflow as either hidden or auto? But more importantly, I'm looking to understand why this is happening. What are the css and layout rules being applied here?
See my Plunkr. This example, is of course a much simplified version of the HTML/CSS I am actually working with.
EDIT
There seems to be some confusion in the answers below because I didn't explain things well enough. If you comment the two overflow lines out, you can see that the cyan box appears. It appears outside of the border of .cell. Why does this happen? How can I make the cyan box appear, while still hiding overflow and z-index?
The reason the cyan box appears only when overflow-x and overflow-y are visible, and disappears otherwise, is simply because the cyan box is overflowing the cell box. overflow: visible simply means "paint this box even if it is overflowing its containing block" — the cell box is the containing block of the cyan box because its position is relative. Any other values of overflow cause overflowing content to be clipped from view. There is nothing special going on here; in particular, the z-index is completely irrelevant and there is no such interaction as the question title alludes to (and there really is no reason to set it to such a huge number unless you're worried about scripts injecting other elements into the cell).
The only way to allow the cyan box to appear while the cell has a non-visible overflow is to remove position: relative from the cell and apply that declaration to the parent of the cell (in your example, it's the body). Like this:
body {
position: relative;
}
.boxy {
position: absolute;
z-index: 9999;
top: 70px;
width: 50px;
height: 50px;
background: #0FF;
}
.cell {
border: 2px solid #F00;
overflow: auto;
}
<div class="cell">
Here is some text to keep things interesting
<div class="boxy"></div>
</div>
Absolute-positioned elements do not contribute to the dimensions of their parents.
Therefore, the .cell DIV has no content that affects its dimensions, making it 100% wide by 0px high.
To make the element appear, you'll have to add a height to .cell that will encompass the DIV, in this case 120px (70px top + 50px height).
The Parent Class cell need to be set it's height. because height of absolute element doesn't affect it;s parent.
.boxy {
position: absolute;
z-index: 9999;
top:70px;
width: 50px;
height: 50px;
background: #0FF;
}
.cell {
border: 2px solid #F00;
position: relative;
/* comment these two lines out and the box appears */
/* or change them both to 'visible' */
/* changing only one of them to 'visible' does not work */
overflow-y: auto;
overflow-x: auto;
min-height: 120px; /* height 70px(Top)+50px*/
}
Your problem
Your problem is related to cell node that hides boxy when overflow is specified on cell node.
The reason
The reason behind is that boxy with position absolute does not contribute to height of cell and overflow hides it.
Why is it shown without overflow?
By default overflow is visible, which for browser means do not do anything special for overflow functionality and it does not need to render overflow => does not hide boxy.
Z-indices are local inside their clipping hierarchical parent context. This is very non-intuitive. They have their own z-stack context, which normally parallels that of the enclosure hierarchy. But they're still subject to clipping! Which can be a real pain if you're intuitively expecting the z-indices to be absolute.
Note that some jquery containers, such as accordion, quietly specify overflow: auto. Even if it's not explicitly in your code. (This can be overridden locally after it's found.)
Also note that if overflow-x: visible is set, but overflow-y is set to a non-visible, then the rendering engine quietly internally changes overflow-x to be the same as overflow-y for your amusement. But you found this out already.
You probably should be able to circumvent the unwanted non-"visible" overflow clipping, even with your high z-index, by invoking transform: translate(0,0); [or whatever desired offset, % or pixels] inside the style of the div that you want to levitate. Transform should create a new local z-stack for that element and its children. Which will let you get around an overly-restrictive parent or grandparent.
I have a glyphicon as such:
<div class="col-xs-4 col-sm-2">
<span class="glyphicon glyphicon-circle-arrow-up glyphicon-large"></span>
</div>
.glyphicon-large {
min-height: 260px;
font-size: 35px;
width: 1em;
display: block;
top: 50%;
margin: -0.5em auto 0px;
}
The glyphicon won't align to the center, vertically. When I open firefox, inspect element, and toggle off/on the top 50% rule, it suddenly works. How come?
Browser Bug Explanation
According to MDN on top:
For relatively positioned elements (those with position: relative), it specifies the amount the element is moved below its normal position.
Note: Percentage is applied as a percentage of the height of the element's containing block
According to W3 on top:
For relatively positioned boxes, the offset is with respect to the top edges of the box itself (i.e., the box is given a position in the normal flow, then offset from that position according to these properties).
Note: Percentages refer to height of containing block
Here's my guess:
I think what's happening is that when the browser is first rendering the visual tree, and sees top:50%;, it looks to the parent to set the height. Since no height has been specifically applied, and it has not loaded any child contents, the height of this div (and all divs) effectively starts off as zero until otherwise indicated. It then pushes down the glyph by 50% of zero.
When you toggle the property later, the browser has already rendered everything, so the calculated height of the parent container is provided by the height of its children.
Minimal, Complete, and Verifiable Example
Note: This doesn't really have anything to do with Bootstrap or Glyphicons. In order to avoid a dependency on bootstrap, we'll add top: 1px that would have been applied by the .glyphicon class. Even though it is overwritten by 50%, it still plays an important role.
Here's a simple set of parent/child elements:
<div id="container">
<div id="child">Child</div>
</div>
In order to simulate the toggling the property in a more repeatable fashion, we can just wait two seconds and then apply a style in javascript like this:
window.setTimeout(function() {
document.getElementById("child").style.top = '50%';
},2000);
Example 1 (jsFiddle)
As a starting point, let's recreate your issue.
#container {
position: relative;
/* For Visual Effects */
border: 1px solid grey;
}
#child {
position: relative;
height: 50px;
top: 1px;
/* For Visual Effects */
border: 1px solid orange;
width: 50px;
margin: 0px auto;
}
Notice that as soon as you resize the window, the browser will repaint the screen and move the element back to the top.
Example 2 (jsFiddle)
If you add top: 50% to the child element, nothing will happen when the javascript adds the property because it won't have anything to overwrite.
Example 3 (jsFiddle)
If you add top: 49% to the child element, then the DOM does have something to update so we'll get the weird glitch again.
Example 4 (jsFiddle)
If you add height: 50px; to the container instead of the child, then the top property has something to position against right from the get go and you don't need to use toggle in JavaScript.
How to Vertically Align
If you just wanted to know how to vertically center something consistently, then you can do the following:
The trick to vertically centering text is to set the line-height equal to the container height. If a line takes up 100 pixels, and the line of text online takes up 10, then browsers will try to center the text within the remaining 90 pixels, with 45 on the top and bottom.
.glyphicon-large {
min-height: 260px;
line-height: 260px;
}
Solution in jsFiddle
Tried centering a glyph icon that was inside an H1 tag, that was taking a while - so I discovered that you can actually change the font size and colour inside the SPAN tag contaning the glyph.
Thus:
<h1><span class="glyphicon glyphicon-envelope" style="font-size: 24px; color: #108db7;"></span> Mes Messages</h1>
actually worked out for me.
Have you tried ? :
<span class="glyphicon glyphicon-circle-arrow-up glyphicon-large" style="vertical-align:middle"></span>
so i have this fiddle http://jsfiddle.net/speeedracer/CGucm/ and as you can see when you mouse over any of the links across the top row, the popup div is under the list elements of the bottom row. anyone know how to get it to cover over the other page content? i changed the z-index to be really high so it appears on top, but it didn't work.
here's the drop-down box code:
enter code here.drop-box {
display: none;
position: static;
width: 400px;
height: 100px;
z-index: 9999;
background: #e8dfc2;
}
*i know i have some visual spacing issues, but i just need a working mockup without it having to be perfect...yet.
thanks!
z-index does not work with position: static. This is as if you had no position.
So changing your position: absolute will solve your problem and z-index will come into play.