CSS property to make text wrappable at any place - css

Is there a CSS property that tells the browser to word-wrap at any position, not only at word boundaries?
My current issue is this. I am faced with HTML similar to this: (I cannot change the HTML, unfortunately)
<div id='categories'>Categories:
<ul>
<li>Category One</li>
<li>Category Two</li>
<li>Category Three</li>
</ul>
</div>
I want it to display in a flowing manner according to the width of the viewport:
Categories: • Category One • Category Two • Category Three
|----------------------------------------------------------------| (viewport)
Categories: • Category One • Category Two
• Category Three
|----------------------------------------------| (viewport width)
Categories: • Category One
• Category Two • Category Three
|----------------------------------| (viewport width)
... but NOT word-breaking within a category name.
So I tried this:
#categories ul {
display: inline;
}
#categories li {
display: inline;
padding: 0 1em;
white-space: nowrap;
}
#categories li:before {
content: '• ';
}
Unfortunately this causes them all to run in one line. So I need to be able to tell the ul to allow wrapping anywhere between any adjacent lis. How do I do that?
I need a CSS-only solution; I cannot change the HTML...

A useful trick for wrapping boxes is to make them all float: left. If I do this to your example, then I get the layout you want except for "Categories:" being pushed to the right. Unfortunately, I don't know of a way to select the text so as to make it floated.
We can use content to re-insert "Categories:" as one of the floated boxes, which leaves the problem of how to hide the existing "Categories:" text without hiding the other contents of #categories. The cleanest way I thought of was to make it transparent. However, this is a CSS3 feature; also, this loses any inherited color due to the need to explicitly set it on the ul.
This stylesheet produces everything you want, but needs some tweaking for spacing.
#categories {
color: transparent;
}
#categories ul {
color: black;
}
#categories li {
display: inline;
float: left;
padding: 0 1em;
white-space: nowrap;
}
#categories li:before {
content: '• ';
}
#categories li:first-child:before {
content: 'Categories: • ';
}

Maybe this?
<ul>Categories: <li>Category One</li><wbr><li>Category Two</li><wbr><li>Category Three</li></ul>

Related

Hanging indent on unbulleted list with CSS

I am trying to create a <ul> with no bullets (i.e. list-style-type: none) where the items have a hanging indent (all lines except first are indented). I do not mean that all <li> after the first should be indented-- rather that, if an <li> spans more than one line, all lines after the first should be indented within that <li>. How can I achieve this?
So far I've tried:
text-indent: 5px hanging: no effect, hanging is not yet supported
text-indent: -5px; padding-left: 5px: found this trick here, but it did not work in this context
the solution at this SO question, which didn't work for unbulleted lists
NOTE: I know that I can achieve this by other means (e.g. using <p>s instead of a list), but I am wondering whether it is possible with <ul>.
You can add some padding and a negative text-indent.
ul {
list-style: none;
padding-left: 40px; /* Most browsers already have this by default */
}
li {
text-indent: -20px;
}
<ul>
<li>Hello<br />world<br />foo bar</li>
</ul>
Is this what you are trying to achieve?
ul {
list-style: none;
margin: 0;
padding-left: 20px
}
li {
text-indent:-15px;
}
<ul>
<li>test
<br/>me</li>
</ul>

How to color specifics parts (letters) of menu?

