I want to replace bullets with images but I can't position them properly. I was doing the following:
.list-item::before {
background: url(../myimg.png);
background-size: contain;
content: '';
display: inline-block;
width: 1.5em;
height: 1.5em;
margin: 0 1.5em -0.5em 0;
}
Which kind of worked until I realized when my li contains more than a line of text the text on the second line goes up to the left of the image of course because it's inline-block, which I don't want (see: https://ibb.co/GkrHhqC).
What I want is something like this (see: https://ibb.co/wJ5ktQc). Except to do that I used
.list-item::before {
content: '';
display: block;
position: absolute;
width: 1.5em;
height: 1.5em;
margin: 0 1.5em -0.5em 0;
left: 1em;
}
Except it's cheating because the left means nothing. I'd like to position an absolute block, but relative to the left of my text. Is there a way to do that?
why not use a grid instead? Something like this
.list-item {
display: grid,
grid-template-columns: min-content 1fr; /* or min-content max-content*/
}
.list-item::before {
content: '';
display: block;
width: 1.5em;
height: 1.5em;
}
2 options spring to mind:
1. You could do this with grid
ul {
list-style: none;
margin: 0;
padding: 0;
max-width: 20ch; /* just to force text wrapping */
}
li {
display: grid;
grid-template-columns: 2em 1fr;
margin-bottom: 1em;
gap: 0.5em;
}
li::before {
content: '';
background: skyblue; /* replace with your image bg */
aspect-ratio: 1;
}
<ul>
<li>Item</li>
<li>Item</li>
<li>Item with longer, wrapping text. Item with longer, wrapping text.</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
2. You could use padding in the li to push the content right and position your image within the padding:
:root {
--list-image-size: 1.5em;
}
ul {
list-style: none;
margin: 0;
padding: 0;
max-width: 20ch; /* just to force text wrapping */
}
li {
position: relative;
padding-left: calc(var(--list-image-size) + 0.5em);
margin-bottom: 1em;
}
li::after {
content: '';
width: var(--list-image-size);
height: var(--list-image-size);
position: absolute;
top: 0;
left: 0;
background: skyblue; /* replace with your image bg */
}
<ul>
<li>Item</li>
<li>Item with longer, wrapping text</li>
<li>Item</li>
<li>Item</li>
</ul>
Related
I'm using pseudo content and a flex layout. Why does li:before not have the 10px width that Ive set?
https://codepen.io/adsfdsfhdsafkhdsafjkdhafskjds/pen/MWmwyOE
<ul>
<li>
<p>Lorum 123 dfjsd 3ijfadsifj sdfjoifj oijas fdjasf ijaio</p>
</li>
<li>
<p>37dkj dfjkasdfjdsijf dksdjf jfjiasdfmdafom</p>
</li>
</ul>
ul {
width: 150px;
margin: 0;
padding: 0;
list-style: none;
}
li {
display: flex;
margin-bottom: 20px
}
li:before {
content: "";
display: flex;
width: 10px;
flex-basis: 10px;
height: 10px;
background: red;
}
p {
margin: 0;
}
By default flex items don't shrink below their minimum content size. To change this, set the item's min-width or min-height.
https://developer.mozilla.org/en-US/docs/Web/CSS/flex
by default flex is setting the shrink value to 1.
If you add flex: 0 0 auto; to the pseudo element your code works.
ul {
width: 150px;
margin: 0;
padding: 0;
list-style: none;
}
li {
display: flex;
margin-bottom: 20px
}
li:before {
content: "";
display: flex;
width: 10px;
flex-basis: 10px;
height: 10px;
background: red;
flex: 0 0 auto;
}
p {
margin: 0;
}
<ul>
<li>
<p>Lorum 123 dfjsd 3ijfadsifj sdfjoifj oijas fdjasf ijaio</p>
</li>
<li>
<p>37dkj dfjkasdfjdsijf dksdjf jfjiasdfmdafom</p>
</li>
</ul>
try this
https://codepen.io/MuhammadRizwan/pen/bGWdpxB
update your class properties
li:before {
content: "";
display: flex;
width:100%;
min-width: 10px;
flex-basis: 10px;
height: 10px;
background: red;
}
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.
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>
I am currently using floats in order to place my logo in the center of my fixed navigation menu. The issue I'm facing currently is that the items I've floated to the right are displaying in reverse order.
How do I use text-align to achieve desired result and still maintain a fixed navigation header?
current code:
<img src="img/logo.png" class="logo" />
<ul class="nav">
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
<li>E</li>
<li>F</li>
</ul>
css:
header {
width: 100%;
padding: 0, 100px, 0, 0;
margin: 10px, 100px, 35px, 0 ;
position: fixed;
height: 6em;
background: transparent;
top: 0;
z-index: 1;
}
header .logo {
display: block;
height: 110px;
text-indent: -9999px;
width: auto;
margin: 0 auto;
position: relative;
}
header ul {
margin: -85px auto 0 auto;
height: 10px;
list-style: none;
}
header li:nth-child(1), header li:nth-child(2), header li:nth-child(3){
float: left;
}
header li:nth-child(4), header li:nth-child(5), header li:nth-child(6){
float: right;
}
Most obvious solution, break the menu into two and put the logo in the middle...then float each menu as required.
* {
margin: 0px;
padding: 0;
}
ul {
margin: 0;
list-style: none;
display: inline-block;
}
li {
display: inline-block;
}
a {
background: grey;
color: white;
padding: .5em;
}
nav {
text-align: center;
}
.left {
float: left;
text-align: left;
}
.right {
float: right;
text-align: right;
}
<nav>
<ul class="nav left">
<li>A
</li>
<li>B
</li>
<li>C
</li>
</ul>
Logo
<ul class="nav right">
<li>D
</li>
<li>E
</li>
<li>F
</li>
</ul>
</nav>
Of course, you may want all the items bunched together..in which case you don't need the floats at all
JSFiddle Demo
Then again, there's this one I like (not mine) which is even better : Codepen Demo
I have a unordered list that is as tall as the page. I don't want it flush with the sides of the div so I added padding. Except now it is overflowing. How can I make the list be as tall as it's parent minus the padding?
HTML
<div class="wrapper">
<div class="menu"></div>
<div class="content">
<ul class="list">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
</div>
</div>
CSS
/* Clear any defaults on the ul */
ul {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
/* Make a container that fills the entire screen */
.wrapper {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
overflow: auto;
background: hotpink;
}
/* Left hand 200px wide menu */
.menu {
position: fixed;
left: 0;
bottom: 0;
top: 0;
width: 200px;
background: blanchedalmond;
}
/* Fill the remaining width of the screen. */
.content {
margin: 0 0 0 200px;
height: 100%;
overflow: auto;
padding: 10px;
background: mistyrose;
}
/* 200px wide that shouldn't be taller than it's container */
.list {
width: 200px;
border: 1px solid orchid;
box-sizing: border-box;
list-style: none;
height: 100%;
}
http://jsfiddle.net/8A2un/
Added box-sizing: border-box to .content.
http://jsfiddle.net/8A2un/1/