Overlay border-top on vertical navigation - html

I have this vertical navigation (Here is the jFiddle)
<style>
ul{
list-style-type: none;
}
li{
display: block;
margin: 0;
padding: 10;
border-top: 1px dashed #08C;
}
li:hover{
background-color: #08C;
}
</style>
<ul>
<li>Abc</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
</ul>
A hovered li should be pure blue without any dashed lines on it. Thus, I want that on a hovered li the surrounding dashed border to be solid. It is no problem to change border-top of the hovered li to solid, but I don't know how to change the border-top of the next li element.
I am looking for a simple solution without javaScript.
In short, I would like to get on a hover this:
instead of (what I am currently getting) this:
One solution that came to my mind was to set border-top and border-bot of each li as dashed and on hover to solid. But then, the blue hovered li would be surrounded by 2 dashed lines, so this idea does not work.
Are there any good solutions for this?

Try modifying the next sibling, like this
li:hover + li {
border: solid 1px #08C;
}
See Updated fiddle
Updated based on comments
ul {
list-style-type: none;
}
li {
display: block;
margin: 0;
padding: 10;
border-top: 1px dashed #08C;
}
li:hover {
background-color: #08C;
}
li:hover + li {
border-top: solid 1px #08C;
}
<ul>
<li>Abc</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
</ul>

You could give each li a negative margin-top so that the hover background will cover the border:
ul{
list-style-type: none;
}
li{
display: block;
margin:-1px 0 0 0;
padding: 10px;
border-top: 1px dashed #08C;
}
li:hover{
background-color: #08C;
}
<ul>
<li>Abc</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
</ul>

I vote for ochi's answer, but I would like to point out another solution based on outline:
ul{
list-style-type: none;
}
li{
display: block;
margin: 0;
padding: 10;
border-top: 1px dashed #08C;
}
li:hover{
background-color: #08C;
outline:1px solid #08C;
}
<ul>
<li>Abc</li>
<li>Test 2</li>
<li>Test 3</li>
<li>Test 4</li>
</ul>
Outline just overpaints the border.
Similarly box-shadow: 0px 1px 0px 0px #08C; does not overpaint but shine through between the dots of the dotted border.

Wow! I am new here but i will like to contribute my twopence to your question:
This are my solution which i think may be of help:
Do you know anything about the CSS "nth-child" selector which can help you in customizing your block elements in way which suites you? for instance you can try this:
p:nth-child(odd) {
color: green;
}
<html>
<head>
</head>
<body>
<p>use the nth child</p>
<!...odd 1...>
<p>use the nth child</p>
<!...even 2...>
<p>use the nth child</p>
<!...odd 3...>
<p>use the nth child</p>
<!...even 4...>
<p>use the nth child</p>
<!...odd 5...>
<p>use the nth child</p>
<!...even 6...>
</body>
<html>
This will change those odd block elements to green.
I guess with you knowledge in html you can use this example for your list items background and hover background.
Other values can be the consecutive numbers you want the style to apply to.
Thanks!

Related

Left border on li elements to mark active item

I've searched for this and can't seem to find a decent solution.
I'm trying to make a left border on a given <li> element so it marks the active option. The effect I'm going for is similar to Gmail where they mark the open folder with a red border, e.g:
I inspected how it's done on Gmail but looks like a series of <div>'s. I'm just trying to do it with list items.
I have this: https://jsfiddle.net/5txj3dpe/2/
So my markup is straightforward - a set of list items, with a .active applied to the active element ("Item 2" in this case):
.list-container {
border:1px solid #ccc;
margin-left: 0;
padding-left: 0;
}
li {
list-style: none;
}
li.active {
border-left: 4px solid red;
}
<div class="list-container">
<ul>
<li>Item 1</li>
<li class="active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
I want to make it so that the red border is flush with the .list-container and there is some space between the red border and the text. Basically I want to make it look similiar to the Gmail screenshot.
Please can anyone advise how to do this. Is it possible with an unordered list, or do I need additional <div>'s, etc?
You need to remove the padding on the ul, not the div like you're doing. Then you can add padding to the li elements. Remember to subtract the size of the border from the padding of the active li:
.list-container {
border: 1px solid #ccc;
}
.list-container ul {
padding: 0;
list-style-type: none;
}
.list-container li {
padding-left: 20px;
}
.list-container li.active {
border-left: 4px solid red;
padding-left: 16px; /* 20px - 4px = 16px */
}
<div class="list-container">
<ul>
<li>Item 1</li>
<li class="active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
We'll need to remove the browser's inherited padding from the ul, to make the elements flush with the container. Then we'll give all the li elements a transparent border, and change the border-left-color of the .active element to the desired color.
.list-container {
border: 1px solid #ccc;
margin: 0;
padding: 0;
}
.list-container ul {
padding: 0;
margin: 0;
}
li {
list-style: none;
padding: 5px 20px;
border-left: 4px solid transparent;
}
li.active {
border-left-color: red;
}
<div class="list-container">
<ul>
<li>Item 1</li>
<li class="active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
You could also use box-shadow inset to achieve this.
https://jsfiddle.net/kL5n2d1e/
You should remove the padding from the ul and apply it to the li's this way you can use the border shadow to create the effect you need without moving anything in the flow of the document.
Alternatively you can just add padding to the li and this will also work.
.list-container {
border:1px solid #ccc;
margin-left: 0;
padding-left: 0;
}
ul {
padding:0;
}
li {
list-style: none;
padding: 1em;
}
li.active {
box-shadow: inset 3px 0px 0px red;
}
<div class="list-container">
<ul>
<li>Item 1</li>
<li class="active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
You just need to play with padding and margin parameters to get this effect.
.list-container {
border:1px solid #ccc;
margin-left: 0;
padding-left: 0px;
}
li {
list-style: none;
padding-left:10px;
}
li.active {
border-left: 4px solid red;
margin-left: -4px;
}
The border should be always present. Just make it transparent if li is not active.
.list-container {
border:1px solid #ccc;
margin-left: 0;
padding-left: 0;
}
li {
list-style: none;
padding: 3px 8px;
border-left: 4px solid transparent;
cursor: pointer;
}
li.active {
border-color: red;
}
li:not(.active):hover{
border-color: #ccc;
}
<div class="list-container">
<ul>
<li>Item 1</li>
<li class="active">Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>

