Is there a LI equivalent for box-sizing: border-box? - css

I have a nav bar that consists of an UL with several LI items. The active nav button has a different background color, but I also need a small bottom border on the button.
When applying a border, this appears outside of the LI. When working with divs, you can use box-sizing:border-box to get the borders inside the div. But how can you offset the border on a LI item ??? (list-style-position seems to have no effect)
My scss code:
nav {
ul {
li {
float: left;
padding: 0;
box-sizing: border-box;
list-style-position: inside;
&.active {
background-color: white;
border-bottom: solid 6px blue;
box-sizing: border-box;
list-style-position: inside;
}
}
}
}

When working with divs, you can use box-sizing:border-box to get the
borders inside the div.
To clarify, box-sizing:border-box does not make the border to be within the element (change offset), it make the border size be included in the width or height, when set, so i.e. if you give li a height of 25px and bottom border 5px, the inner height will decrease to 20px.
But how can you offset the border on a LI item
You can't offset the border, one workaround to show/hide a border on an element is to use a pseudo element, which will avoid having the element jump/resize when toggle the border, but there are more ways, such as linear-gradient (shown in below sample when hover)
body {
background: lightgray;
}
nav ul li {
position: relative;
float: left;
padding: 0 5px;
list-style-type: none;
}
nav ul li.active::before {
content: '';
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: -6px;
background-color: white;
border-bottom: solid 6px blue;
z-index: -1;
}
/* or one can use linear-gradient */
nav ul li:hover {
background: linear-gradient(
to bottom, white calc(100% - 5px), blue 5px
) no-repeat left bottom;
}
<nav>
<ul>
<li>
Some text
</li>
<li>
Some text
</li>
<li class="active">
Some text
</li>
<li>
Some text
</li>
</ul>
</nav>
Updated
There is actually a way to offset the border, using border-image-outset, shown in this answer:
border-image-outset in CSS

Another fast and clean way to create an inside border is to create an inset shadow without a blur. You don't even need box-sizing or list-style.
nav {
ul {
li {
float: left;
padding: 0;
&.active {
background-color: white;
box-shadow: 0px -6px 0px red inset;
}
}
}
}

Related

Continue list item background color to left of container

I created a to-do list and applied styling that sets even list items to have a light grey background color with li:nth-child(even), but there's a gap to the left of these lines where the white doesn't continue due to setting margin-left: 15px for li elements. I would like the white to be filled in all the way to the left side of the container, but for the text to remain starting 15px to the right of it. How can I accomplish this? Here's the relevant CSS (view CodePen for more):
ul {
list-style: none;
margin: 0;
padding: 0;
}
li {
background: white;
/* distance from the top of the first line of text to the top of the second */
line-height: 40px;
min-height: 40px;
color: #666;
margin-left: 15px;
position: relative;
}
/* Sets color of even li elements */
li:nth-child(even) {
background: #f7f7f7;
}
/* Sets appearance of span content (Bootstrap trash can icon) when user hovers over list item */
li:hover span {
width: 40px; /* Applies to icon background */
opacity: 1.0;
}
Change
margin-left:15px;
to
padding-left:15px;

Pure css tree with borders

