Sliding icon next to dynamic text with ellipsis - html

I have a list of items and to the end of some items I want to add an icon (or several of them - it's dynamic). Items' container has a fixed width and if item's text size is too big - I'd like to add ellipsis.
So the problem is that icon is added next to text and if text is long - the icon moves off the container. The template for all items has to be the same.
Note: not all items have icons and some icons may have more than one icon.
Note2: javascript solution is not applicable, want to make it in pure CSS.
Actual:
Expected:
Any help is much appreciated.
body {
font-size: 20px;
}
.container {
width: 150px;
background: #ff0;
list-style: none;
padding: 0px;
margin: 0px;
}
.container li {
border-bottom: 1px solid #000;
}
.item {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.icon {
background: #0f0;
}
<ul class="container">
<li>
<div class="item">
<span class="text">Text 1</span>
<span class="icon">12</span>
</div>
</li>
<li>
<div class="item">
<span class="text">Text 2 Text 2</span>
<span class="icon">12</span>
</div>
</li>
<li>
<div class="item">
<span class="text">Text 3 Text 3 Text 3</span>
<span class="icon">12</span>
</div>
</li>
<li>
<div class="item">
<span class="text">Text 4 Text 4 Text 4</span>
<span class="icon"></span>
</div>
</li>
</ul>

If anyone still looking for solution I figured it out:
Markup:
<div class="block-wrap">
<div class="block">
<div class="icon"></div>
<div class="text">Text text text text text text text text text text text text text text text text text text text</div>
</div>
</div>
Styles:
.block-wrap {
display: inline-block;
max-width: 100%;
}
.block {
width: 100%;
}
.text {
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.icon {
float: right;
margin-left: 10px;
width: 20px;
height: 14px;
background-color: #333;
}
https://jsfiddle.net/rezed/n1qft37L/

Try like this: Demo
Fix the width for the text next to .item class and make display as inline-block to get floated with icon.
CSS:
.item {
width:100%;
overflow: hidden;
}
.item >span {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width:70%;
display:inline-block;
}
.icon {
background: #f00;
display:inline-block;
max-width:50px;
}
Hope this helps :)

Related

Display: inline-block not working with divs

i'm trying to create a news box where there will be a div containing an image on the left and a div containing lines of text on the right. Whenever i set them to inline-block the text goes right beneath the div image and stays there. I want them to be in a single line.
Here's my code, can you point out what i'm doing wrong?
EDIT: Corrected the TYPO but still...
<div id="newsBox">
<div id="newsImg">
<img src="images/news1.jpg" alt="news1">
</div>
<div class="metaNews">
<div id="newsTitle">
<h3>Text Text Text Text Text Text Text Text .</h3>
</div>
<div class="newsBrief">
<p>Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text </p>
</div>
</div>
<div style="clear:both"></div>
<div class="newsBy">
<span class="metaDate">Posted on 10/5/2017</span>
<span class="metaBy">By Li</span>
</div>
<div class="newsLink">
View →
</div>
<div style="clear:both"></div>
</div>
And the CSS:
#newsBox {
width: 85%;
margin: 0.5rem auto;
padding: 0.5rem;
border: #333 solid 1px;
background-color: #c2c2c2;
}
#newsImg {
display:inline-block;
}
#newsImg > img{
max-width: 120px;
max-height: 120px;
padding-right:20px;
vertical-align: middle;
}
.metaNews{
text-align:center;
display:inline-block;
}
#newsTitle {
}
.newsBy {
display:inline-block;
}
.newsLink {
float:right;
width: 6rem;
text-align: center;
background-color: #2F4F4F;
}
.newsLink a{
font-family: 'Play', sans-serif;
color: #fff;
text-decoration: none;
}
You got a typo in:
.metaNews{
text-align:center;
display:inline-blockl
}
inline-blockl has extra l instead of a ;
.metaNews{
text-align:center;
display:inline-block;
}
jsfiddle (you should stretch the result window a bit to let it have enough width to see the results you wanted )
Wrap the divs <div id="newsImg"> , <div class="metaNews"> using a div and set its display as flex.
#newsBox {
width: 85%;
margin: 0.5rem auto;
padding: 0.5rem;
border: #333 solid 1px;
background-color: #c2c2c2;
}
#newsImgWrapper {
display: flex;
}
#newsImg {
display: inline-block;
}
#newsImg>img {
max-width: 120px;
max-height: 120px;
padding-right: 20px;
vertical-align: middle;
}
.metaNews {
text-align: center;
display: inline-block;
}
#newsTitle h3{ margin:0;}
.newsBy {
display: inline-block;
}
.newsLink {
float: right;
width: 6rem;
text-align: center;
background-color: #2F4F4F;
}
.newsLink a {
font-family: 'Play', sans-serif;
color: #fff;
text-decoration: none;
}
<div id="newsBox">
<div id="newsImgWrapper">
<div id="newsImg">
<img src="images/news1.jpg" alt="news1">
</div>
<div class="metaNews">
<div id="newsTitle">
<h3>Text Text Text Text Text Text Text Text .</h3>
</div>
<div class="newsBrief">
<p>Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text </p>
</div>
</div>
</div>
<div style="clear:both"></div>
<div class="newsBy">
<span class="metaDate">Posted on 10/5/2017</span>
<span class="metaBy">By Li</span>
</div>
<div class="newsLink">
View →
</div>
<div style="clear:both"></div>
</div>
The problem is that you are using display: inline-block, Without use width, display: inline-block does not work without using setting width,
So I added these properties: width: 50% to #newsImg selector and to .metaNews,
Here a running example in jsFiddle

