How to create dynamic bracket borders around content? - css

I'm trying to add this gray bracket to the right of a list. I tried playing around with borders on the div around the each item, but the items are separated by a few other tags and margin space top and bottom, also I don't know how to get only part of a top border showing. I need the brackets to expand and stay aligned if a selected item is expanded.
Any CSS recommendations?
This is where I'm at now https://jsfiddle.net/ux9dxoa9/
.item {
float: left;
clear:left;
border: 2px solid red;
padding: 8px 0px;
height: 100px;
width: 100px;
}
.other_div{
float: left;
padding: 18px 0px;
height: 100px;
width: 100px;
}

You can use pseudo elements
* {
margin: 0; padding: 0; box-sizing: border-box;
}
.outer {
display: inline-block;
border-right: 1px solid #ddd;
margin-left: 30px;
}
.outer, .outer > li {
position: relative;
}
.outer > li {
padding: 1em;
}
.outer:before, .outer:after, .outer > li:not(:first-child):before {
content: '';
position: absolute;
width: .5em;
height: 1px;
background: #ddd;
}
.outer:before, .outer:after, .outer > li:before, .outer > li:after {
right: 0;
}
.outer:before, .outer > li:before {
top: 0;
}
.outer:after, .outer > li:after {
bottom: 0;
}
<ul class="outer">
<li>item</li>
<li>item</li>
<li>nested
<ul>
<li>nested</li>
<li>nested</li>
<li>nested</li>
</ul>
</li>
<li>item</li>
<li>item</li>
</ul>

Related

How to create progress steps in CSS

I have a list of items that I want to turn into a progress steps in CSS.
ol {
width: 800px;
}
li {
display: inline-block;
color: transparent;
height: 25px;
width: 25px;
background-color: #abc;
border-radius: 50%;
border: 2px solid #08f;
margin-right: 150px;
}
li:last-child {
margin-right: 0;
}
li:not(:last-child)::before {
content: "";
border: 2px solid #08f;
margin-left:25px;
width: 153px;
display: inline-block;
}
<ol>
<li>Step 1</li>
<li>Step 2</li>
<li>Step 3</li>
<li>Step 4</li>
</ol>
What I ideally want to do is:
Stop Step 4 from disappearing off the bottom
Use the content of the <li> as a label above the circle
Make the total width equal to 80% of the viewport width
I'm just trying to teach myself some more advanced CSS, and I've seen this pattern used somewhere else - but I've been trying for an hour or so to get there with no joy.
This is a learning exercise for me, so would love some explanation with the answer if you have the time.
Thanks,
body {
display: grid;
place-items: center;
margin: 0;
padding: 36px;
}
ol {
display: flex;
width: 80%;
padding: 12px 0;
}
li {
position: relative;
padding: 0;
flex-grow: 1;
height: 2px;
background: #08f;
display: flex;
align-items: center;
}
li:last-child {
margin-right: 0;
flex-grow: 0;
}
li::after {
content: "";
position: absolute;
left: 0;
display: inline-block;
color: transparent;
height: 24px;
width: 24px;
background: #abc;
border-radius: 50%;
border: 2px solid #08f;
}
span {
position: absolute;
top: -36px;
left: 12px;
width: max-content;
transform: translateX(-50%);
z-index: 1;
}
<ol>
<li><span>Step 1</span></li>
<li><span>Step 2</span></li>
<li><span>Step 3</span></li>
<li><span>Step 4</span></li>
</ol>
In my code the nodes are the pseudo elements, and I use the flex-grow property so that the rules (that are the li tags) are properly distributed. font-size: 0 hides the text and removes it from the content-size of the elements as well.
---- edit:
I removed the font-size: 0 and added span tags for the labels and the css to position it.

Why doesn't menu on drop down appear over content?

