materializecss, vertically offset dropdown menu content - css

I'm trying to add a dropdown menu to my nav as detailed in the docs here.
By default, .dropdown-content is set to top: 0;. And here is the default behavior:
If I change the top to 50px in materialize.css it actually moves it up 50 pixels and sets the element style to top: -50px.
Here is the code:
.dropdown-content {
top: 50px;
}
But when it renders, the element looks like this:
<ul id="dropdown1" class="dropdown-content" tabindex="0" style="display: block; width: 139.297px; left: 900.891px; top: -50px; height: 216px; transform-origin: 0px 0px 0px; opacity: 1; transform: scaleX(1) scaleY(1);">
(The key being `top: -50px;)
I tested with multiple values, here is 65:
.dropdown-content {
top: 65px;
}
<ul id="dropdown1" class="dropdown-content" tabindex="0" style="display: block; width: 139.297px; left: 900.891px; top: -65px; height: 216px; transform-origin: 0px 0px 0px; opacity: 1; transform: scaleX(1) scaleY(1);">
(now it is top: -65px)
Here's a screenshot if you care to take a look
Why is it inverting this value? How can I make the dropdown so it doesn't occlude the main menu?

I checked it and i see the best way to do that becuase the styles comes from JS which is have special calc i have checked and if you want to avoid any fixed height maybe you will have padding or anything in the header so the best to give the top:100% and to use !important to be stronger than the JS
give the class .dropdown-content top: 100% !important;
.dropdown-content {
top: 100% !important;
}

Looks like this option has been added in Materialize v1.0.0:
https://materializecss.com/dropdown.html
via the option coverTrigger on instantiation. It defaults to true (must set to false to achieve desired behavior).

Not a solution, but as a workaround I added a "spacer" element to the top of the dropdown:
<li class="spacer"></li>
.dropdown-content {
background: none; //overwrites default materialzie value of white
}
.dropdown-content li > a, .dropdown-content li > span {
background-color: white; //needed now that the whole menu has no background
}
.dropdown-content li:hover, .dropdown-content li.active {
background: none; //no white on hover
}
.dropdown-content li.spacer {
min-height: 65px; //height of the nav element
cursor: default; //so it doesn't look like a menu option
opacity: 0; //the magic
}
And here's the result:

<mat-menu class="abc" #menu="matMenu" [overlapTrigger]="false">
<div mat-menu-item >
11111
</div>
<div mat-menu-item >
22222222
</div>
</mat-menu>
Hope this works

Related

How to get rid of a Bootstrap 4 navbar style

In this nice Bootstrap navbar with submenus, I would like to get rid of the light-grey background (#f8f9fa) that persists on the dropdown item when hovering the submenu.
That's probably a default bootstrap css but I can't find how to disable it.
Here's the codepen : https://codepen.io/surjithctly/pen/PJqKzQ
.dropdown-submenu {
position: relative;
}
.dropdown-submenu a::after {
transform: rotate(-90deg);
position: absolute;
right: 6px;
top: .8em;
}
.dropdown-submenu .dropdown-menu {
top: 0;
left: 100%;
margin-left: .1rem;
margin-right: .1rem;
}
You may change this color to whatever you like by overriding the CSS this way:
.dropdown-item:focus, .dropdown-item:hover {
background-color: #fff;
}
In the example above, I set it to white.

I need an element to be a child of other without inheriting certains properties

<span id="priority-dot-open-menu">
<span id="priority-menu">
<span class="tooltip-top"></span>
<span id="priority-dot-blue"></span>
<span id="priority-dot-yellow"></span>
<span id="priority-dot-red"></span>
</span>
</span>
/* The popup menu - hidden by default */
#priority-menu {
display: none;
position: absolute;
top: 150%;
left: -50%;
border: 3px solid #f1f1f1;
z-index: 9;
max-width: 300px;
padding: 10px;
background-color: white;
}
#priority-dot-open-menu {
position: relative;
height: 25px;
width: 25px;
background-color: blue;
border-radius: 50%;
display: inline-block;
opacity: 0.8;
cursor: pointer;
}
#priority-dot-open-menu:hover {
opacity: 1;
}
My #priority-menu (column with the 3 dots) is a child of the dot above (#priority-dot-open-menu). I need it to be so I can use absolute positioning. However it's also inheriting certain properties/values, like opacity and hovering which I don't want to. What would be the ideal solution?
https://jsfiddle.net/moq2bwLj/ (the menu doesn't open on js fiddle, it's just for code-viewing purposes. Thanks!
Child elements in CSS automatically inherit the rules applied to their parents; there is nothing you can do to prevent this. What you can do, however, is to override this behaviour by crafting a rule that targets the child, changing it to the initial value:
#priority-menu {
cursor: initial;
opacity: initial;
}

Creating custom dropdown, why is width of child element wider than its parent?

I am trying to build a custom dropdown component for React. Unfortunately, my child list's width, which I have set to 100%, is showing up as wider than its parent element.
The DOM:
<div className="dd-wrapper" id={this.state.wrapperID}>
<div className="dd-header" id={this.state.headerID} onClick={() => this.toggleList()}>
<div className="dd-header-title"></div>
</div>
<ul className="dd-list hidden" id={this.state.listID}>
<li className="dd-list-item">Test</li>
<li className="dd-list-item">Test2</li>
<li className="dd-list-item">Test3</li>
</ul>
</div>
the toggleList function removes the hidden class from the list, and adds a border property class dd-border to the wrapper, which is also not behaving properly (the border is wrapping only the header).
It is being called in the parent element like this (I am using Bootstrap grid):
<div className="col-md-3">
<label> Dropdown
<Dropdown id="test-dd"/>
</label>
</div>
Here's the relevant css:
.dd-wrapper {
width: 100%;
margin-top: 8px;
}
.dd-header {
height: 40px;
background-color: #E2E8F2;
background-image: url("assets/images/down-chevron.png");
background-repeat: no-repeat;
background-position: 95% 50%;
}
.dd-list {
list-style-type: none;
background-color: white;
position: absolute;
}
.dd-list li {
height: 40px;
}
.dd-border {
border: 1px solid #3d70b2;
}
label {
display: inline-block;
width: 100%;
font-size: 14px;
}
.hidden {
display: none;
}
The result looks like this:
How can I get the width to match its parent without doing it manually (to ensure it will work for any size of dropdown? And, secondarily, does anyone know a good trick for getting the border to cover the child as well?
A quick note: This is a CSS question so your React logic is just acting as a hurdle for anyone willing to answer. I've extracted the important parts based on your description into a working snippet below without React. I would recommend pulling out anything not crucial to the context of your questions to encourage more prompt answers.
How can I get the width to match its parent without doing it manually (to ensure it will work for any size of dropdown?
I think the main thing you are looking for is position: relative on the parent. Because absolutely positioned elements size and position themselves against the first "positioned" ancestor. As a result, you can then combine this with top, left, right, bottom, width and/or height values (and probably box-sizing: border-box;)
...does anyone know a good trick for getting the border to cover the child as well?
You can fake it by putting the dropdown right up against the bottom and toggling a class on a common parent to hide/show certain borders.
Here's the snippet to demonstrate:
// The toggle logic in vanilla JS just to make the example work
// This, instead of toggling "hidden" on the list, toggles a "dd-closed" class on the wrapper
const wrapperEl = document.querySelector('.js-wrapper')
const headerEl = document.querySelector('.js-header')
if (wrapperEl && headerEl) {
const ancestorLabel = headerEl.closest('label')
const targetEl = ancestorLabel ? ancestorLabel : headerEl
targetEl.addEventListener('click',
() => wrapperEl.classList.toggle('dd-closed')
)
}
.dd-wrapper {
position: relative;
width: 100%;
margin-top: 8px;
}
.dd-header {
position: relative;
height: 40px;
background-color: #E2E8F2;
background-repeat: no-repeat;
background-position: 95% 50%;
border: 1px solid #3d70b2;
border-bottom-width: 0;
padding-right: 3em;
}
.dd-header::before {
position: absolute;
content: '\25B4';
right: 0;
text-align: center;
line-height: 40px;
width: 1em;
top: 0;
bottom: 0;
font-size: 2em;
}
.dd-list {
list-style-type: none;
background-color: white;
position: absolute;
border: 1px solid #3d70b2;
margin-top: 0;
left: 0; right: 0;
padding: 0;
}
.dd-list li {
vertical-align: middle;
padding: 1em;
}
.dd-list li:hover {
background-color: #eee;
}
label {
display: inline-block;
width: 100%;
font-size: 14px;
}
.dd-closed > .dd-header::before {
content: '\25BE';
float: right;
}
.dd-closed > .dd-header {
border-bottom-width: 1px;
}
.dd-closed > .dd-list {
display: none;
}
<!-- Basically what React would render as your output HTML...plus any necessary changes -->
<label> Dropdown
<div class="dd-wrapper dd-closed js-wrapper">
<div class="dd-header js-header">
<div class="dd-header-title"></div>
</div>
<ul class="dd-list">
<li class="dd-list-item">Test</li>
<li class="dd-list-item">Test2</li>
<li class="dd-list-item">Test3</li>
</ul>
</div>
</label>
<p>(Some other content for the dropdown to cover)</p>
<button>(I do nothing)</button>

<li> img and description disappearing when display:none is applied

My li element has a img as background and the text written to the side. I want to display: none just the text and make it appear only on hovering. However if i apply display: none to the span element having text it takes out the whole li element.please check the images attached.
Li Element with list style image and description
HTML
CSS
You may try this. You will get appear Text on Hover Image using only
css.
body
{
font-family: sans-serif;
}
.image-hover-text-container
{
position: relative;
display: inline-block;
width: auto;
height: auto;
transition: all 0.2s linear;
}
.image-hover-image
{
display: block;
}
/* Make the image round */
.image-hover-image img
{
border-radius: 0%;
width: 300px;
}
.image-hover-text
{
position: absolute;
top: 0;
width: 100%;
height: 100%;
margin: 0 auto;
opacity: 0;
cursor: default;
transition: opacity 0.2s linear;
}
.image-hover-text:hover
{
opacity: 1;
}
.image-hover-text-bubble
{
position: relative;
box-sizing: border-box;
top: 0; left: 0; right: 100%;
height: 100%;
text-align: center;
background: rgba(218, 211, 211, 0.9);
border-radius: 0%;
margin: 0 auto;
padding: 30% 0px;
overflow: hidden;
font-size: 17px;
text-align: center;
word-wrap: break-word;
}
.image-hover-text .image-hover-text-title
{
font-size: 25px;
display: block;
}
<div class="image-hover-text-container">
<li class="image-hover-image">
<img src="http://dummyimage.com/600x400/38acf0/a9e1f2.jpg">
</li>
<div class="image-hover-text">
<div class="image-hover-text-bubble">
<span class="image-hover-text-title">Sample</span>
This Text display on Hover the Image.
</div>
</div>
</div>
Take a look at css selectors
You're using this selector on the post so i think you're not using the same selector on your code to perform display: none;
#fixed ul li a span{
display: none;
}
This will apply the display: none; in a descendant way (Any element matching span that is a descendant of an element matching a, that is a descendant of an element matching li etc.
#fixed > ul > li > a > span{
display: none;
}
This is a more "strict" way to do almost the same (Any element matching span that is a direct child of an element matching a, etc.)
Both should work (see the example below). So if not, you may have an error on your code that applies inheritance of display property or something similar, or your full code has differences between both selectors (maybe you need to select direct childs and you're selecting descendants).
Try first to apply direct child selector simply adding > between descendants, if not work inspect and try to find where inheritance is applied.
Another possible reason is that you may be using js or jquery to apply display none and it's not catching the selector properly so, try to inspect and fins where is the display property applied. (Maybe you coded a $('#fixed').hide();?
ul#first > li > a > span{display: none;}
ul#second li a span{display: none;}
<ul id="first">
<code>ul#first > li > a > span{display: none;}</code>
<li>icon- <span>a</span></li>
<li>icon- <span>b</span></li>
</ul>
<ul id="second">
<code>ul#second li a span{display: none;}</code>
<li>icon- <span>a</span></li>
<li>icon- <span>b</span></li>
</ul>
<ul id="third">
<code>No css applied</code>
<li>icon- <span>a</span></li>
<li>icon- <span>b</span></li>
</ul>

Change style of element on hover of it's child with just CSS3

I have a site with a changing background image, on hover of certain elements. The image is usually dark, but sometimes light. The light images have the class .whiteImg applied to them.
I have gotten this to work with just CSS, by having the 'background' images set as the sibling of the element that is hovered. For example:
HTML:
<ul>
<li>
<a>link 1</a>
<img src="http://foo.com/" />
</li>
<li>
<a>link 2</a>
<img src="http://foo.com/" />
</li>
<li>
<a>link 3</a>
<img src="http://foo.com/" class="whiteImg" />
</li>
</ul>
CSS:
img{
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
opacity: 0;
transition: opacity 1s;
}
li a:hover + img{
opacity: 1;
}
Now that all works fine. But I have body{color: #fff;} by default but that needs to change to #000 when .whiteImg is visible. I've tried solving this with jQuery (and it's color plugin) but the animation happens after the CSS animation. So I'm looking for a pure CSS solution to *make the body color change to black at the same time as .whiteImg is shown.
Is there anyway to do this? I'm looking for something similar to
li a:hover + img.whiteImg < body {
color: #000;
}
which is inspired by the end of this post but obviously doesn't actually work.
Thanks.
This is the only pure CSS solution I can think:
http://jsfiddle.net/7K83g/3/
li, li * {
position: relative;
z-index: 2;
}
.whiteImg ~ .fakebg {
display: block;
position: absolute;
z-index: 1;
top: 0; left: 0;
width: 100%;
height: 100%;
background: black;
}
This is a 100% solution, uses direction: rtl to apply the right position to the links.
With jQuery instead:
$(document.body).toggleClass("dark");
CSS:
.dark { background: black; color: white; }
Will do the trick.
Example: http://jsfiddle.net/QKAh6/
As the post your refer to suggests, the > selector is a wish, not an actual implementation. Reality is you can't select a parent in CSS.
It also states an alternative jQuery method:
$('p:has(img)');
In your case, this would be:
$('body:has(img.whiteImg)').css('color', '#fff');
Just run this when you are triggering the image change.
Alternatively, to make it easier, you can just add or remove a class to the body when you are starting to fade in the new image.
body {
color: #000;
transition: color 0.4s;
}
body.negative { color: #fff; }

Resources