I am trying to create a tree with indentations in pure CSS. I have been trying using something like:
ul.tree ul {
padding-left: 5px;
}
However I would like to have a separation between each item in the list. If I use the code above the separating bar gets indented as well so it's not too good.
Here is my current code (I do the indent directly in js, which I don't like): jsfiddle
Ultimately, I want to create something that basically looks like that:
Any idea how to do this in pure CSS? kudos for the simplest answers.
Simple with Multi-level Depth Support
UPDATED: Tweaked to accommodate hover
No extra HTML needed, no having to limit depth because of css selector chaining, as it supports any number of levels deep without having to adjust your css at all for those levels (no keeping track of "padding" to set on the next level deep).
This works well with only a two minor limitations (which I don't believe will factor into affecting you).
See fiddle demo.
Add a position: relative to your ul.tree, but keep all the child elements the default static position. Then change/add the following css:
ul.tree a {
display: block;
height:30px;
line-height: 30px;
padding-left: 15px;
}
/* this is making our bottom border, but sizing off the .tree ul width */
ul.tree a:before {
content: '';
height: 30px; /* match your <a> height */
position: absolute;
left: 0;
right: 0;
z-index: -1;
border-bottom-width: 1px;
border-bottom-color: lightgray;
border-bottom-style: solid;
}
ul.tree a + ul {
padding-left: 15px; /* this is your spacing for each level */
}
ul.tree a:hover:before {
background-color: #DDDDDD;
}
The limitations are that no child elements can have a position set and we are using a pseudo-element (which means it cannot be used for some other feature, but that is probably not an issue either).
For lists with unknown depths, I've used an absolutely positioned element for separating lines. It adds a little extra markup, but seems to work.
div.separator {
position:absolute;
left:0px;
right:0px;
border-top:1px solid lightgray;
}
<ul class="tree">
<li><a>Item1</a><div class="separator"></div></li>
<li><a>Item2</a><div class="separator"></div>
<ul>
<li><a>Item3</a><div class="separator"></div></li>
<li><a>Item4</a><div class="separator"></div></li>
<li><a>Item5</a><div class="separator"></div>
<ul>
<li><a>Item6</a><div class="separator"></div></li>
</ul>
</li>
</ul>
</li>
</ul>
http://jsfiddle.net/7u87c/20/
This CSS makes the link inside a nested li have a padding-left of 30px, and I add another nested li link have padding-left: 60px.
ul.tree li ul li a {
padding-left: 30px;
}
ul.tree li ul li ul li a {
padding-left: 60px;
}
http://jsfiddle.net/7u87c/5/
No extra markup and use of icon image.
Pretty simple and dynamic based on the content.
Sample HTML:
<ul class="tree">
<li><span>public</span></li>
<li><span>server.js</span></li>
<li>
<span>server</span>
<ul>
<li><span>webfs</span></li>
</ul>
</li>
<li><span>specs</span></li>
<li>
<span>src</span>
<ul>
<li>
<span>core</span>
<ul>
<li><span>CellAddress.js</span></li>
</ul>
</li>
</ul>
</li>
</ul>
CSS:
ul.tree {
border-top: 1px solid grey;
}
ul.tree, ul.tree ul {
padding: 0;
margin: 0;
list-style: none;
}
ul span {
display: block;
padding-left: 25px;
border-bottom: 1px solid #666;
height: 25px;
line-height: 25px;
background: url("http://lorempixel.com/10/8/") no-repeat scroll 5px 8px transparent;
}
ul ul span {
padding-left: 35px;
background-position: 15px 8px;
}
ul ul ul span {
padding-left: 45px;
background-position: 25px 8px;
}
Please see example
Note: You can convert the spans into a tags

CSS multiple image positioning

I have two background images, but I cannot display both of them (one of them is invisible).
Another problem is the padding-top for li a element is not working.
HTML:
<ul class="menu">
<li class="item-101 current active">Home</li>
<li class="item-102">Merchants / Shops</li>
<li class="item-103">Contact us</li>
</ul>
CSS:
* {
margin: 0;
}
#left #menu ul.menu {
list-style: none;
padding: 0;
}
#left #menu ul.menu li {
background: url(http://tax.allfaces.lv/templates/tax/images/menu_fons.png) no- repeat, url(http://tax.allfaces.lv/templates/tax/images/bulta_peleka.png) no-repeat;
background-position: left 0px, 200px 0px;
width: 294px;
height: 44px;
padding: 0 0 5px 0;
}
#left #menu ul.menu li a {
text-transform: uppercase;
text-decoration: none;
font-style: italic;
padding: 15px 0 0 17px;
color: #336699;
}
See full example here: http://jsfiddle.net/BWagZ/
The questions are:
1) How to make two background images to appear on button. You can think that the first image is background image for button. But the second image is a small arrow that should be displayed on the right side of the button. Currently this image doesn't appear at all (but it is somwhere there).
2) Why padding-top for li elements are not working? I want text in li element to have top padding in the button.
You must add a div inside anchor tag for double background and cover full button area
Check out fiddle
HTML
<div id="left">
<div id="menu">
<ul class="menu">
<li class="item-101 current active"><div>Home</div></li><li class="item-102"><div>Merchants / Shops</div></li><li class="item-103"><div>Contact us</div></li></ul>
</div>
</div>
CSS
* {
margin: 0;
}
#left #menu ul.menu {
list-style: none;
padding: 0;
}
#left #menu ul.menu li {
background: url(http://tax.allfaces.lv/templates/tax/images/menu_fons.png) no-repeat;
background-position: left 0px, 200px 0px;
width: 294px;
height: 30px;
padding: 14px 0 5px 0;
}
#left #menu ul.menu li a {
text-transform: uppercase;
text-decoration: none;
font-style: italic;
color: #336699;
}
#left #menu ul.menu li a div {
color: #336699;
background:url(http://tax.allfaces.lv/templates/tax/images/bulta_peleka.png) no-repeat center right;
width: 235px;
}
Working fiddle
I think you want the links to have a top-offset in the li element. Then you'd have to set a padding-top in the li element, not the a element, which works for me (Chromium). I don't understand your image-problem.
Try setting some z-index for each background, also when u put the arrow image first you will see both.. now you just have to adjust them.
Is this good enough? http://jsfiddle.net/goodfriend/BWagZ/10/
You should change the order of your backgrounds around.
background: url(http://tax.allfaces.lv/templates/tax/images/bulta_peleka.png) no-repeat 200px 0px,
url(http://tax.allfaces.lv/templates/tax/images/menu_fons.png) no-repeat left 0px;
And the a elements you can adjust by giving them a line-height property.
Here you go: http://jsfiddle.net/MrLister/yFMZf/1
Your method is good. You just have to swapp images between them.
Meaning:
background: url(http://tax.allfaces.lv/templates/tax/images/bulta_peleka.png) no-repeat, url(http://tax.allfaces.lv/templates/tax/images/menu_fons.png) no-repeat;
background-position: 200px 0px, left 0px;
Do you want to achive something like this?
Demo
Answer 1:
Change the orders of the images and positioning accordingly.
Replace your CSS with the following:
#left #menu ul.menu li {
background-image: url(http://tax.allfaces.lv/templates/tax/images/bulta_peleka.png), url(http://tax.allfaces.lv/templates/tax/images/menu_fons.png);
background-position: 200px 7px, left 0px;
background-repeat: no-repeat;
width: 294px;
height: 44px;
padding: 0 0 5px 0;
}
Answer 2:
Add display: block; css rule in the following line:
#left #menu ul.menu li a
It will make the whole list clickable and your padding will work also.

Thicker interior borders compared to outer border

http://jsfiddle.net/MzqYL/3/
In the example above the border of the frame is thinner than the inner borders.
How can I fix this difference?
Image: http://i.stack.imgur.com/FEtio.png
Here's what I have:
body {
margin: 10px;
}
ul {
list-style: none;
width: auto;
margin: 0;
padding: 0;
border: 1px solid black;
border-bottom: 0;
border-right: 0;
}
ul:after {
content: "";
display: table;
height: 0;
}
li {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
float: left;
width: 50%;
}
/* Styles for Menu Items */
ul li a {
text-decoration: none;
color: #777;
padding: 5px;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
li > a {
display: block;
}
ul li a:hover {
color: #E2144A;
background: #f9f9f9;
}
/* Hover Styles */
li ul li a {
padding: 2px 5px;
}
/* Sub Menu Styles */
​
Some points:
Please indent code properly, for yours and ours sake.
What I did is set a left and bottom border on the a elements, and a top and left border on the ul element. This makes a consistent 1px border.
I use clearfix to give the ul height with the floated elements.
I use box-sizing: border-box to make it so that when I set width: 50%, it'll be 50%, including padding and border (not margin).
There is how: http://jsfiddle.net/MzqYL/9/
Basic idea is to define border on two sides for inner elements and add missing borders to main wrapper element.
The problem is that you are stacking the borders so the 1px from the box above + the 1 px from the box below = 2 px. That is why it seems to be thicker.
The way you solve this is by applying different styles to each type of box.
There are 4 types,
Normal box (border on left and on top) Style added
Boxes on the right (border on the left right and top)
Boxes on the bottom (border on the left top and bottom)
The one box that is on the bottom right (all 4 borders)
jsfiddle example
In the example two css classes are added: .right and .last You can just give one box multiple classes <li><a class="right last">...</a></<li> so you can apply styles to the list items easily.

css - horizontal menu - background-color

I have a horizontal menu. I want to have a border around the menu (not the entire-row, only the space menu is covering). When I put border on ul, it covers the entire row, when I put border on li, it has border between menu items as well.
<ul id="menu" style = "text-align:left;">
<li>...anchor stuff...
</li><li>...anchor stuff...
</li><li>...anchor stuff...
</li><li>...anchor stuff...
</li><li>...anchor stuff...</li>
</ul>
Here is the CSS:
ul#menu
{
padding: 0 0 0px;
position: relative;
margin: 0 0 0;
text-align: right;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
ul#menu li
{
display: inline;
list-style: none;
}
ul#menu li a
{
padding: 0px 0px;
margin-right:20px;
font-weight: bold;
text-decoration: none;
line-height: 2.8em;
}
Kill display: inline on the list items and float them left instead. Float the container as well, which will ensure that it's only as wiide as its contents. Finally, set overflow: hidden on the ul.
Declare ul with display:inline-block. It'll cause ul to take only space necessary to display its contents, not 100% of it.
An example
Use display: inline-block on the ul and add the border to the ul.
If you need IE6 compatibility:
#menu li {
border-top: 1px solid #000;
border-bottom: 1px solid #00;
}
You might be able to use li:first-child (I can't remember, and don't have a copy of IE6 to test with) to apply:
#menu li:first-child {
border-left: 1px solid #000;
}
But you'll likely have to add either a class-name, or id, to the first and last li elements to give them the appropriate border-left and border-right.

Resources