How can a I make inline-block stay in a single line but still fit the available width?

I have the following demo code the demonstrates my problem. I want to add some decoration beside the title via CSS and have this problem. If the title is short enough it works as expected, but if the title is longer, when the text wraps around but not enough to be inside the div.base.
How can I make the second sample it looks like the third (fake) sample below?
Just to be clear, I want the div contents to appear "inline" with only the middle div being allowed to word-wrap, the div contents should stay within the container width without adding extra spaces between the divs.
<html>
<style>
.base { font-size:32pt; text-align:center; border:solid; display: block; white-space:nowrap; width:400px;}
.base span, .base::before, .base::after { display: inline-block; border:solid; white-space:normal;}
.base::before { content: "\00a0-\00a0"; }
.base::after { content: "\00a0-\00a0"; }
</style>
<body>
<div class="base">
<span>Short text</span>
</div>
<div class="base">
<span>Testing some longer text</span>
</div>
<div class="base">
<span>Fake some <br>longer text</span>
</div>
</body>
</html>
Two ways to go, the second one better (flex), but dependent on browser support:
1.) You can use a max-width with a percentage or (better) calc value on that span:
.base {
font-size: 32pt;
text-align: center;
border: solid;
display: block;
white-space: nowrap;
width: 400px;
}
.base span,
.base::before,
.base::after {
display: inline-block;
border: solid;
white-space: normal;
}
.base::before {
content: "\00a0-\00a0";
}
.base::after {
content: "\00a0-\00a0";
}
.x2 span {
max-width: calc(100% - 112px);
}
<div class="base x1">
<span>Short text</span>
</div>
<div class="base x2">
<span>Testing some longer text</span>
</div>
<div class="base x3">
<span>Fake some <br>longer text</span>
</div>
2.) Here's the second solution using flexbox:
.base {
font-size: 32pt;
text-align: center;
border: solid;
display: block;
white-space: nowrap;
width: 400px;
display: flex;
justify-content: center;
}
base span {
}
.base span,
.base::before,
.base::after {
display: inline-block;
border: solid;
white-space: normal;
}
.base::before {
content: "\00a0-\00a0";
margin-right: 10px;
}
.base::after {
content: "\00a0-\00a0";
margin-left: 10px;
}
<div class="base x1">
<span>Short text</span>
</div>
<div class="base x2">
<span>Testing some longer text</span>
</div>
<div class="base x3">
<span>Fake some <br>longer text</span>
</div>

Break text on the left before breaking float on the next line

