I searched for this problem for quite a while now, but only found solutions to the opposite problem.
So here is my problem:
I have a side panel that should be only as wide as its content. This panel has a header with a potentially long title. That header should not expand the panel, but instead be ellipsed.
The HTML looks similar to this
<div class="outer">
<div class="inner">
<div class="header">
superlongtextthatshouldbeellipsed
</div>
<div class="line">
short text
</div>
<div class="line">
even shorter text
</div>
</div>
</div>
This is the CSS to demonstrate the problem
.outer {
background-color: #FFAAAA;
display: flex;
flex-direction: row;
}
.inner {
background-color: #AAAAFF;
display: flex;
flex-direction: column;
margin: 5px;
}
.header {
margin: 5px;
background-color: #AAFFAA;
white-space: nowrap;
overflow: none;
text-overflow: ellipsis;
}
.line {
margin: 5px;
background-color: #FFAAFF;
}
https://jsfiddle.net/1yn725hy/9/
In the fiddle the blue box should be as wide as the second purple box (+margin). The text in the green box should be ellipsed.
How do I do this?
EDIT: Just to clarify: The blue box should fit the content of the purple box which has a varying size. A fixed width does not solve the problem.
First of all your container has to have max-width or width fixed. Second of all your overflow has to be hidden instead of none:
.outer {
background-color: #FFAAAA;
display: flex;
flex-direction: row;
}
.inner {
background-color: #AAAAFF;
display: flex;
flex-direction: column;
margin: 5px;
}
.header {
margin: 5px;
background-color: #AAFFAA;
white-space: nowrap;
max-width:200px;
overflow: hidden;
text-overflow: ellipsis;
}
.line {
margin: 5px;
background-color: #FFAAFF;
}
<div class="outer">
<div class="inner">
<div class="header">
superlongtextthatshouldbeellipsed
</div>
<div class="line">
short text
</div>
<div class="line">
even shorter text
</div>
</div>
</div>
Ok, finally solved it myself. The trick is to use the almighty flexbox and wrap the header in it:
.outer {
background-color: #FFAAAA;
display: flex;
flex-direction: row;
}
.inner {
background-color: #AAAAFF;
display: flex;
flex-direction: column;
margin: 5px;
}
.header {
margin: 5px;
background-color: #AAFFAA;
display: flex;
}
.header2 {
width: 0px;
flex-grow: 1;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
.line {
margin: 5px;
background-color: #FFAAFF;
}
<div class="outer">
<div class="inner">
<div class="header">
<div class="header2">
superlongtextthatshouldbeellipsed
</div>
</div>
<div class="line">
short text
</div>
<div class="line">
even shorter text
</div>
</div>
</div>
You should add some width to your div. Otherwise the header text wont ellipsed, because there is no "end".
https://jsfiddle.net/1yn725hy/14/
Related
Hi below is the html code,
.wrapper {
min-width: 0%;
max-width: 100%;
line-height: 21px;
position:relative;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
max-height: 50px;
text-align:center;
}
.iconwrapper {
min-width:0;
}
<div class="wrapper">
<div class="iconwrapper">
<svg/>
</div>
<span>sometext</span>
<div>
now for some reason the div with class iconwrapper takes up complete space in the div and span appears in the next row or below in wrapper div.
how can i fix this. could someone help me with this. thanks.
try adding display: flex; property to .wrapper.
.wrapper {
...
display: flex;
}
Check the snippet. Like this you can provide.
.wrapper {
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
max-height: 50px;
text-align:center;
display: flex;
border: 1px solid #ddd;
}
.iconwrapper {
min-width:0;
flex: 1;
border: 1px solid #ccc;
}
<div class="wrapper">
<div class="iconwrapper">
<svg/>
</div>
<span>sometext</span>
<div>
I'm trying to fit some text and divs all into a single line (without wrapping) and using text-overflow: ellipsis. However in all my experimenting (I can't even recall all the things I've tried), the text fills up the entire line, and the divs get pushed down onto a new line.
I'd like the text to truncate so the blue boxes are on the same line as the text.
I'm able to get it to work with JS, but I want a pure CSS solution.
EDIT:
Sorry, I should have added some more details.
The text length is variable
The solution should allow for a responsive page design (I put the width: 400px to constrain the container, but in reality it's responsive, sorry I know my question was misleading.)
.page-container{
width: 400px;
background: yellow;
}
div.header {
white-space: nowrap;
display: inline;
width: 100%;
}
div.one-line-div {
font-size: larger;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
}
.move-divs {
display: inline-block;
float: right;
}
.div1, .div2, .div3, .div4 {
float: right;
margin-right: 12px;
cursor: pointer;
display: inline-block;
width: 30px;
height: 30px;
background: blue;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">Text text, so much text here, what do we do with all this text?.
<div class="more-divs">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
Have you tried flex-box? Based on what I've tested it should work for you. You'll need to wrap your text in another div, though. And also need to change some things from inline-block back to block, etc. Basically flex-box is the new layout engine that allows you to do some awesome stuff. Generally you shouldn't ever need float if you use flex-box. Check out this guide on flex-box from CSS-Tricks. You can do some amazing things with it. Let me know if you have any questions regarding my answer. I didn't want to go into too much specifics because that'd be a pretty big rabbit hole.
.page-container{
width: 400px;
background: yellow;
}
/*
You don't need this anymore with flex.
div.header {
white-space: nowrap;
display: inline;
width: 100%;
}*/
/* Updated to use flex box. */
div.one-line-div {
display: flex;
flex-direction: row;
font-size: larger;
}
/* define the style for our .text element */
.text {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
/* our .move-divs needs to be flex too */
.more-divs {
display: flex;
flex-direction: row;
}
/* I removed the floats and display inline, since you don't need them */
.div1, .div2, .div3, .div4 {
margin-right: 12px;
cursor: pointer;
width: 30px;
height: 30px;
background: blue;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<body>
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">
<div class="text">
Text text, so much text here, what do we do with all this text?.
</div>
<div class="more-divs">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
The solution: put the text in a "span" element . then do the following styles
.page-container{
width: 400px;
background: yellow;
}
div.header {
white-space: nowrap;
display: inline;
width: 100%;
}
div.one-line-div {
font-size: larger;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
}
.move-divs {
display: inline-block;
float: right;
}
.div1, .div2, .div3, .div4 {
float: right;
margin-right: 12px;
cursor: pointer;
display: inline-block;
width: 30px;
height: 30px;
background: blue;
}
.myText {
max-width: 55%;
text-overflow: ellipsis;
overflow: hidden;
display: inline-block;
}
.more-divs {
display: inline-block
}
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">
<span class="myText">Text text, so much text here, what do we do with all this
text?.</span>
<div class="more-divs"">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
It is easy and best using flex or grid , though here using float as you said.
When using float this display:inline-block is not needed because float it self makes elements display inline
.page{
background: yellow;
}
.page-container{
width: 400px;
}
div.header {
white-space: nowrap;
width: 100%;
}
div.one-line-div {
font-size: larger;
white-space: nowrap;
width: 100%;
text-overflow: ellipsis;
overflow: hidden;
float: left;
}
.move-divs {
float: right;
}
.div1, .div2, .div3, .div4 {
margin-right: 12px;
cursor: pointer;
display: inline-block;
width: 30px;
height: 30px;
background: blue;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<body>
<div class="page">
<div class="page-container">
<div class="header">
<div class="one-line-div">Text text, so much text here, what do we do with all this text?.</div>
<div class="more-divs">
<div class="div1">
</div>
<div class="div2">
</div>
<div class="div3">
</div>
<div class="div4">
</div>
</div>
</div>
</div>
</div>
</div>
</body>
I have a child div with a border that should only wrap as much as the text. However, it seems to inherit the parent div's width.
Example: https://jsfiddle.net/xstaf3cc/
<div class="contentContainer">
<div>Title</div>
<div>Posted by u/user1</div>
<div class="text">
Text
</div>
</div>
.contentContainer {
display: flex;
flex-direction: column;
margin-bottom: 15;
}
.text {
border: 1px solid black;
}
How can I make the width of 'Text' not inherit its parent div's width? I would like its width to just be as long as the text.
Use align-items: flex-start; style on contentContainer div
.contentContainer {
display: flex;
flex-direction: column;
margin-bottom: 15px;
align-items: flex-start;
}
.text {
border: 1px solid black;
}
<div>
<div class="contentContainer">
<div>
<div>Title</div>
<div>Posted by u/user1</div>
</div>
<span class="text">
Text
</span>
</div>
</div>
use width: fit-content; to .text
.contentContainer {
display: flex;
flex-direction: column;
margin-bottom: 15;
}
.text {
border: 1px solid black;
width: fit-content;
}
<div>
<div class="contentContainer">
<div>
<div>Title</div>
<div>Posted by u/user1</div>
</div>
<div class="text">
Text
</div>
</div>
</div>
I need to make a responsive web, so that the width of parent is dynamic.
There are two flex items, one is long (dynamic) and another one is short (static).
I hope the result can look like the second line, that the long text is broken (or hidden when overlap), and the short text is always displayed correctly.
I tried to use flex-shrink: 0 but seems there is always an overflow.
How can I get rid of the overflow in this case?
I do need flex layout, and the js should not be involved.
.parent {
display: flex;
flex-direction: row;
width: 15rem;
background: yellowgreen;
padding: 10px;
overflow: hidden;
}
.flex-item {
width: 10em;
padding: 10px;
background: yellow;
flex: 1 1 50%;
}
.block1 {
background: red;
}
.block2 {
background: orange;
}
.nos {
flex-shrink: 0 !important;
}
<div class="parent">
<div class="flex-item">
<div class="block1">
longlonglonglonglonglonglonglonglonglonglonglonglonglong
</div>
</div>
<div class="flex-item nos">
<div class="block2">
Display
</div>
</div>
</div>
<br/>
<div class="parent">
<div class="flex-item">
<div class="block1">
longlonglonglonglong...
</div>
</div>
<div class="flex-item">
<div class="block2">
Display
</div>
</div>
</div>
https://jsfiddle.net/templefox/Lw3hhz8j/
just put word-break:break-all property to its parent div. You can see it live by clicking this JSFiddle link
.parent {
display: flex;
width: 15rem;
padding: 10px;
background: yellowgreen;
/* overflow: hidden <-- not necessary at this point */
/* flex-direction: row <-- default value; can be omitted */
}
.flex-item {
/* width: 10em <-- not necessary at this point */
/* flex: 1 1 50% <-- not necessary at this point */
padding: 10px;
background: yellow;
display: flex; /* new */
min-width: 0; /* see note #1 */
}
.block1 {
width: 10em;
overflow: hidden; /* see note #2 */
text-overflow: ellipsis; /* see note #2 */
white-space: nowrap; /* see note #2 */
background: red;
}
.block2 {
background: orange;
}
/* .nos { flex-shrink: 0 !important; } */
<div class="parent">
<div class="flex-item">
<div class="block1">longlonglonglonglonglonglonglonglonglonglonglonglonglong</div>
</div>
<div class="flex-item">
<div class="block2">Display</div>
</div>
</div>
<br/>
<div class="parent">
<div class="flex-item">
<div class="block1">longlonglonglonglong...</div>
</div>
<div class="flex-item">
<div class="block2">Display</div>
</div>
</div>
revised fiddle
Notes:
Why doesn't flex item shrink past content size?
Applying an ellipsis to multiline text
Something like this.
*{
box-sizing:border-box;
}
.parent {
display: flex;
flex-direction: row;
width: 16rem;
background: yellowgreen;
padding: 10px;
overflow: hidden;
position: relative;
}
.flex-item {
width: 100%;
padding: 10px;
background: yellow;
flex: 1 1;
}
.block1 {
background: red;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding-right:70px;
}
.block2 {
background: orange;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.nos {
flex-shrink: 0 !important;
position: absolute;
right: 10px;
max-width: 70px;
}
<div class="parent">
<div class="flex-item">
<div class="block1">
longlonglonglonglonglonglonglonglonglonglonglonglonglong
</div>
</div>
<div class="flex-item nos">
<div class="block2">
Display
</div>
</div>
</div>
I have the following snippet of html that forms an X-Y scrollable listbox
* {
font-family: "consolas";
}
.listbox {
border: 1px solid black;
padding: 4px;
width: 150px;
height: 200px;
display: flex;
flex-direction: column;
}
.caption {
font-weight: bold;
background-color: #aaf;
padding: 10px;
}
.content {
flex-grow: 1;
overflow: scroll;
}
.item {
background-color: #ddd;
padding: 2px;
padding-left: 6px;
margin-top: 4px;
white-space: nowrap;
}
<div class="listbox">
<div class="caption">Caption</div>
<div class="content">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three (this has a longer bit)</div>
<div class="item">Four</div>
<div class="item">Five</div>
<div class="item">Six</div>
<div class="item">Seven</div>
<div class="item">Eight (so does this)</div>
<div class="item">Nine</div>
<div class="item">Ten</div>
</div>
</div>
It's working fine, with one problem, as the user scrolls from left to right, the background of the div seems to get left behind. It's as though the actual div only stretches the width of its parent, and the scrolling/overflow thing is "faked" somehow.
Why is this the case?
How do I address the problem? The behaviour I want is for all the items to appear to be the same width as the largest one.
Try adding a container <div class="items"> around the items set it to display:inline-block.
.items {
display: inline-block;
}
* {
font-family: "consolas";
}
.listbox {
border: 1px solid black;
padding: 4px;
width: 150px;
height: 200px;
display: flex;
flex-direction: column;
}
.caption {
font-weight: bold;
background-color: #aaf;
padding: 10px;
}
.content {
flex-grow: 1;
overflow: scroll;
}
.items {
display: inline-block;
}
.item {
background-color: #ddd;
padding: 2px;
padding-left: 6px;
margin-top: 4px;
white-space: nowrap;
}
<div class="listbox">
<div class="caption">Caption</div>
<div class="content">
<div class="items">
<div class="item">One</div>
<div class="item">Two</div>
<div class="item">Three (this has a longer bit)</div>
<div class="item">Four</div>
<div class="item">Five</div>
<div class="item">Six</div>
<div class="item">Seven</div>
<div class="item">Eight (so does this)</div>
<div class="item">Nine</div>
<div class="item">Ten</div>
</div>
</div>
</div>
Explanation: by default a block level element takes 100% width of the container no more than that, however an inline block will expand to content length if available e.g. in a scrollable container.
Also apply .items {min-width: 100%;} in case you want the background to grow full width even with less text in every row.