I am creating a dropdown menu component using React. I would like to know the CSS required to position the menu element directly under the ".menu-trigger" button, with its right border aligned to its parent's (".menu-container"), right border. I would like this CSS to be able to position a menu element of any reasonable size like this.
I believe I want to position the ".menu" component absolutely, relative to the parent, ".menu-container", element.
Below is a stripped down version of html and css:
<body>
<div className="menu-container">
<button className="menu-trigger">
<span>Drop Down Menu</span>
</button>
<nav className="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</nav>
</div>
</body>
<style>
.menu ul {
list-style: none;
}
.menu-container {
position: relative;
display: inline-block;
}
.menu {
position: absolute;
top: 100%;
}
</style>
**** Edit ****
Solved using flexbox solution:
.menu-container {
display: inline-flex;
flex-direction: column;
align-items: flex-end;
}
Here's how to right-align using flexbox:
.menu-container {
width: 50%;
display: flex; /* flexbox container */
flex-direction: column; /* children in columns */
align-items: flex-end; /* children right-aligned */
background-color: #e0e0e0;
}
.menu-trigger {}
.menu {
background-color: #c0c0c0;
}
.menu ul {
list-style: none;
margin: 0 .5rem;
}
<body>
<h4>Right-alignment using flexbox</h4>
<div class="menu-container">
<button class="menu-trigger">
<span>Drop Down Menu</span>
</button>
<nav class="menu">
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</nav>
</div>
</body>
Related
I'm a beginner, and trying to understand everything. I tried using <p> and it works smoothly but when I insert a text like a ul and li it wont show up
I also tried using a div but only the <a> part is working not the ul and li. I hope someone can help me.
$(document).ready(function() {
$(".more-less").click(function() {
$(this).parent().prev('ul.more').toggleClass("main");
if ($(this).parent().prev('ul.more').hasClass('main')) {
$(this).text('Read Less');
} else {
$(this).text('Read More');
}
});
});
.more {
text-align: left !important;
display: none;
}
.more-less {
/* position: absolute; */
/* right: -30px; */
/* top: -34px; */
color: #e43330 !important;
text-align: center;
float: left;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<p style="text-align: left;">First paragraph then cuts...
<p class="more">Second paragraph.</p>
<p><strong>Header key roles</strong></p>
<ul class="more">
<li>trait 1</li>
<li>trait 2</li>
<li>trait 3</li>
<li>trait 4</li>
<li>trait 5</li>
</ul>
<a class="more-less">Read More</a>
<p> end paragraph</p>
strong text
There's two main issues in your code. Firstly the ul.more is not a parent element of the clicked p, so parents().next() isn't the correct traversal logic to use. As the target element is a sibling of the one which raised the event, use siblings().
Secondly, you need to set display: block on the hidden ul. You can do this through CSS, on the .main class which you toggle.
Also note that you cannot nest p elements. I corrected this in the example below by converting the containing element to a div.
jQuery($ => {
$(".more-less").click(function() {
let $more = $(this).siblings('ul.more').toggleClass("main");
if ($more.hasClass('main')) {
$(this).text('Read Less');
} else {
$(this).text('Read More');
}
});
});
.more {
text-align: left !important;
display: none;
}
.more.main {
display: block;
}
.more-less {
color: #e43330 !important;
text-align: center;
float: left;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div>
First paragraph then cuts...
<p class="more">Second paragraph.</p>
<p><strong>Header key roles</strong></p>
<ul class="more">
<li>trait 1</li>
<li>trait 2</li>
<li>trait 3</li>
<li>trait 4</li>
<li>trait 5</li>
</ul>
<a class="more-less">Read More</a>
<p> end paragraph</p>
</div>
Try delete display: none; from more class
Goal:
Make the list (ul and its li) to be responsive design in relation to the screen's width.
Problem:
I don't know how to solve it.
Info:
*You need to take account to amount of li in each ul list. Different responsive design depends on the width of the ul.
*Each ul can be random from 1 to 10 li or more.
JSBin:
https://jsbin.com/xibalahave/edit?html,css,output
Thank you!
.aaa ul.listlist {
margin: 10px 0 16px;
padding: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.aaa ul.listlist li {
font-size: 1.125rem;
display: block;
margin-right: 24px;
line-height: 22px;
border-radius: 12px 12px 12px 12px;
padding: 8px 24px;
background-color: #00FFFF;
white-space: nowrap;
}
<div class="aaa">
<ul class="listlist">
<li>1Test 1</li>
<li>1Test 2</li>
<li>1Test 3</li>
</ul>
</div>
<br />
<div class="aaa">
<ul class="listlist">
<li>1Test 1</li>
<li>1Test 2</li>
<li>1Test 3</li>
<li>1Test 4</li>
</ul>
</div>
<br />
<div class="aaa">
<ul class="listlist">
<li>1Test 1</li>
<li>1Test 2</li>
</ul>
</div>
You can simply add a flexwrap: wrap; to the container of the li, it will allow the child-elements (here, li), to go to another line. I invite you to learn about the flexbox and all their properties, this is very helpful for the responsive design! Check it out here.
.listlist{
display: flex;
flex-wrap: wrap;
}
This question already has answers here:
How can you set the height of an outer div to always be equal to a particular inner div?
(2 answers)
Closed 2 years ago.
I got a div containing an unordered list and an image.
Currently, the image is bigger, thus increasing the size of the div.
I want the image to have the same height as the unordered list, like this:
How can I do this using HTML/CSS/js?
.container {
display: flex;
}
.list {
list-style-type: none;
}
.picture{
max-width: 100%;
height: auto;
}
<div class="container">
<ul class="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<div>
<img src="https://upload.wikimedia.org/wikipedia/commons/e/ee/Sample_abc.jpg" class="picture" />
</div>
</div>
Example:
https://jsfiddle.net/ck26ybg4/
There is another way to get rid of img and add a picture as a background image, for example:
.container {
width: 50%;
display: grid;
grid-auto-flow: column;
border: 1px solid red;
margin-bottom: 10px; /* demo only */
}
.list {
margin: 0;
padding: 0;
}
.picture{
border: 1px solid green;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
}
<div class="container">
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="picture" style="background-image:url(https://via.placeholder.com/728x90.png)"></div>
</div>
<div class="container">
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<div class="picture" style="background-image:url(https://via.placeholder.com/728x90.png)"></div>
</div>
You can just make the picture container relative and add position: absolute to the image, so it won't affect the flow of the document.
.container {
display: flex;
}
.picture-container {
position: relative;
}
.picture{
position: absolute;
height:100%;
}
<div class="container">
<ul class="list">
<li>Point</li>
<li>Point</li>
<li>Point</li>
</ul>
<div class="picture-container">
<img class="picture" src="https://dummyimage.com/150/efefef/242424"></img>
</div>
</div>
You can use object-fit so the image adapts to the container
The object-fit property defines how an element responds to the height and width of its content box.
For example .picture { object-fit: 'fill' }
I have two divs. When I click on 3 dots , then the div is appearing and on clicking the same 3 dots , same div is disappearing. But I want to hide the div, even if I click anywhere in the document.
There are two circles. When I click on one circle, then a div is shown and when I click on another circle, then the opened div is closing and related div is opening but when I click anywhere on the document, then none of the div are closing.
$("#discussion_declined , #discussion_pending").click(function() {
var relatedDiv = $(this).closest('.panel').find('.discussion_edit_div');
relatedDiv.toggle("fast");
$('.discussion_edit_div').not(relatedDiv).hide('fast');
});
.discussion_small_round_div {
width: 25px;
height: 25px;
border-radius: 50%;
position: relative;
background: #2d3446;
bottom: 9px;
left: 15px;
float: right;
}
.discussion_small_round_div:after {
content: '\2807';
font-size: 1.5em;
color: white;
position: absolute;
left: 9px;
top: 1px;
}
.discussion_edit_div {
background: #FFFFFF;
display: none;
position: absolute;
right: 35px;
border: thin #ced0d1 solid;
z-index: 1001;
width: 150px;
box-shadow: 0px 3px 3px #ccc;
}
ul li {
padding: 5px 15px;
list-style-type: none;
color: #838383;
}
ul li:hover {
background: #eeeded;
cursor: pointer;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="panel discussion_panel_div no_background no_box_shadow" style="position: relative;">
<div class="panel-heading no_border_radius bg-dark set_padding_0">
<div class="discussion_small_round_div pull-right cursor_pointer" id="discussion_declined"></div>
</div>
<div class="discussion_edit_div">
<ul>
<li> <span class="glyphicon glyphicon-trash"></span> Replicate</li>
<li><span class="glyphicon glyphicon-trash"></span> Delete</li>
<li><span class="glyphicon glyphicon-ban-circle"></span> Deactivate</li>
</ul>
</div>
</div>
<div class="panel discussion_panel_div no_background no_box_shadow" style="position: relative;">
<div class="panel-heading no_border_radius bg-dark set_padding_0">
<div class="discussion_small_round_div pull-right cursor_pointer" id="discussion_pending"></div>
</div>
<div class="discussion_edit_div">
<ul>
<li> <span class="glyphicon glyphicon-trash"></span> Replicate</li>
<li><span class="glyphicon glyphicon-trash"></span> Delete</li>
<li><span class="glyphicon glyphicon-ban-circle"></span> Deactivate</li>
</ul>
</div>
</div>
Praveen's answer is nice but you can also achieve the same without tweaking your HTML.
Just add this to your jQuery:
$(window).click(function() {
//Hide the menus if visible
$('.discussion_edit_div').hide('fast');
});
$("#discussion_declined , #discussion_pending").click(function(e) {
e.stopPropagation();
var relatedDiv = $(this).closest('.panel').find('.discussion_edit_div');
relatedDiv.toggle("fast");
$('.discussion_edit_div').not(relatedDiv).hide('fast');
});
And your are good to go.
This achieves one more thing which is that once you have opened one ul, then you can directly toggle to another ul by clicking once. In Praveen's answer you have to click twice in order to open the other ul.
Check the link:https://jsfiddle.net/zfqqqr1c/1/
How Bootstrap handles this is interesting. They have a mask, and the only thing you can click is the mask or the items in the menu.
$(function () {
$(".mask").hide();
$("nav > ul > li > a").click(function () {
$(this).closest("li").addClass("open");
$(".mask").show();
return false;
});
$(".mask").click(function () {
$(this).hide();
$(".open").removeClass("open");
});
});
* {font-family: 'Segoe UI'; margin: 0; padding: 0; list-style: none; line-height: 1; box-sizing: border-box;}
body {background-color: #f5f5f5;}
a {text-decoration: none; color: inherit;}
.mask {position: fixed; top: 0; bottom: 0; right: 0; left: 0; z-index: 8;}
nav > ul > li {display: inline-block; position: relative; width: 30%;}
nav > ul > li a {display: block; padding: 5px; border: 1px solid #ccc;}
nav > ul ul {position: absolute; left: 0; right: 0; z-index: 9; display: none;}
nav > ul > li.open > ul {display: block;}
<script src="https://code.jquery.com/jquery-2.2.4.js"></script>
<div class="mask"></div>
<nav>
<ul>
<li>
Main Item 1
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
<li>Sub Item 4</li>
<li>Sub Item 5</li>
</ul>
</li>
<li>
Main Item 2
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
<li>Sub Item 4</li>
<li>Sub Item 5</li>
</ul>
</li>
<li>
Main Item 3
<ul>
<li>Sub Item 1</li>
<li>Sub Item 2</li>
<li>Sub Item 3</li>
<li>Sub Item 4</li>
<li>Sub Item 5</li>
</ul>
</li>
</ul>
</nav>
I successfully created this not so bad css-only dropdown. I'm trying to hide the .submenutwo so that it is only visible when .submenu is on hover. If we can do this with css only that would be nice. But if javascript or jQuery can help it's fine.
/* define a fixed width for the entire menu */
.navigation {
min-width: 300px;
}
/* reset our lists to remove bullet points and padding */
.mainmenu,
.submenu {
list-style: none;
padding: 0;
margin: 0;
}
/* make ALL links (main and submenu) have padding and background color */
.mainmenu a {
display: block;
background-color: #CCC;
text-decoration: none;
padding: 10px;
color: #000;
}
/* add hover behaviour */
.mainmenu a:hover {
background-color: #C5C5C5;
}
/* when hovering over a .mainmenu item,
display the submenu inside it.
we're changing the submenu's max-height from 0 to 200px;
*/
.mainmenu li:hover .submenu {
display: block;
min-height: 200px;
height: auto;
}
/*
we now overwrite the background-color for .submenu links only.
CSS reads down the page, so code at the bottom will overwrite the code at the top.
*/
.submenu a {
background-color: #999;
}
/* hover behaviour for links inside .submenu */
.submenu a:hover {
background-color: #666;
}
/* this is the initial state of all submenus.
we set it to max-height: 0, and hide the overflowed content.
*/
.submenu {
overflow: hidden;
max-height: 0;
-webkit-transition: all 0.5s ease-out;
}
<nav class="navigation">
<ul class="mainmenu">
<li>Apples
<ul class="submenu">
<li>Green Apples
<ul class="submenutwo">
<li class='listOptionLvlThree'> Option 3
</li>
<li class='listOptionLvlThree'> Option 3
</li>
<li class='listOptionLvlThree'> Option 3
</li>
</ul>
</li>
</ul>
</li>
<li>Oranges
<ul class="submenu">
<li>Option 2
</li>
<li>Option 2
</li>
<li>Option 2
</li>
</ul>
</li>
<li>Grapes
<ul class="submenu">
<li>Purple Grapes
<ul class="submenutwo">
<li class='listOptionLvlThree'> Option 3
</li>
<li class='listOptionLvlThree'> Option 3
</li>
<li class='listOptionLvlThree'> Option 3
</li>
</ul>
</li>
<li>Green Grapes
</li>
<li>Red Grapes
</li>
</ul>
</li>
</ul>
</nav>
.submenutwo {
display: none }
.submenu:hover .submenutwo {
display: initial }
Here's how you can do it in css. Basically, what's happening here is. At first, you just need to hide .submenutwo. After the hover triggered, you just need to bring back the display to the default or even other display value will do.
may be this will help u
/* define a fixed width for the entire menu */
.navigation {
min-width: 300px;
}
.submenutwo {
display: none }
.submenu:hover .submenutwo {
display: initial }
/* reset our lists to remove bullet points and padding */
.mainmenu, .submenu {
list-style: none;
padding: 0;
margin: 0;
}
/* make ALL links (main and submenu) have padding and background color */
.mainmenu a {
display: block;
background-color: #CCC;
text-decoration: none;
padding: 10px;
color: #000;
}
/* add hover behaviour */
.mainmenu a:hover {
background-color: #C5C5C5;
}
/* when hovering over a .mainmenu item,
display the submenu inside it.
we're changing the submenu's max-height from 0 to 200px;
*/
.mainmenu li:hover .submenu {
display: block;
min-height: 200px;
height:auto;
}
/*
we now overwrite the background-color for .submenu links only.
CSS reads down the page, so code at the bottom will overwrite the code at the top.
*/
.submenu a {
background-color: #999;
}
/* hover behaviour for links inside .submenu */
.submenu a:hover {
background-color: #666;
}
/* this is the initial state of all submenus.
we set it to max-height: 0, and hide the overflowed content.
*/
.submenu {
overflow: hidden;
max-height: 0;
-webkit-transition: all 0.5s ease-out;
}
<nav class="navigation">
<ul class="mainmenu">
<li>Apples
<ul class="submenu">
<li>Green Apples
<ul class="submenutwo">
<li class='listOptionLvlThree'> Option 3</li>
<li class='listOptionLvlThree'> Option 3</li>
<li class='listOptionLvlThree'> Option 3</li>
</ul>
</li>
</ul>
</li>
<li>Oranges
<ul class="submenu">
<li>Option 2</li>
<li>Option 2</li>
<li>Option 2</li>
</ul>
</li>
<li>Grapes
<ul class="submenu">
<li>Purple Grapes
<ul class="submenutwo">
<li class='listOptionLvlThree'> Option 3</li>
<li class='listOptionLvlThree'> Option 3</li>
<li class='listOptionLvlThree'> Option 3</li>
</ul>
</li>
<li>Green Grapes</li>
<li>Red Grapes</li>
</ul>
</li>
</ul>
</nav>