Shape (line) under a tab element CSS

I'm a beginner in CSS but I'm currently trying to create a material-design header with "line" under each tab like on this Google site : Our Products | Google
If possible I'd also like the animation when changing tab.
For now my header html is :
<header>
[MY LOGO]
<nav>
<ul>
<li>tab 1</li>
<li>tab 2</li>
<li>tab 3</li>
</ul>
</nav>
</header>
And my CSS :
header {
display: table;
background:#FFF;
box-shadow: 0 0 8px 0 rgba(0,0,0,.3);
width:100vw;
clear: both;
display: table;
overflow: hidden;
white-space: nowrap;
}
nav {
display: inline-block;
margin-left: 5vw;
vertical-align: middle;
}
nav ul {
display: inline-block;
margin 0;
padding: 0;
}
nav li {
display: inline-block;
margin-right: 3vw;
}
nav a {
text-decoration: none;
}
nav a:visited {
color: inherit;
}
nav a:hover,:active,:focus {
color: #b82525;
}
How do I position the shape to be under the .current-nav tab ?
If you inspect the example you have linked to, you will see that one way they do this is by adding a border-bottom to the selected element. You can do this like so
.current-nav {
border-bottom:1px solid #4285f4;
}
They have another technique which is to add an element below, but i'll leave that for you to investigate/reverse engineer.
just use nav ul li a.current-nav{ border-bottom: 1px solid red; } and you are done.
Try this:
<header>
[MY LOGO]
<nav>
<ul>
<li>tab 1</li>
<li>tab 2</li>
<li>tab 3</li>
</ul>
<div class="line-selected right" style="display: block; left: 322px; right: 0.078px;"></div>
</nav>
</header>
The left and right values depends on the sizes of your Logo and of your <li>. You have to change the style of the "line-selected right"class for each event.

On hover over li make second row li move

I am trying to show border color on hover over the list of items. When i move mouse over first row items, the second row items move towards right. Please check jsFiddle
<ul class="tiles">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
css
ul.tiles { width: 400px; }
ul.tiles li {
float: left;
list-style-type: none;
width: 100px;
height: 100px;
margin: 10px;
background: white;
}
ul.tiles li:hover {
border: 1px solid black;
}
}
Add a transparent border to your li:
li {
border: 1px solid transparent;
}
ul.tiles { width: 400px; }
ul.tiles li {
float: left;
list-style-type: none;
width: 100px;
height: 100px;
margin: 10px;
background: white;
}
ul.tiles li:hover {
border: 1px solid black;
}
ul.tiles li {
border: 1px solid transparent;
}
<ul class="tiles">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
you can user box-sizing: border-box; on the ul.tiles li
http://jsfiddle.net/gm8zvfsk/
The box-sizing property is used to tell the browser what the sizing
properties (width and height) should include.
Should they include the border-box or just the content-box which is
the default value of the width and height properties.
For example, if you want two bordered boxes side by side, it can be
achieved through setting box-sizing to "border-box". This forces the
browser to render the box with the specified width and height, and
place the border and padding inside the box.
JS Fiddle.
As Praveen said, using outline fixes the issue.
ul.tiles li:hover {
outline: 1px solid black;
}

Why are these list elements not appearing in a line?

