I have an inline-flex element book-ended by two inline block elements. They are all different heights but I want to align them to their vertical centres.
In webkit this is possible by applying position: relative; top: 53px; to the inline-block elements. However, in firefox this puts the inline blocks way below where I want them.
Removing the top offset I can see that the default position of the elements is completely different in webkit and firefox.
Here's a fiddle: https://jsfiddle.net/ralphonz/p9s1pjtd/29/
Here's my HTML:
<div class="newsletter-navigation" role="navigation">
<div class="arrow prev-arrow">
<svg width="100%" height="100%" viewBox="0 0 20 37" version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path id="Arrow-Right-Icon" d="M18.64 32.359L6.323 18.569 18.64 4.78c.923-1.035.923-2.711 0-3.744-.924-1.035-2.421-1.035-3.344 0L1.356 16.642c-.474.531-.701 1.23-.688 1.927-.013.695.214 1.396.688 1.927l13.94 15.606c.923 1.033 2.42 1.033 3.344 0 .923-1.034.923-2.71 0-3.743z" fill="#6d4272"></path></svg>
</div>
<ul class="nav nav-pills">
<li class="archive-year">2017
<ul class="nav">
<li class="nav-item">Item 1</li>
<li class="nav-item">Item 2</li>
<li class="nav-item">Item 3</li>
<li class="nav-item">Item 4</li>
<li class="nav-item">Item 5</li>
</ul>
</li>
<li class="archive-year">2016
<ul class="nav">
<li class="nav-item">Item 1</li>
<li class="nav-item">Item 2</li>
<li class="nav-item">Item 3</li>
<li class="nav-item">Item 4</li>
<li class="nav-item">Item 5</li>
</ul>
</li>
</ul>
<div class="arrow next-arrow">
<svg width="100%" height="100%" viewBox="0 0 20 37" version="1.1" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" fill-rule="evenodd" clip-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="1.414"><path id="Arrow-Right-Icon" d="M18.64 32.359L6.323 18.569 18.64 4.78c.923-1.035.923-2.711 0-3.744-.924-1.035-2.421-1.035-3.344 0L1.356 16.642c-.474.531-.701 1.23-.688 1.927-.013.695.214 1.396.688 1.927l13.94 15.606c.923 1.033 2.42 1.033 3.344 0 .923-1.034.923-2.71 0-3.743z" fill="#6d4272"></path></svg>
</div>
</div>
and here's my SCSS:
.newsletter-navigation {
width: 100vw;
position: relative;
margin-bottom: 2em;
padding: 0 2em 2em;
background-color: rgb(230,230,230);
.arrow {
display: inline-block;
position: relative;
top: 53px;
width: 19px;
height: 37px;
cursor: pointer;
color: rgb(109,66,114);
}
.prev-arrow {
margin-right: .5em;
}
.next-arrow {
margin-left: .5em;
transform: rotate(180deg);
}
ul.nav {
display: inline-flex;
flex-wrap: nowrap;
width: 100%;
overflow: scroll;
li {
width: 25vw;
margin-right: 1em;
padding: 1em 2em;
background-color: rgb(31,148,195);
border-radius:.5em;
color: #fff;
ul {
padding: 0;
}
}
.nav-item {
text-align: center;
}
.archive-year {
width: auto;
margin: 0;
padding: 0;
background-color: transparent;
color: rgb(128, 128, 128);
}
}
&>ul.nav {
width: 85%;
}
}
How can I get a consistent, cross-browser result and achieve my goal of vertical centre alignment?
Since you’re using flexbox anyway, may as well use it to align your elements vertically.
#container {
align-items: center;
display: flex;
}
.small {
background: #fcc;
}
.big {
background: #ccf;
font-size: 2em;
}
<div id="container">
<span class="small">flexbox</span>
<span class="big">vertical</span>
<span class="small">alignment</span>
</div>
Updated fiddle
Related
I'm trying to make a drop-down menu that opens by click. I am trying to use the target property how below for this, but in vain. Could someone suggest how to fix the code?
:target + .parent > ul {
display:block;
position:absolute;
z-index:9999;
}
.parent {
display: block;
position: relative;
float: left;
line-height: 30px;
background-color: black;
border-right: #CCC 1px solid;
}
.parent a {
margin: 10px;
color: #FFFFFF;
text-decoration: none;
}
:target + .parent > ul {
display:block;
position:absolute;
z-index:9999;
}
.child {
display: none;
}
.child li {
background-color: #E4EFF7;
line-height: 30px;
border-bottom: #CCC 1px solid;
border-right: #CCC 1px solid;
width: 100%;
background-color: black;
}
.child li a {
color: #FFF;
color: red;
}
ul {
list-style: none;
margin: 0;
padding: 0px;
min-width: 10em;
}
ul ul ul {
/* left: 100%;
top: 0;
margin-left:1px;
*/
}
li:hover {
background-color: red;
}
.parent li:hover {
background-color: #F0F0F0;
}
.expand {
font-size: 12px;
float: right;
margin-right: 5px;
color: red;
}
nav {
margin: 0 auto;
display: table;
text-align: center;
}
nav ul {
text-align: center;
}
<nav>
<ul id="menu">
<li class="parent">
CAT 1
<ul class="child">
<li class="parent">
<a href="#">Video Games <span class="expand">
▼</span></a>
<ul class="child">
<li>Car</li>
<li class="parent">
<a href="#">Bike Race<span class="expand">
▼</span></a>
<ul class="child">
<li>Yoyo</li>
<li>Doctor Kit</li>
</ul>
<li>Fishing</li>
</ul>
</li>
<li>Barbies</li>
<li>Teddy Bear</li>
<li>Golf Set</li>
</ul>
</li>
<li class="parent">
CAT 2
<ul class="child">
<li>Yoyo</li>
<li>Doctor Kit</li>
<li class="parent">
<a href="#">Fun Puzzle<span class="expand">
▼</span></a>
<ul class="child">
<li><a href="#" nowrap>Cards</a></li>
<li><a href="#" nowrap>Numbers</a></li>
</ul>
</li>
<li>Uno Cards</li>
</ul>
</li>
<li class="parent">CAT 3
<li class="parent">CAT 4
<li class="parent">CAT 5
<li class="parent">CAT 6
<li class="parent">
CAT 7
<ul class="child">
<li>Battery Toys</li>
<li class="parent">
<a href="#">Remote Toys <span class="expand">
▼</span></a>
<ul class="child">
<li>Cars</li>
<li>Aeroplane</li>
<li>Helicopter</li>
</ul>
</li>
<li>Soft Toys
</li>
<li>Magnet Toys</li>
</ul>
</li>
</ul>
</nav>
You need to reference your child element, which should be displayed on click, in your anchor by setting an ID like #child-1: CAT 1
Add child-1 as ID to your child element, so that your anchor and your child are "connected". <ul class="child" id="child-1">. Now this child element will be addressed by the :target selector, when the anchor is clicked
Since the target selector addresses the child-element, your CSS can look like this ul:target { ... }.
Note: Keep in mind that IDs must be unique for each anchor/child pair.
Source with an executable example: https://www.w3schools.com/cssref/sel_target.asp
Additional: You want to implement a nested dropdown in your code. I'm not sure if this nested behavior is possible to be implemented in pure CSS, because you can not address the parent element in CSS, and therefore you have no chance to keep the parent(s) displayed, while the child is shown. If someone has any idea, please let me know!
.parent {
display: block;
position: relative;
float: left;
line-height: 30px;
background-color: black;
border-right: #CCC 1px solid;
}
.parent a {
margin: 10px;
color: #FFFFFF;
text-decoration: none;
}
ul:target {
display:block;
position:absolute;
z-index:9999;
}
.child {
display: none;
}
.child li {
background-color: #E4EFF7;
line-height: 30px;
border-bottom: #CCC 1px solid;
border-right: #CCC 1px solid;
width: 100%;
background-color: black;
}
.child li a {
color: #FFF;
color: red;
}
ul {
list-style: none;
margin: 0;
padding: 0px;
min-width: 10em;
}
ul ul ul {
/* left: 100%;
top: 0;
margin-left:1px;
*/
}
li:hover {
background-color: red;
}
.parent li:hover {
background-color: #F0F0F0;
}
.expand {
font-size: 12px;
float: right;
margin-right: 5px;
color: red;
}
nav {
margin: 0 auto;
display: table;
text-align: center;
}
nav ul {
text-align: center;
}
<nav>
<ul id="menu">
<li class="parent">
CAT 1
<ul class="child" id="child-1">
<li class="parent">
<a href="#child-1-1">Video Games <span class="expand">
▼</span></a>
<ul class="child" id="child-1-1">
<li>Car</li>
<li class="parent">
<a href="#child-1-1-1">Bike Race<span class="expand">
▼</span></a>
<ul class="child" id="child-1-1-1">
<li>Yoyo</li>
<li>Doctor Kit</li>
</ul>
<li>Fishing</li>
</ul>
</li>
<li>Barbies</li>
<li>Teddy Bear</li>
<li>Golf Set</li>
</ul>
</li>
<li class="parent">
CAT 2
<ul class="child" id="child-2">
<li>Yoyo</li>
<li>Doctor Kit</li>
<li class="parent">
<a href="#child-2-1">Fun Puzzle<span class="expand">
▼</span></a>
<ul class="child" id="child-2-1">
<li><a href="#" nowrap>Cards</a></li>
<li><a href="#" nowrap>Numbers</a></li>
</ul>
</li>
<li>Uno Cards</li>
</ul>
</li>
<li class="parent">CAT 3
<li class="parent">CAT 4
<li class="parent">CAT 5
<li class="parent">CAT 6
<li class="parent">
CAT 7
<ul class="child" id="child-7">
<li>Battery Toys</li>
<li class="parent">
<a href="#child-7-1">Remote Toys <span class="expand">
▼</span></a>
<ul class="child" id="child-7-1">
<li>Cars</li>
<li>Aeroplane</li>
<li>Helicopter</li>
</ul>
</li>
<li>Soft Toys
</li>
<li>Magnet Toys</li>
</ul>
</li>
</ul>
</nav>
This is look I'm trying to achive
<ul>
<li class="btn">A</li>
<li class="btn" hidden>B</li>
<li class="btn" hidden>C</li>
<li >D</li>
<li >E</li>
</ul>
or it can be like this
<ul>
<li class="btn">A</li>
<li class="btn" hidden>B</li>
<li class="btn">C</li>
<li >D</li>
<li >E</li>
</ul>
and this too
<ul>
<li class="btn">A</li>
<li class="btn">B</li>
<li class="btn">C</li>
<li >D</li>
<li >E</li>
</ul>
I tried css first and last child it did not work. button set need to appear as a group and first and last element need to be rounded, in some cases, the button group might have only two buttons, or just one. any advice ?
ul li.btn:first-child {
padding-left: 7px;
border-radius: 50px 0px 0px 50px;
}
ul li.btn:last-child {
padding-right: 7px;
border-radius: 0px 50px 50px 0px;
}
You were on the right track. This is what you are looking for:
ul {
list-style: none;
display: flex;
}
li {
padding: 16px;
}
li.group {
background-color: lightgray;
}
li.first {
border-radius: 50% 0 0 50%;
}
li.last {
border-radius: 0 50% 50% 0;
}
<ul>
<li class="group first">A</li>
<li class="group">B</li>
<li class="group">C</li>
<li class="group">D</li>
<li class="group last">E</li>
<li>F</li>
<li>G</li>
</ul>
Edit If you do not want the first and last class, this is a workaround
NOTE: this only works in this specific case:
group of buttons is always at the start
there is only one group, no other elements in between
this actually moves element B to the back
ul {
list-style: none;
display: flex;
}
li {
padding: 16px;
}
li.group {
background-color: lightgray;
}
li.group:first-child {
border-radius: 50% 0 0 50%;
}
li.group~.group~.group {
border-radius: 0;
order: 0;
}
li.group~li.group {
border-radius: 0 50% 50% 0;
order: 1;
}
li:not(.group) {
order: 2;
}
<ul>
<li class="group">A</li>
<li class="group">B</li>
<li class="group">C</li>
<li class="group">D</li>
<li class="group">E</li>
<li>F</li>
<li>G</li>
</ul>
ul {
list-style: none;
display: flex;
}
li {
padding: 16px;
}
li.btn {
background-color: lightgray;
}
ul li.btn:first-child {
border-radius: 50% 0 0 50%;
}
ul li.btn:last-child {
border-radius: 0 50% 50% 0;
}
<ul>
<li class="btn">A</li>
<li class="btn" hidden >B</li>
<li class="btn">C</li>
<li >D</li>
<li >E</li>
</ul>
Do you want to group the list items no matter how many items available ?
i think this is what you need:
.group,
.list {
display: flex;
align-items: center;
}
.list>div:not(.group) {
padding: 5px;
}
.group>div {
padding: 5px;
border: 1px solid #ccc;
}
.group>div:first-child {
border-radius: 5px 0 0 5px;
}
.group>div:last-child {
border-radius: 0 5px 5px 0;
}
<div class="list">
<div class="group">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<div>D</div>
<div>E</div>
<div class="group">
<div>A</div>
<div>B</div>
<div>C</div>
</div>
<div>D</div>
<div>E</div>
</div>
I'm using bootstrap 3.3.7
I have created dropdown menus and sub-menus down to 4 levels and so far it is working as expected using a combination of li and ul elements. The trouble is that some of the menu dropdowns are quite large, so I want to force scrollbars and height to contain the size of the dropdowns on screen.
On my top level dropdown I've added the following style to the css:
height:300px; overflow-y:scroll; overflow:hidden;
this has given me the desired effect on the first and second level dropdown (both have scroll bars and sit side by side) on the next level it displays inside the second level's container. when this should also be outside. (my code below doesn't show correctly using the code snippet tool for some reason, but if you place the code locally it shows correctly as far as it goes).
Basically if you take the default way that bootstrap creates menu's and submenus where each submenu appears to the right of the parent and slightly down. My goal is to set the top of each level to the top of the first level menu keeping the height of each level the same with scrollbars when necessary.
body {
font-family: EvaluateFont, Arial, sans-serif;
font-weight: bold;
font-size: 9pt;
padding-top: 70px;
}
.navbar {
height: 70px;
}
.navbar-toggle {
top: -8px;
left: 0px;
width: 64px;
height: 69px !important;
border-style: none;
padding-top: 0px;
padding-bottom: 0px;
padding-left: 20px !important;
padding-right: 20px !important;
background-color: lightblue;
border-radius: 0 0 0 0;
-webkit-border-radius: 0 0 0 0;
-moz-border-radius: 0 0 0;
float: left !important;
}
.scrollable-menu {
height: 75px;
overflow-x: hidden;
overflow-y: auto;
}
.dropdown-menu { /* This is valid in the browser.*/
width: max-content;
border-bottom:none;
}
.dropdown-menu.main {
top: 161px !important;
height: 75px;
border: 0;
outline: none;
}
.wrapper {
position: relative;
cursor:auto;
}
li {
position: static;
list-style: none;
color: #333;
font-weight: 400;
white-space: nowrap;
// submenu
ul.wrapper {
// position on top of the menu item
position: absolute;
// top matches top
//top: 0;
// left matches 75% of menu item width
// left: 75%;
// show on top of the menu item
z-index: 10; /*put this to -1 once click state has been implemented (will put it below the scrollbar)*/
// do not show the submenu by default
display: none;
}
// display the submenu when we hover on the menu item
&:hover > .wrapper {
display: block;
top: 85px !important;
border: 0;
outline: none;
left: 235px;
width: auto;
}
}
li.level-1, li.level-2, ul.level-3 {
margin-left: -30px;
a {
display: block;
padding: 5px;
white-space: nowrap;
clear: both;
}
}
ul.level-2 > li {
margin-left: -25px;
}
ul.menu-list {
background-color:#b200ff;
}
ul.wrapper.level-2 {
background-color: #ff6a00;
width: 100%;
}
ul.wrapper.level-3 {
background-color: #451968;
width: 100%;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-collapse collapse">
<ul class='nav navbar-nav'>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<span class="fa fa-pencil"></span> CREATE REPORT
<span class="caret"></span>
</a>
<div class="dropdown-menu">
<ul>
<li class="dropdown-submenu not-visible"><span class="text">Choose a type of report.</span><i class="fa fa-close pull-right icon-dropdown"></i></li>
</ul>
<ul class="scrollable-menu menu-list">
<li class="parent level-1" >
report set 1
<ul class="wrapper level-2" role="menu" aria-labelledby="comenu">
<li>rep 1</li>
<li>rep 2</li>
<li>rep 3</li>
</ul>
</li>
<li class="parent level-1">
rep set 2
<ul class="wrapper scrollable-menu menu-list level-2">
<li>rep 1</li>
<li>rep 2</li>
<li>rep 3</li>
<li>rep 4</li>
<li>rep 5</li>
<li>rep 6</li>
<li>rep 7</li>
<li class="parent level-2">
rep 7 sub
<ul class="wrapper menu-list level-3">
<li>sub 1</li>
<li>sub 2</li>
<li>sub 3</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
</nav>
</body>
</html>
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
I'm completely stuck and have been struggling with this for days because I'm not a developer and just learn from forums.
I cannot modify the li classes with the price and table, restriction on code blocks to generate this from my ecommerce platform. I would like to get the results displayed in two rows, qty on top and price on bottom.
96 150 300 450 600
8.06 7.66 7.26 6.86 5.97
li.QtyTabQty {
display: inline-block;
/* text-align: right; */
border-right: 1px solid #fff;
/* width: 100%; */
/* float: right; */
/* width: 100%; */
}
li.QtyTabPrc {
display: inline-block;
text-align: right;
border-right: 1px solid #fff;
/* width: 100%; */
float: right;
}
<ul class="none">
<li class="QtyTabQty">96</li>
<li class="QtyTabPrc">$8.06</li>
<li class="QtyTabQty">150</li>
<li class="QtyTabPrc">$7.66</li>
<li class="QtyTabQty">300</li>
<li class="QtyTabPrc">$7.26</li>
<li class="QtyTabQty">450</li>
<li class="QtyTabPrc">$6.86</li>
<li class="QtyTabQty">600</li>
<li class="QtyTabPrc">$5.97</li>
</ul>
if you want use lists you can do with flexbox:
.none {
display: flex;
flex-flow: column wrap;
/* height is required */
height: 50px;
}
.none li {
list-style: none;
flex: 1;
/* Modify padding as required */
padding: 0 7px;
}
<ul class="none">
<li class="QtyTabQty">96</li>
<li class="QtyTabPrc">$8.06</li>
<li class="QtyTabQty">150</li>
<li class="QtyTabPrc">$7.66</li>
<li class="QtyTabQty">300</li>
<li class="QtyTabPrc">$7.26</li>
<li class="QtyTabQty">450</li>
<li class="QtyTabPrc">$6.86</li>
<li class="QtyTabQty">600</li>
<li class="QtyTabPrc">$5.97</li>
</ul>
Another option...pretty close to what you already have.
li.QtyTabQty {
display: inline-block;
position:absolute;
}
li.QtyTabPrc {
display: inline-block;
float:left;
margin-top:30px;
margin-right:10px;
}
<ul class="none">
<li class="QtyTabQty">96</li>
<li class="QtyTabPrc">$8.06</li>
<li class="QtyTabQty">150</li>
<li class="QtyTabPrc">$7.66</li>
<li class="QtyTabQty">300</li>
<li class="QtyTabPrc">$7.26</li>
<li class="QtyTabQty">450</li>
<li class="QtyTabPrc">$6.86</li>
<li class="QtyTabQty">600</li>
<li class="QtyTabPrc">$5.97</li>
</ul>