I've got a drop down menu that won't appear over the rest of the content. I've set the position to absolute and the z-index to 99 and no luck. Any ideas how to get it to lay on top of the rest of the site?
<body>
<header>
<div class="container">
<h1 class="logo">Relaxr</h1>
<nav>
</span>
<ul>
<li>Home</li>
<li>About</li>
<li>Contact</li>
<li>Blog</li>
</ul>
</nav>
</div>
</header>
<section id="main">
<div class="container">
nav {
position: relative;
}
nav ul {
display: none;
}
header {
margin-left: -20px;
margin-right: -20px;
}
body {
margin-left: 20px;
margin-right: 20px;
}
.container {
width: 100%;
margin: 0;
}
#main {
margin-top: 10px;
}
header nav ul li {
display: block;
margin-right: 20px;
margin: 0 20px 0 0;
}
.hamburger {
margin-top: 5px;
margin-right: 80px;
margin-bottom: 20px;
float:right;
position: relative;
display: inline-block;
width: 1.5em;
height: 0.74em;
border-top: 0.2em solid #fff;
border-bottom: 0.2em solid #fff;
}
.hamburger:before {
content: "";
position: absolute;
top: 0.9em;
left: 0px;
width: 100%;
border-top: 0.2em solid #fff;
}
nav ul {
position: absolute;
left: 0; top: 100%;
width: 100%;
background-color: black;
z-index: 99;
Codepen:
http://codepen.io/kiddigit/pen/wWvPJm
In your #media query change
nav {
position: relative;
}
to
nav {
position: absolute;
}
This will keep your menu on top.
I think You should use something like this to work
$(".hamburger").click(function(e){
$("nav > ul").toggle();
});
there is only one difference I've added a closing bracket in
$("nav > ul").toggle();

CSS3 li ul auto size issue

I have created a small drop down menu.. the issue is I don't want it to be a 200px button link unless it needs to in order to make the text fit. example where it says drop downlink that will be a dynamic link if register has 7 letters but drop downlink has 12 I don't want register to be 200px wide.
<ul class="tactical-nav-isolate">
<li>Register</li>
<li>Login</li>
<li class="account-dropdown">
Dropdown Link<span class="glyphicon glyphicon-menu-down account-dropdown-icon"></span>
<ul class="account-dropdown-nav">
<li>My Profile</li>
<li>My Account</li>
<li>Logout</li>
</ul>
</li>
</ul>
* {
-moz-box-sizing: border-box;
box-sizing: border-box;
}
ul {
list-style: none;
padding: 0;
margin: 0;
}
.tactical-nav-isolate {
text-align: center;
}
.account-dropdown-nav {
background: #000000;
text-align: left;
text-indent: 15px;
}
.tactical-nav-isolate {
float: right;
margin-top: 0px;
border-left: solid 1px #1e2a36;
}
.tactical-nav-isolate > li {
float: left;
border-left: solid 1px #1e2a36;
}
.tactical-nav-isolate li:first-child {
border-left: none;
}
.tactical-nav-isolate a {
color: #fff;
display: block;
line-height: 50px;
width: 200px;
text-decoration: none;
}
.account-dropdown {
position: relative;
}
.account-dropdown:after {
font-size: .5em;
display: block;
position: absolute;
top: 38%;
right: 12%;
}
.account-dropdown-icon {
text-indent: 5px;
}
.account-dropdown-nav {
position: absolute;
display: none;
}
.account-dropdown-nav li {
border-bottom: 1px solid rgba(255,255,255,.2);
}
.account-dropdown:hover > .account-dropdown-nav {
display: block;
background-image: url(../../media/opacityBG.png);
}
I am not one hundred percent sure what you are asking for, but if your question pertains to having a non-uniform width that fits your <a> tags then all you would need to do is uncomment the following:
.tactical-nav-isolate a {
//display: block;
}
look at this to see the difference between block and inline elements:

Child take width % from parents parent

Is the following result possible with CSS:
So that li.item takes 50% of the width of div.wrapper, not the ul.list (which is extremly long).
I've added a snippet of a basic setup. Any ideas on the matter are appreciated (please keep in mind I'm looking for CSS options). A jsfiddle playground link: http://jsfiddle.net/6o8t9t8L/
.wrapper {
width: 400px;
overflow-y: hidden;
overflow-x: scroll;
border: 1px solid black;
}
.list {
list-style-type: none;
border: 1px solid red;
width: 2000px;
}
.item {
display: inline-block;
height: 200px;
width: 50%;
border: 1px solid green;
}
<div class="wrapper">
<ul class="list">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
I believe there are some 'workaround' solutions to your issue, so I'll pour in some of my ideas, maybe it will help you out a bit.
Idea 1: Position absolute and a bunch of :nth-child selectors
In order to make the .item have their width relative to .list wrapper, you can absolute position these items, and set .list wrapper to position relative, so that the .item width will be calculated based on .list width.
The major downfall of this idea would be that you have to position these elements next to each, like using the left property, but passing it like a loop:
first item will have left: 0;
second item will have left: 50%;
third item will have left: 100%;
and so on...+50% to the next items
You can either pour in a bunch of :nth-child(n), each with +50% left prop. from each other, OR use some sass stuff to make it faster.
Check out the demo here & sass demo here
*,
*:after,
*:before {
box-sizing: border-box;
}
.wrapper {
width: 400px;
overflow-y: hidden;
overflow-x: scroll;
border: 1px solid black;
/*make the grandparent, .wrapper, relative, so that the grandchilds, .item,
will calculate their width based on this width*/
position: relative;
}
.list {
list-style-type: none;
border: 1px solid red;
width: 2000px;
margin: 50px 0;
padding: 0;
/*since everyone has position absolute, theres no content flow, so a fixed height
has to be supplied*/
height: 200px;
}
.item {
width: 50%;
border: 1px solid green;
position: absolute;
left: 0;
/*you can set a height here, or position them like I did bellow*/
top: 51px;
bottom: 51px;
}
/*now the fun part starts
somehow these .items have to have left: +50% for each of them, like a loop somehow,
so you can either pour in a lot of nth-child(), for how many children you think this
list is going to have, or use sass to write it faster like i did here:
*/
.item:nth-child(1) {
left: 0;
}
.item:nth-child(2) {
left: 50%;
}
.item:nth-child(3) {
left: 100%;
}
.item:nth-child(4) {
left: 150%;
}
.item:nth-child(5) {
left: 200%;
}
.item:nth-child(6) {
left: 250%;
}
.item:nth-child(7) {
left: 300%;
}
.item:nth-child(8) {
left: 350%;
}
.item:nth-child(9) {
left: 400%;
}
.item:nth-child(10) {
left: 450%;
}
.item:nth-child(11) {
left: 500%;
}
<div class="wrapper">
<ul class="list">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
Idea 2: Display: flex
Using display: flex on .wrapper, will allow you to have the widths of the .item to be relative to their grandparent.
The major downfall of this idea would be that the width of .list element, will be overwritten by the width of .wrapper, no matter if you specify it or not. However, not all is lost, if you need that specific width for some styling, you can specify it, and use some pseudo classes with width: inherit, so they'll stretch to whatever width you specified in the first place.
Check out the demo here
*,
*:after,
*:before {
box-sizing: border-box;
}
.wrapper {
width: 400px;
overflow-y: hidden;
overflow-x: scroll;
border: 1px solid black;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
/*bring on the awesomeness*/
margin: 20px;
}
.list {
list-style-type: none;
/*border: 1px solid red;*/
/*you can keep this defined width, items will calculte their width
based on .wrapper class, wich will overwrite this classes width,
however if you have some use for this width, consider using :after, :before
classes like I did bellow, with .list:before*/
position: relative;
z-index: 1;
width: 2000px;
white-space: nowrap;
margin: 20px 0;
padding: 0;
font-size: 0;
/*display inline block extra spacing ....*/
}
.list:before {
content: '';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: inherit;
/*it will inherit the width you set above*/
border: 1px solid red;
}
.item {
display: inline-block;
vertical-align: top;
height: 200px;
width: 50%;
border: 1px solid green;
font-size: 16px;
/*bump back the font-size*/
}
<div class="wrapper">
<ul class="list">
<li class="item">a</li>
<li class="item">b</li>
<li class="item">c</li>
<li class="item">d</li>
</ul>
</div>
<div class="wrapper">
<ul class="list">
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
<li class="item"></li>
</ul>
</div>
.wrapper {
width: 400px;
border: 1px solid black;
}
.list {
list-style-type: none;
border: 1px solid red;
width: 400px;
display: block;
white-space:nowrap;
padding: 0;
margin: 0;
}
.item {
display: inline-block;
height: 200px;
width: 47%;
border: 1px solid green;
padding: 1%;
}
http://jsfiddle.net/btsewL9v/
I would suggest something like this..
EDIT:
I don't know how many items you are trying to cram into the list, but take a look at this:
http://lea.verou.me/2011/01/styling-children-based-on-their-number-with-css3/