I have a code like this: https://jsfiddle.net/qchtngzf/1/
and now, when the browser is too narrow, the div.right (the text on the right) jumps onto a next line. I would like to, however, if the div.left (the text on the left) would get smaller and the text inside would break onto a next line and the div.right would stay in the same place instead.
I found a similar issue here: Making a div float left, but not "fall" if text is too long
but it's a little different and doesn't work for me even with some changes I tried.
Thank you.
You should set width for both of them right and left class:
html, body, header, nav, footer, div, p, ul, li, a {
margin: 0;
padding: 0;
text-decoration: none;
font-family: sans-serif;
font-size: 18px;
}
.left {
width: 80%;
float: left;
position: relative;
}
.right {
width: 10%;
}
.clearfix:after {
content: "";
display: block;
clear: both;
}
hr {
border: 0;
height: 1px;
background-color: #e9e9e9;
margin: 16px 0;
}
section.body {
max-width: 960px;
min-width: 272px;
}
div.left {
color: #1e344c;
float: left;
}
div.left span {
font-size: 14px;
color: #666666;
}
div.right {
float: right;
}
<section class="body">
<div class="item clearfix">
<div class="left">
text text text text text text text text text text text text text text
</div>
<div class="right">text </div>
</div>
<hr>
<div class="item clearfix">
<div class="left">
text text text text text text text text text text <br>
<span>text text text text text </span>
</div>
<div class="right">text </div>
</div>
<hr>
<div class="item clearfix">
<div class="left">
text text text text text text text text text
</div>
<div class="right">text </div>
</div>
<hr>
<div class="item clearfix">
<div class="left">
text text text text text <br>
<span>text text text text text text text text text text text text text text text </span>
</div>
<div class="right">text </div>
</div>
<hr>
<div class="item clearfix">
<div class="left">
text text text text text text text <br>
<span>text text text text text text text </span>
</div>
<div class="right">text </div>
</div>
<hr>
<div class="item clearfix">
<div class="left">
text text text text text text text text text <br>
<span>text text text text text text </span>
</div>
<div class="right">text </div>
</div>
</section>
You can use below css if you want right section not to wrap in next line and left section to get shorter.
html, body, header, nav, footer, div, p, ul, li, a {
margin: 0;
padding: 0;
text-decoration: none;
font-family: sans-serif;
font-size: 18px;
}
.clearfix:after {
content: "";
display: block;
clear: both;
}
hr {
border: 0;
height: 1px;
background-color: #e9e9e9;
margin: 16px 0;
}
section.body {
max-width: 960px;
min-width: 272px;
}
div.left {
color: #1e344c;
width
}
.item {
display: flex;
-webkit-flex-direction: row;
-ms-flex-direction: row;
flex-direction: row;
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;
-webkit-justify-content: space-between;
-ms-flex-pack: justify;
justify-content: space-between;
}
div.left span {
font-size: 14px;
color: #666666;
}
div.right {
white-space:nowrap;
}
1) Set width for both divs
2)set font size in "vh"
3) No need to set position:relative; of div.left;
div.left{
width:90%;
font-size:2vh;
float:left;
}
div.right{
width:10%;
float:right;
}
Actually, a combination of these answers helped. There is a problem with the one from Teuta (https://stackoverflow.com/a/38073935/6522717) that if the screen is too small and the content on the right is bigger than the set percentage, the text then breaks onto another line. This would be solved by another #media width or, as San posted (https://stackoverflow.com/a/38074311/6522717), by assigning white-space: nowrap to the div.right.
Thank you very much for the answers as they helped a lot.

Keeping HTML list items inline and overlaying text

I need some help understanding how to solve this problem. I've got multiple list elements that each have text with an unknown length. On each side of this text, there will be a small image/icon. Here is an example of the HTML:
.truncate>img {
width: 25px;
height: 25px;
}
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
<div class="container-fluid">
<div class="row">
<div class="col-sm-4">
Content
</div>
<div class="col-sm-4">
<ul id="myList" class="list-group">
<li class="list-group-item" value="">
<div class="truncate">
<img src="https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Close_Box_Red.png">A long text string that is about this length
<img src="http://www.clker.com/cliparts/1/5/4/b/11949892282132520602led_circle_green.svg.med.png">
</div>
</li>
<li class="list-group-item" value="">
<div class="truncate">
<img src="https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Close_Box_Red.png">A long text string that is about this length
<img src="http://www.clker.com/cliparts/1/5/4/b/11949892282132520602led_circle_green.svg.med.png">
</div>
</li>
<li class="list-group-item" value="">
<div class="truncate">
<img src="https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Close_Box_Red.png">A long text string that is about this length
<img src="http://www.clker.com/cliparts/1/5/4/b/11949892282132520602led_circle_green.svg.med.png">
</div>
</li>
</ul>
</div>
<div class="col-sm-4">
Content
</div>
</div>
</div>
JS Fiddle.
I want the text to have an ellipsis at the end if it is longer than the available width. I know how to use text-overflow: ellipsis and I can get the text to have an ellipsis but only after the right image drops below the text.
Some things that I have tried:
I have tried surrounding the whole li element in a div and using
display: inline-block
Similarly, I've tried surrounding just the image tags and text in a
single div with inline-block which has been closest to the desired result.
I tried putting the text in a span element and various CSS styling.
Each time the right image still jumps below the text.
Desired result:
And actual result:
Let me know if I should include any other information. Thanks in advance for any advice.
One trick could be to manually position the images on left and right and then place the text inside an absolutely-positioned div:
.left { position: absolute;
left: 0px;
}
.right { position: absolute;
right: 0px;
}
.text { position: absolute;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
left: 24px;
right: 24px;
}
.container { display: inline-block;
width: 100%;
position: relative;
height: 24px;
}
<ul>
<li>
<div class="container">
<img class="left" src="http://raksy.dyndns.org/cross.png">
<div class="text">
This is a text
</div>
<img class="right" src="http://raksy.dyndns.org/disc.png">
</div>
</li>
<li>
<div class="container">
<img class="left" src="http://raksy.dyndns.org/cross.png">
<div class="text">
This is a much longer text that most probably will have to be truncated
</div>
<img class="right" src="http://raksy.dyndns.org/disc.png">
</div>
</li>
<li>
<div class="container">
<img class="left" src="http://raksy.dyndns.org/cross.png">
<div class="text">
This is a text (somewhat longer but not huge)
</div>
<img class="right" src="http://raksy.dyndns.org/disc.png">
</div>
</li>
</ul>
Probably not 100% what you want, but may get you the rest of the way:
Fiddle
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: inline-block;
width: 50%;
}
.list-group-item{
background-color:transparent;
border:none;
padding:0px 15px;
cursor: pointer;
white-space: nowrap;
}
I tried with a div wrapper, including display: inline-block, and it worked well:
http://jsfiddle.net/nozimica/y3oy723v/
The key is:
Create a div wrapper.
Assign display: inline-block;
Give it a width.
Floats work, and so does absolute positioning:
.truncate>img {
width: 25px;
height: 25px;
position: absolute;
left: 8px;
}
.truncate img:first-child {
right: 8px;
left: auto;
}
.truncate {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 0 30px;
}
<li class="list-group-item" value="">
<div class="truncate">
<img src="...">
<img src="..."> A long text string that is about this length
</div>
</li>
Demo