Firstly, happy new year to you all! :)
Ok let's get to it. I have 5 items in my menu, and i would like to color "+" part of the word to red, choosing 2nd,3rd and 4th item of menu.
This is what menu looks like right now.
This is how the menu should look like, when its done.
I might have given a bad picture, but i think you can see the red "+" on 2nd,3rd and 4th item of menu.
This is what i've tried so far, but i can't seem to figure out the nth-child method.
#menu li:nth-child(2):first-letter a{color:red;}
Also tried this, but it colors every first letter in all 5 elements :S
#menu .nav > li > a:first-letter{color:red;}
Any help will be appreciated!
Thank you all!
I've managed to find the solution. Not sure if it's the best one, but im posting it below, so that any1 in the future can use it too, if no other solution is found
#menu .nav > li:nth-child(2) > a:first-letter
{
color:red;
}
#menu .nav > li:nth-child(3) > a:first-letter
{
color:red;
}
#menu .nav > li:nth-child(4) > a:first-letter
{
color:red;
}
Use the :not() selector to have all but one selected like this:
#menu{
background: rgb(83,83,83);
width: 100vw;
height: 40px;
}
ul{
text-align: center;
line-height: 40px;
vertical-align: central;
}
ul li{
display: inline-block;
color: white;
list-style: none;
margin-left: 25px;
}
a{
color: white;
display: block;
}
#menu ul li:not(:first-child):not(:last-child) a::first-letter{
color: red;
}
<div id="menu">
<ul>
<li>+option</li>
<li>+option</li>
<li>+option</li>
<li>+option</li>
<li>+option</li>
</ul>
</div>
I know this question already has an accepted answer, but I think there is a semantically better way of doing this. Instead of having the + symbol inside the link's markup, why not add it as a pseudo :before element? Easier to style and not dependent on your markup.
<nav>
<ul>
<li>Domov</li>
<li class="with-symbol">Naravni kamen</li>
<li class="with-symbol">Dekorativni kamen</li>
<li class="with-symbol">Keramika</li>
<li>Kontakt</li>
</ul>
</nav>
And the respective CSS:
.with-symbol:before {
content: '+';
color: red;
}
Then position it with either position: absolute; or negative left margin.
From the docs (https://developer.mozilla.org/en-US/docs/Web/CSS/%3A%3Afirst-letter): A first line has meaning only in a block-container box, therefore the ::first-letter pseudo-element has an effect only on elements with a display value of block, inline-block, table-cell, list-item or table-caption. In all other cases, ::first-letter has no effect. So you will need to add display: block to your anchor tags.
I would also change the selector to:
ul li a:first-letter {
color:red;
}
as you need to select the first letter of the anchor tag, not the list item.
As a side note, it might be a better solution to use a span as suggested above or pseudo elements to insert the plus character and use a class to determine if it should be displayed or no.

Using CSS to style a numbered list

I need HTML to produce output similar to:
1. Some title
1.1 blah blah
(a) blah blah blah
(b) blah blah
1.2 blah blah
I believe that because of the need for parenthesis round the letters that I cannot use the ordered list tag for this. Obviously it can be done with a table, but I'd much rather use CSS. However I'm at a loss as to how to do this.
If lines wrap to the next line, they should continue under the text like an ordered list would.
UPDATE
I have tried
OL {
counter-reset: numeric
}
OL LI OL LI OL {
counter-reset: latin
}
LI {
display: block
}
LI:before {
content: counters(numeric, ".") " ";
counter-increment: numeric
}
OL LI OL LI OL LI:before {
content: "(" counter(latin, lower-latin) ") ";
counter-increment: latin
}
and HTML such as:
xxx
<ol>
<li>one
<ol>
<li>onedotone</li>
<li>onedottwo
<ol>
<li>A</li>
</ol>
</li>
</ol>
<li>two</li>
</ol>
produces this
xxx
1 one
1.1 onedotone
1.2 onedottwo
(a) A
2 two
Unfortunately, my requirements are exactly as stated in the original question. So my CSS fails in these areas.
There needs to be a full stop after 1 and after 2 but not after 1.1 and 1.2
1 and 1.1 should not be indented and the text for both of them needs to be aligned to the same place. So the word onedotone needs to be exactly below the word one. Also there needs to be a bigger gap than one space between the number and the text.
The (a) needs to line up with the words onedottwo, and again there needs to be a bigger gap than one space between (a) and A.
padding-left is not the answer, as it does not help line up the text after the numbers, You get
1 one
1.1 onedotone
instead of
1. one
1.1 onedotone
This is beyond my CSS capabilities. Unless anyone has the expertise to point me in the right direction, I fear that I will have to fall back on using a table.
Below is a sample on how the desired result can be achieved using <ol> (ordered lists) and CSS counters. It has a bit of a hack-ish feel about it because of the expectation that when a line is wrapped around, it should not start from under the numberings. Otherwise, I feel this method is much better than manually keying in the numbers (or) using tables.
Consistent spacing between the numbering and text is obtained by setting a width to the li:before pseudo-element and making its display as display: inline-block. Modify the width based on how much spacing is required. Note that when modifying the width, the margin-left and padding-left also have to be modified accordingly to maintain the styling.
CSS Counters have reasonably good browser support also.
.level1, .level2, .level3 {
list-style-type: none;
}
.level1 {
counter-reset: level1; /* first level counter - for 1, 2, 3 */
}
.level2 {
counter-reset: level2; /* second level counter - for 1.1, 1.2 */
}
.level3 {
counter-reset: level3; /* third level counter - for (a), (b) */
}
li {
display: block;
}
li:not(:last-child):after, li > ol:before{
content: " ";
display: block;
position: relative;
height: 20px; /* this is filler where height should be equal to required line height */
left: 0px; top: 100%;
}
.level1, .level2, .level3 {
margin: 0;
padding: 0;
}
.level1 > li, .level3 > li {
padding-left: 40px;
}
li:before {
margin-left: -40px;
/* following 2 props are for consistent spacing between numbering and text */
width: 40px;
display: inline-block;
}
.level1 > li{
font-weight: bold;
}
.level1 > li:before, .level1 > li * {
font-weight: normal;
}
.level1 > li:before {
content: counter(level1)"."; /* display current item number + dot */
counter-increment: level1; /* increment counter everytime a new element of that level is encountered */
}
.level2 > li:before {
content: counter(level1)"." counter(level2); /* format level 1 counter + dot + level 2 counter */
counter-increment: level2;
}
.level3 > li:before {
content: "(" counter(level3, lower-latin)") "; /* format ( + level3 counter + ) */
counter-increment: level3;
}
<ol class='level1'>
<li>one
<ol class='level2'>
<li>one dot one - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
<li>one dot two
<ol class='level3'>
<li>A</li>
<li>B - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
</ol>
</li>
</ol>
</li>
<li>two - has some really really lengthy text which wraps around to the next line when it overflows the width.</li>
</ol>
Feedback to comments:
The {content: "\a"; white-space: pre;} trick does not quite work with inline-block elements. The inner level li tags are inline-block in our case (for reasons explained above in 2nd paragraph) and hence that particular trick doesn't work. The alternate is to insert a blank filler line with height of the line equal to the required line-height and position it below the li tag. Note that the selector used is li:not(:last-child):after because we don't need an extra line break after the last li (if we do not do it, we will have double line space after the inner li ends). This is a CSS3 selector and so might not work with lower versions of IE. If you need to support those versions also then we would need to tweak it further (or simpler would be to use br).
You were on the correct path here, but the :before pseudo-element (which has the numbering) is not on the element with class='level1'. It was on the .level1 > li and hence doing a reset of font-weight for selector .level1 > li:before, .level1 > li * would fix it. As you would have already known/guessed, .level1 > li * means every element under the level one li.

Bullets disappear with CSS3 columns

The bullets on my list items disappear when I convert them to columns using CSS3. Any ideas why or suggestions on how to correct it?
See the example: http://jsfiddle.net/gduDm/1/
ul li {
list-style-type: disc !important;
column-break-inside: avoid;
}
ul {
list-style-type: disc !important;
margin-top: 1em;
column-count: 2;
column-gap: 0.5em;
}
I think the bullets are there, but they're being rendered to the left of the viewing area. Try:
list-style-position: inside;
Adding both padding-left and a negative text-indent to the list elements seems to produce the desired result:
ul li {
padding-left: 1em;
text-indent: -1em;
}
ul {
list-style: inside disc;
}
http://jsfiddle.net/mblase75/gduDm/4/
Alternatively, add a margin-left to the list element (instead of the list) and use outside bullets:
ul li {
margin-left: 1em;
}
ul {
list-style: outside disc;
}
http://jsfiddle.net/mblase75/gduDm/9/
Setting margin-left:1em makes the bullets appear without messing with the text indentation.
After trying the first answer here, I was having issues with my list items spilling onto a second row and not lining up. Using column-gap I was able to move the second column over and see the bullets.
Source: http://karlikdesign.com/how-to-split-a-list-into-two-columns-with-pure-css/
<!– CSS CODE –>
.two-columns {
-webkit-column-count: 2;
-moz-column-count: 2;
column-count: 2;
-webkit-column-gap: 40px;
column-gap: 40px;
-moz-column-gap: 40px;
}
Some of the other solutions are pretty good, but all the ones I tried caused various side effects for me. I made some small tweaks and tried to get it as close to perfect as possible.
ul {
column-count:2;
}
ul.solution {
margin-left:-0.6em;
margin-right:0.6em;
}
ul.solution > * {
margin-left:0.6em;
margin-right:-0.6em;
}
Experimental Group
<ul class="solution">
<li>
This solution is pretty similar to the others.
</li>
<li>
It does not require you to put the bullets inside, so you can keep your left edge clean if you want.
</li>
<li>
This fixed it for me in IE11 while also not impacting the appearance on Chromium, so I didn't have to do any browser filtering.
</li>
</ul>
Control Group
<ul>
<li>
This solution is pretty similar to the others.
</li>
<li>
It does not require you to put the bullets inside, so you can keep your left edge clean if you want.
</li>
<li>
This fixed it for me in IE11 while also not impacting the appearance on Chromium, so I didn't have to do any browser filtering.
</li>
</ul>

Getting rid of li last item counter

I have a annoying problem .. I want my first 4 items in a list to be numbered but I wanna leave fifth item out of numbering .. here is my css :
#alternate_navigation ol
{
display:block;
padding:0;
margin:0;
counter-reset: item;
}
#alternate_navigation li
{
display:block;
padding:0px 0px 0px 10px;
margin:0;
background: url('images/list_bg.jpg') no-repeat;
height:19px;
width:99%;
border-bottom:1px solid #B9B5B2;
}
#alternate_navigation li:before
{
content: counter(item) ". ";
counter-increment: item ;
}
RESULT :
Online Booking
Coupon Ordering
Print Letters
Send Emails
View orders
How could I achieve for last item not to be numbered like this :
Online Booking
Coupon Ordering
Print Letters
Send Emails
View orders
and yes HTML
<div id="alternate_navigation">
<ol>
<li>Online Booking</li>
<li>Coupon Ordering</li>
<li>Print Letters</li>
<li>Send Emails</li>
<li>View orders</li>
</ol>
<div>
Thank you for any response
After your current CSS, add:
#alternate_navigation li:last-child:before {
content: "";
counter-increment: none;
}
That should 'reset' the style for the last element.
EDIT: I should just mention that this will not work in IE8 due to the use of :last-child. If you need IE6/7/8 compatibility, I would use something like JQuery instead of manually inserting HTML markup.
Is it possible that the browser you are using doesn't support content, counter-reset, :before, or counter-increment?
I'm pretty sure IE doesn't, and I'm not certain about others. If that is the case, you're just recieving the default numbered list: in short, the browser would ignore the newer CSS.
You can aplly a css class to reset that counter, like this example :
#alternate_navigation li.last:before
{
content: "";
counter-increment: none ;
}
Check my example :
http://www.aeon-dev.org/tests/before_pseudo_ie.html
Out of curiousity, in this case why are you using the counter-reset at all? Why not set
list-style: decimal;
and then for your html add a class to your last <li> tag like <li class="last">?
Then you can set
li.last { list-style: none; }

Resources