Forcing <a> tag have the same height as parent <li>

I am designing a top bar for a website and cannot figure out how to force the <a> elements below have the same height as the parent <li> elements. The code below shows the <li> elements with a green background and the <a> elements with a yellow background. I would like to have the yellow boxes span the whole height of the green boxes. Setting the height of the <a> elements to 100% doesn't do trick. What am I missing?
<!DOCTYPE html>
<head>
<style>
div#topbar {
width: 100%;
height: 30px;
top: 0;
border: 1px solid black;
}
#topbar ul {
margin: 0;
padding: 0;
list-style: none;
line-height: 30px;
}
#topbar ul li {
margin: 0;
padding: 0 10px;
background-color: green;
display: inline;
float: left;
}
#topbar a {
background-color: yellow;
}
</style>
</head>
<body>
<div id="topbar">
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
</div>
</body>
Its because tag is an inline element and it doesn't take height into account so you need make it block which can be made by various methods but most suitable in your case is 'float'.
div#topbar {
width: 100%;
height: 30px;
top: 0;
border: 1px solid black;
}
#topbar ul {
margin: 0;
padding: 0;
list-style: none;
line-height: 30px;
}
#topbar ul li {
margin: 0;
padding: 0 10px;
background-color: green;
display: inline;
float: left;
}
#topbar a {
background-color: yellow;
float:left; /*add this*/
}
http://jsfiddle.net/YMPe2/
Have you tried :
#topbar a {
background-color: yellow;
display: inline-block;
}
the a tag should be display:block, then it will fill the parent. And lose the padding on the li tag.

Resources