How to wrap lines in an inline-block with CSS?

I have a simple HTML structure (jsfiddle):
<li>
<div class="buttons">
<img src="done.png">
</div>
<div class="owners">
Даня Абрамов и Саша Васильев
</div>
<div class="text">
трали-вали трали-вали трали-вали трали-вали
</div>
</li>
buttons, owners and text have display: inline-block.
This looks fine when text is fairly small:
However, as the text grows, inline-block elements extend and eventually fall over the line:
This is ugly, and I would like to avoid that.
What I want to achieve instead is this:
When the text is too large to fit inside the element, I want it to be wrapped by lines.
I tried setting float: left on the elements, but couldn't get it working.
What's the proper way to do this with HTML and CSS (no tables)?
The exact result you desire can be achieved if you use floats instead of display: inline-block.
See: http://jsfiddle.net/thirtydot/CatuS/
li {
overflow: hidden;
}
.buttons, .owners {
float: left;
}
.text {
overflow: hidden;
padding-left: 4px;
}
You have to specify some max-width with percentage:
<li>
<div class="buttons" style="max-width:10%;">
<img src="done.png">
</div>
<div class="owners" style="max-width:30%;">
Даня Абрамов и Саша Васильев
</div>
<div class="text" style="max-width:60%;">
трали-вали трали-вали трали-вали трали-вали
</div>
</li>
<!-- 10+30+60 = 100% -->
There is a very nice flexbox solution if you have the browser support:
/* flexbox additions */
ul li {
display: flex;
}
.buttons {
flex-shrink: 0;
}
.owners {
flex-shrink: 0;
margin-right: 6px;
}
/* original CSS (inline-block is technically no longer necessary) */
.buttons {
display: inline-block;
}
.owners {
display: inline-block;
}
.text {
display: inline-block;
}
/* the rest is visual styling */
ul li {
line-height: 1.5em;
padding: 12px 8px 12px 8px;
margin-bottom: 12px;
margin-top: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
font-size: 15px;
background-color: #DBEAFF;
min-height: 23px;
}
.buttons {
min-width: 13px;
vertical-align: top;
margin-top: 3px;
margin-bottom: -3px;
}
.buttons a {
padding: 13px 9px 5px 9px;
}
<ul>
<li>
<div class="buttons">
<img src="http://clstr.org/static/images/tick.png">
</div>
<div class="owners">
<a>Даня Абрамов</a>
</div>
<div class="text">short text
</div>
</li>
<li>
<div class="buttons">
<img src="http://clstr.org/static/images/tick.png">
</div>
<div class="owners">
<a>Даня Абрамов</a>
</div>
<div class="text">longer text longer text longer text longer text longer text longer text longer text longer text longer text
</div>
</li>
<li>
<div class="buttons">
<img src="http://clstr.org/static/images/tick.png">
</div>
<div class="owners">
<a>Даня Абрамов</a> и <a>Саша Васильев</a>
</div>
<div class="text">
longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text longer text
longer text longer text longer text longer text longer text longer text
</div>
</li>
<li>
<div class="buttons">
<img src="http://clstr.org/static/images/tick.png">
</div>
<div class="owners">
<a>Даня Абрамов</a> и <a>Саша Васильев</a>
</div>
<div class="text">
трали-вали трали-вали трали-вали трали-вали
</div>
</li>
</ul>
I think you need to set max-width with different display mode.
li {overflow:hidden;}
li div { float:left; }
.button{ max-width: 10%;}
.owners{ max-width: 20%;}
.text{ max-width: 70%;}
See the new result here
BTW, if you use inline-block, the owners part won't stay on top.
I modified the code to fit your requirement. :)
FYI, li {overflow:hidden;} is a way to make a container to encompass its floated children.