I'm trying to make the navbar elements appear in a row, side by side, with the dropdown one causing a menu to drop down beneath them.
I know there's the nav element and I know there are a thousand jQuery plugins for this. I just want to understand why this isn't working.
http://codepen.io/anon/pen/hjKLD
<!-- Works all the way down to IE7! -->
<header>
<nav>
link
link
<ul class="drop">
<li>
dropdown
</li>
<li class="menu">
link
link
link
link
</li>
</ul>
link
link
</nav>
</header>
li {
list-style-type:none;
margin: 0px;
padding: 0px;
border: 0px;
}
Try
ul, li {
display: inline;
}
Update
I found a quick solution, and without using JavaScript! You might need to make some changes to fix the minor issues.
Here's what I'd suggest for your HTML:
<header>
<nav>
<ul>
<li>link 1</li>
<li>link 2</li>
<li class="menu">Dropdown
<ul class="drop">
<li>link 3</li>
<li>link 4</li>
<li>link 5</li>
<li>link 6</li>
</ul>
</li>
<li>link 7</li>
<li>link 8</li>
</ul>
</nav>
</header>
It's cleaner and more semantic.
Now for the CSS:
a, ul, li {
list-style-type:none;
margin: 0px;
padding: 0px;
border: 0px;
display: inline;
text-decoration: none;
}
a:hover {text-decoration: underline;}
ul {display: inline-block;}
.drop {
display: none;
padding: 5px;
border: 1px solid #000;
background-color: #fff;
}
.menu:hover .drop {
display: block;
position: absolute;
left: 90px;
}
.drop li {display: block;}
No JS required.
Demo via Codepen here.
Need to add display: inline; to the <li> element as well. Otherwise, it's still blocked.
Your list is being displayed as a block element. Which will fill the space horizontaly causing the elements to render vertically.
In order to fix this issue you can chance the display type:
display: inline;
display: inline-block;
Or you can float the element, which will make it no longer fill horizontally and allow the elements to be displayed side by side:
float: left;
See here for more details on css display types http://css-tricks.com/almanac/properties/d/display/
Try this css instead:
a{
vertical-align: top;
}
li {
list-style-type:none;
margin: 0px;
padding: 0px;
border: 0px;
}
ul{
display: inline-block;
margin: 0px;
padding: 0px;
}
This will make them all end up on the same row, but something does still need to be done about the dropdown menu pushing the items to the right further when it's shown.
I think that's what you searching for:
Try this: http://codepen.io/anon/pen/vaEkt
For consistency of markup I swapped the <ul> list in <nav> element.
HTML
<header>
<nav>
link
link
<nav class="drop">
<span>dropdown</span>
<nav class="menu">
link
link
link
link
</nav>
</nav>
link
link
</nav>
</header>
CSS
li {
list-style-type:none;
margin: 0px;
padding: 0px;
border: 0px;
}
nav,
ul {
display: inline-block;
}
.drop {
position: relative;
}
.drop .menu {
position: absolute;
bootom: 0;
left: 0;
}

Best method for displaying a tree list using CSS only (no images or JS, example inside)

I want to display something like this on a HTML page:
With the restriction of using only CSS. The main problem lies in making these: |└ ├ "branches".
The example above was a solution I done myself. Each branch has the same width and consists of:
<ul>
<li></li>
<li></li>
</ul>
The trick is to turn the borders of <li> black accordingly. An image to show this (just a quick mock up)
A problem I've encountered is turning the border white to match the background instead of transparent (apparently CSS has some problem with transparent borders on lists).
My question is: what's the most simplest solution? Is there a better way to do this?
EDIT: Some requirements:
The branch must have fixed width but the height must grow accordingly with the height of the table cell.
The two li elements must take up half of the row's height each such that the - in ├ will always be in the middle.
EDIT2: http://en.wikipedia.org/wiki/Template:Tree_list did a little research. Alas, they use images for branches.
PS: As requested http://jsfiddle.net/q3zdB/2/
The best I can come up with for this is some (unfortunately regrettable) nesting and use of generated content (so it does require a pretty up-to-date browser, so IE < 8 isn't going to look terribly pretty), however, that said, given the HTML:
ul {
padding: 0;
margin: 0;
list-style-type: none;
position: relative;
}
li {
list-style-type: none;
border-left: 2px solid #000;
margin-left: 1em;
}
li div {
padding-left: 1em;
position: relative;
}
li div::before {
content:'';
position: absolute;
top: 0;
left: -2px;
bottom: 50%;
width: 0.75em;
border: 2px solid #000;
border-top: 0 none transparent;
border-right: 0 none transparent;
}
ul > li:last-child {
border-left: 2px solid transparent;
}
<ul>
<li><div>Level 1</div></li>
<li><div>Level 1</div>
<ul>
<li><div>Level 2</div></li>
<li><div>Level 2</div>
<ul>
<li><div>Level 3</div></li>
<li><div>Level 3</div></li>
</ul>
</li>
</ul>
</li>
<li><div>Level 1</div></li>
</ul>
We get this:
JS Fiddle demo
Here's a fork of David's solution eliminating the need for the extra <div> in each <li>:
ul {
padding: 0;
margin: 0;
list-style-type: none;
position: relative;
}
li {
border-left: 2px solid #000;
margin-left: 1em;
padding-left: 1em;
position: relative;
}
li li {
margin-left: 0;
}
li::before {
content:'┗';
color: #000;
position: absolute;
top: -5px;
left: -9px;
}
ul > li:last-child {
border-left: 2px solid transparent;
}
<ul>
<li>Level 1</li>
<li>Level 1
<ul>
<li>Level 2</li>
<li>Level 2
<ul>
<li>Level 3</li>
<li>Level 3</li>
</ul>
</li>
</ul>
</li>
<li>Level 1</li>
</ul>
Demo on JS Bin