Make a div containing CSS columns have unlimited width - css
Imagine a very common <header><article><footer> layout, where the header and footer are fixed heights and the article gets as tall as needed (the page scrolls vertically to accommodate). That's like most web pages.
What I'm trying to get is a layout just like that, but on its side so the article gets as wide as needed, and the page scrolls horizontally:
My initial attempts used flexbox:
Here is my first attempt on jsFiddle.
Relevant CSS:
body {
display: flex;
position: absolute;
height: 100%;
}
header {
background: green;
width: 400px;
flex: none;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
}
footer {
background: yellow;
width: 450px;
flex: none;
}
But I'm moving away from that as I try other things, like in this fiddle, which is a little closer. The problem with this attempt is that the article width is constrained to 100% of the viewport width, even though the text flows over to the right! (My article uses CSS columns which is absolutely important to my layout.)
My requirements are:
Header, Article, Footer to be 100% height (done)
Header to be 400px wide (done) and to left of content (done)
Footer to be 450px wide (done) and to right of the article (how?)
Article to be as wide as it needs to be without overlapping footer (how?)
So, I need help with the bolded goals. What can I do to keep the article from overlapping the footer to its right? Are there other ways to lay out this page so that the article width expands as the content does?
Should work in Chrome, Firefox, and Safari (IE and Opera a plus, but not necessary)
Preferably no JavaScript (or CSS features likely to be dropped from the spec)
Simple, clean CSS is ideal
I've been working on this all afternoon and without JS it seems pretty impossible. I've also fiddled with #Grily's solution and I think I nailed it in Chrome at least.
Solution 1 Works on Firefox, Chrome and IE
However I got this to work, sort of. It's not completely to spec.
HTML
<div id="DIV-1">Header </div>
.. in the Fiddle there's a lot of "Lorum ipsum here"
<div id="DIV-3">Footer </div>
CSS
#media only screen
and (orientation : landscape) {
body {
position: absolute;
display: block;
box-sizing: border-box;
white-space: normal;
-webkit-columns: 235px auto;
-moz-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
-moz-column-gap: 0;
column-gap: 0;
height: 100%;
float: left;
width: calc(100% + 450px);
min-width: -webkit-min-content;
padding-left: 400px;
}
#DIV-1{
position: absolute;
left: 0px;
box-sizing: border-box;
background-color: #2693FF;
height: 100%;
width: 400px;
float: left;
}
#DIV-3 {
position: relative;
float: right;
left: 205px;
box-sizing: border-box;
background-color: #FF7373;
height: 100%;
width: 450px;
-webkit-column-span: all;
-moz-column-span: all;
column-span: all;
-webkit-column-break-inside: avoid;
page-break-inside: avoid;
break-inside: avoid;
}
}
I've put the content container the columns directly into the body. (Can still be a div).
width: calc(100% + 450px);
min-width: -webkit-min-content;
This bit actually (by magic) forces the browser to recognize that the body has a width that is broader than the viewport. The positioning of the header is simple. absolute and add padding to the body and it's in place. The content now flows nicely to the right. Exception is the footer. I got it in the right position on it's own by using column-span: all. Firefox is going it's own way with this and actually renders it correctly. Chrome and IE render the column inline and only the width of the column. That's the drawback of this approach.
I hope you can do something with it or somebody else could improve this so it actually appends the footer at the end of the page without shrinking it to the column's width.
The Fiddle: http://jsfiddle.net/5dtq47m3/
Solution 2 - Works on Chrome
Edited the work of Grily.
HTML
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
........
</article>
<footer>Footer should be 450px wide and appear to the right of everything else.</footer>
CSS
* {
padding: 0;
margin: 0;
}
body {
display: flex;
position: absolute;
height: 100%;
}
header {
background: green;
width: 400px;
flex: none;
float: left;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
color: rgba(0, 0, 0, .75);
flex:none; /*added*/
width: calc(100% + 10px); /*added*/
max-width: -webkit-max-content; /*added*/
}
article p {
padding: .2em 15px;
text-indent: 1em;
hyphens: auto;
}
footer {
background: yellow;
width: 450px;
flex: none;
float: right; /*added*/
}
http://jsfiddle.net/w4wzf9n6/8/
I have the flex basics here: http://jsfiddle.net/hexalys/w4wzf9n6/16/ which is the cleanest theoretical css.
This places the footer to the right of the article and the article doesn't overlap with the footer. Best visible in Webkit/Blink with calculation issues on the text content width interpreted by Flex.
In an ideal world, Flexbox would know what to do with the columns and calculate the auto width of the article flex item. But because 1. This isn't specced yet; 2. Flex still has existing issues to be resolved; And 3. CSS Columns are still quite buggy and unstable. Webkit and Firefox handle his both differently and wrong. For Webkit a flex auto width is that of the <p> element on one line, and for FF/IE it is the size of one column only. So it's quite a dead end, and need solving by the W3C specs before this would work. I tried to wrap article, but it doesn't seem to help that cause.
Meanwhile if you know the constraint of the viewport height and the amount of text on the server side, you could use a JS fallback to give the article element a flex width before DOMContentLoaded. (See my later comment for a partial Webkit/Blink polyfill)
Update: The multi-column issue is a know problem back from 2007. This case was added as reference on the CSS Working Group wiki page listing current multicolumn issues
Here's a solution that works on webkit browsers, Firefox, and IE:
// JS to work around the CSS column bug where the width
// is not properly calculated by the browser. We have a
// float:right marker at the end of the article. Set the
// width of the article to be where the marker is.
function resize()
{
var article = document.querySelector("article"),
marker = document.querySelector("endmarker");
article.style.width = (marker.offsetLeft) + "px";
}
window.addEventListener("resize", resize);
resize();
* { padding: 0; margin: 0; }
holder {
position: absolute;
top: 0; left: 0;
height: 100%;
background: #fed;
white-space: nowrap;
}
header,
article,
footer {
position: relative;
display: inline-block;
height: 100%;
vertical-align: top;
white-space: normal;
}
header {
background: green;
width: 400px;
}
endmarker {
position: relative;
display: block;
float: right;
width: 10px;
height: 10px;
background: red;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
-moz-columns: 235px auto;
columns: 235px auto;
-webkit-column-fill: auto;
-moz-column-fill: auto;
column-fill: auto;
-webkit-column-gap: 0;
-moz-column-gap: 0;
column-gap: 0;
}
article p {
padding: .2em 15px;
text-indent: 1em;
hyphens: auto;
}
footer {
background: yellow;
width: 450px;
}
<holder>
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b>
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo venenatis efficitur. Nam vel ultricies urna, non auctor lorem. Suspendisse sodales, nunc eu pharetra ornare, elit quam scelerisque ex, id congue orci lectus eget turpis. Ut consequat nisi et erat efficitur faucibus. Maecenas laoreet magna nec odio porta, et consequat leo rhoncus. In imperdiet pellentesque justo eu pellentesque. Curabitur ut ante tristique, placerat est porta, porttitor ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed scelerisque est vitae orci elementum, et vehicula quam lacinia. Vivamus vestibulum metus quis dui dictum vehicula. Mauris et tempor libero.</p>
<p>Sed lorem quam, feugiat sit amet vehicula non, ultricies quis quam. Ut lobortis leo ac ex facilisis, vel elementum ante feugiat. Quisque efficitur tellus sed sodales dictum. Mauris sed justo dictum, finibus velit id, pulvinar mi. Phasellus mi augue, finibus ut vestibulum et, volutpat id sapien. Sed feugiat eleifend augue, ut commodo nulla bibendum ac. Nullam quis posuere lectus. Curabitur dictum quam id massa finibus blandit. Nam malesuada metus ut massa ullamcorper luctus. Curabitur vitae dictum orci, a finibus sapien. Maecenas eget nisl tempus, pharetra enim eget, tempor urna. Suspendisse viverra felis bibendum neque rhoncus, id eleifend tortor sodales. Suspendisse sed magna pulvinar, laoreet turpis nec, ultrices enim. Vivamus at auctor arcu. Nunc vitae suscipit tellus. Etiam ut accumsan arcu.</p>
<p>Morbi faucibus, mauris sed blandit ultrices, turpis turpis dapibus quam, quis consectetur erat nibh cursus magna. Donec quis ullamcorper quam, a facilisis leo. Phasellus ut mauris eget risus ultrices lobortis. Pellentesque semper ante eu vehicula pharetra. Vestibulum congue orci non felis vehicula volutpat. Praesent vel euismod ligula. Sed vitae placerat ipsum, a hendrerit felis. Mauris vitae fermentum nunc, non tincidunt magna. Fusce nibh ex, porta sed ante ut, dapibus maximus urna. Nulla tristique magna ipsum, at sodales ipsum feugiat a. Mauris convallis mi vel arcu vehicula elementum. Aliquam aliquet hendrerit lectus, congue auctor ipsum sodales vitae. Phasellus congue, ex non viverra cursus, nunc est fermentum dui, ac tincidunt turpis mauris a tellus. Curabitur sollicitudin condimentum mauris consectetur tincidunt. Morbi vulputate ac augue ut maximus.</p>
<p>Nulla in auctor ligula. In euismod volutpat ex a eleifend. Sed eu elit et nulla faucibus fringilla. Sed posuere metus in elit gravida pharetra. Vivamus a ultricies ipsum. Mauris mollis est nisi, a convallis est iaculis id. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam tincidunt blandit metus nec sagittis. Sed faucibus non urna in ullamcorper. Sed feugiat, tellus ut feugiat mollis, ligula neque molestie augue, vitae mattis ligula eros eget augue. Curabitur finibus sodales metus ac finibus. Sed id mollis ante. Phasellus vitae purus vel risus pulvinar aliquet. Vestibulum vitae elementum felis.</p>
<p>Nam ipsum ipsum, consequat in dictum vitae, malesuada eget est. Phasellus elementum lacinia maximus. Maecenas dictum neque ligula, et congue mauris venenatis eu. Pellentesque pretium tortor nec ligula rutrum, a aliquet eros aliquam. Etiam euismod varius ipsum, id molestie massa. Quisque elementum lacus at ipsum egestas facilisis. Maecenas arcu risus, euismod ac lacus ac, euismod dictum nunc. Aenean non felis aliquet mi tincidunt bibendum. Curabitur ultricies ullamcorper gravida. In pretium nibh non eleifend egestas. Cum sociis natoquenatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin auctor lacus erat, sit amet vestibulum lorem mattis in. Aenean dapibus at risus ac lacinia. Vivamus fringilla nulla diam, vel facilisis magna mollis maximus. Sed quis dolor tempor magna pharetra scelerisque. Nam velit felis, mollis sit amet risus et, imperdiet interdum nibh.</p>
<p>END OF ARTICLE</p>
<endmarker></endmarker>
</article>
<footer>Footer should be 450px wide and appear to the right of everything else.</footer>
</holder>
http://jsfiddle.net/jmhh56g2/2/
All browsers have a bug with column layout and how they calculate the width of the element with columns. So unfortunately, a tiny bit of JS is needed to set the width. I know the requirement said "preferably no javascript", but this is fairly minimal and it works on all browsers that support CSS columns.
Quick overview:
Put the entire content in an absolutely positioned div (<holder>) that is 100% height. This pulls the content out of the main body flow and prevents the body and viewport width from doing crazy things.
Set white-space: nowrap on <holder> and normal for all other elements. This forces the header,article, and footer to align horizontally, while allowing the text inside them to flow normally.
Set all elements to be position: relative (needed for offsetWidth)
Create a little marker element at the article that is float:right. This is used to calculate the correct width.
A tiny bit of js to watch the window resize event and recalculate the proper width for the article.
Flexbox does indeed work for this, but you need to add a few more things.
Add the following CSS:
article {
display: flex;
}
To make each paragraph inside the article tag the same width, add:
article p {
flex: 1;
}
A quick fix for the width (and height) of the footer, add:
footer {
display: table;
height: 100%;
}
Edit:
Been playing around with it a little, but didn't figure it out yet.
I'll just leave the code here, but it's incorrect.
html {
height: 100vh;
}
body {
display: -webkit-box;
height: 100%;
}
header {
background: green;
width: 400px;
flex: none;
}
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
color: rgba(0, 0, 0, .75);
height: 100%;
}
footer {
background: yellow;
width: 450px;
display: table;
height: 100%;
}
The simple answer is to set the overflow-x and overflow-y on the body, and then display: inline-block the elements inside. Here's the code:
body {
height: 500px; /* just for demo */
white-space: nowrap;
overflow-x: scroll;
overflow-y: hidden;
}
header,
article,
footer,
.box {
display: inline-block;
height: 500px; /* just for demo */
}
header,
footer {
width: 200px;
background: #666;
}
.box {
width: 300px; /* just for demo */
background: #ccc;
}
<header>header</header>
<article>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
<div class="box">stuff</div>
</article>
<footer>footer</footer>
Here is a demo
There is a lot to be said for flex. I suggest bookmarking this link: CSS-TRICKS A Complete guide to FlexBox
Regarding the columns - column width is a minimum width, not a forced value so you will never see a partial column within <article> tags
Css Changes as noted and fiddle following:
article {
background: #CCC;
-webkit-columns: 235px auto;
columns: 235px auto;
-webkit-column-gap: 0;
column-gap: 0;
color: rgba(0, 0, 0, .75);
/* Added */
overflow:hidden;
overflow-x: scroll;
}
footer {
background: yellow;
/* Changed */
min-width: 450px;
display: block;
}
EDIT: I updated my fiddle; There are some limitations being imposed by Fiddle in that the results are displayed in an iframe that limit the width and height to 100% of the results display quadrant so you don't really get to see true browser results.
The solution in this edited fiddle does not use Flex, but a combination of inline-blocks with some white-space management. This is as close as I could come with the time I had. Hope it helps.
Updated: FIDDLE
Possible solution.
The CSS:
<style type="text/css">
* {
margin:0;
padding:0;
}
html {
height:100%;
}
body {
display:table;
height:100%;
width:100%;
}
header {
background:green;
display:table-cell;
vertical-align:top;
width:400px;
}
article {
background:#CCC;
color:rgba(0, 0, 0, .75);
display:table-cell;
}
article div {
-moz-column-gap:0;
-moz-columns:235px auto;
-webkit-column-gap:0;
-webkit-columns:235px auto;
column-gap:0;
columns:235px auto;
height:100%;
max-height:1vh;
min-height:100%;
overflow-x:scroll;
}
article p {
hyphens:auto;
padding:.2em 15px;
text-indent:1em;
}
footer {
background:yellow;
display:table-cell;
vertical-align:top;
width:450px;
}
</style>
The HTML:
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
<div>
<p>Article Text</p>
</div>
</article>
<footer>
Footer should be 450px wide and appear to the right of everything else.
</footer>
Man I thought I had it... It works if the window is a particular height. If you change the size of the output pane, the content doesn't fit evenly. Works the same in both Firefox and Chrome, wanted to put it out there to see if it helps someone get closer to a solution.
http://jsfiddle.net/ryanwheale/bbhmkLw5/
HTML:
<article>
<header></header>
<section></section>
<footer></footer>
</article>
CSS:
html, body, article, header, section, footer {
height: 100%;
margin: 0;
}
html, body {
background: red;
width: calc(100% + 850px);
}
article {
white-space: nowrap;
background: blue;
}
article > * {
white-space: normal;
display: inline-block;
vertical-align: top;
}
header {
background: green;
width: 400px;
}
section {
background: grey;
-webkit-columns: 2000 235px;
-moz-columns: 2000 235px;
columns: 2000 235px;
-moz-column-fill: auto;
}
footer {
background: yellow;
width: 450px;
}
Check this out!
Some JavaScript code is needed to calculate dynamic width, otherwise overall structure is simple and will work with almost all major browser (didn't checked JS, but that will be easy change, "in case"!).
You can also check on JSFiddle here.
var header = document.getElementsByTagName('header')[0].offsetWidth;
var article = document.getElementsByTagName('article')[0].children[0].offsetWidth * document.getElementsByTagName('article')[0].children.length;
var footer = document.getElementsByTagName('footer')[0].offsetWidth;
document.getElementsByTagName('html')[0].style.width = header + article + footer + 'px';
html,body,header,article,article p,footer{
margin:0px;
padding:0px;
height:100%;
}
html{ width: 100%; }
body{ width: auto; }
header, footer{
width: 200px;
float: left;
}
header{ background-color: green; }
footer{ background-color:yellow; }
article{
display:block;
width: auto;
float: left;
}
article p{
border:1px solid red;
width: 200px;
float: left;
display:inline-block;
}
<header>
<h1>Article Title</h1>
</header>
<article>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b></p>
</article>
<footer>
Footer should be 450px wide and appear to the right of everything else.
</footer>
You should use table css then it's easy - otherwise it's pain in the butt
Here is a working example: http://jsfiddle.net/y60zy7fp/1/
The main difference is removing flex and then wrapping everything in 1 .layout and 1 more div for table and table-row, and first element in div in .layout will become column this is css:
.layout {
display: table;
}
.layout > div {
display: table-row;
}
.layout > div > * {
display: table-cell;
}
update:
The article needs to have set width for the scroll to become horizontal.
In my example it's 200%.
example: http://jsfiddle.net/n3okxq94/7/
Why it has to have width? Because the width of a paragraph is the size of the container. And you're asking the container to set the width according to paragraph which has width: auto
You can add white-space: nowrap on article but that makes all text one line http://jsfiddle.net/n3okxq94/10/
finished? http://jsfiddle.net/n3okxq94/8/
You could put inside of the article something like at least one <p style="width: 1000px;">and that way you could have width per-article
How about this simple sultion below using very simple CSS and HTML?
html, body {width:100%; height:100%; min-height:100%; margin:0; padding:0;}
article {width:100%; height:100%; min-height:100%;}
header {width:400px; float:left; background:red; height:100%; min-height:100%;}
section {width:auto; display:block; background:blue; height:100%; min-height:100%; padding-right:450px;}
footer {width:450px; position:absolute; top:0; right:0; background:green; height:100%; min-height:100%;}
<article>
<header>content</header>
<section>content</section>
<footer>content</footer>
</article>
Hi Matt just try it me be it help full sorry for i can't make the live demo.
First download this jQuery library http://manos.malihu.gr/jquery-custom-content-scroller/ and css and js file in your code as lik.
<link rel="stylesheet" href="../jquery.mCustomScrollbar.css">
<style>
* {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width:auto;
display:block;
white-space:nowrap;
}
header, article, footer {
float: left;
height:100%;
vertical-align:top;
white-space:normal;
}
header {
background: green;
width: 250px;
padding: 0px 15px;
}
article {
background: #CCC;
color: rgba(0, 0, 0, .75);
width: 100%;
padding-right: 20px;
}
article p {
padding: .2em 15px;
text-indent: 1em;
hyphens: auto;
}
footer {
background: yellow;
width: 250px;
padding: 0px 15px;
}
.showcase #content-6.horizontal-images.content{
padding: 10px 0 5px 0;
background-color: #444;
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAYAAACp8Z5+AAAAG0lEQVQIW2NkYGA4A8QmQAwGjDAGNgGwSgwVAFVOAgV/1mwxAAAAAElFTkSuQmCC");
}
.showcase #content-6.horizontal-images.content .mCSB_scrollTools{
margin-left: 10px;
margin-right: 10px;
}
</style>
<body>
<header>
<h1>Article Title (width 400)</h1>
</header>
<article>
<p><b>Article should stretch as wide as it needs to be. Horizontal scrolling only. Preferably, columns aren't sized according to viewport width. Seeing partial column helps the user know they can scroll left.</b>
</p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed commodo venenatis efficitur. Nam vel ultricies urna, non auctor lorem. Suspendisse sodales, nunc eu pharetra ornare, elit quam scelerisque ex, id congue orci lectus eget turpis. Ut consequat nisi et erat efficitur faucibus. Maecenas laoreet magna nec odio porta, et consequat leo rhoncus. In imperdiet pellentesque justo eu pellentesque. Curabitur ut ante tristique, placerat est porta, porttitor ligula. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed scelerisque est vitae orci elementum, et vehicula quam lacinia. Vivamus vestibulum metus quis dui dictum vehicula. Mauris et tempor libero.</p>
<p>Sed lorem quam, feugiat sit amet vehicula non, ultricies quis quam. Ut lobortis leo ac ex facilisis, vel elementum ante feugiat. Quisque efficitur tellus sed sodales dictum. Mauris sed justo dictum, finibus velit id, pulvinar mi. Phasellus mi augue, finibus ut vestibulum et, volutpat id sapien. Sed feugiat eleifend augue, ut commodo nulla bibendum ac. Nullam quis posuere lectus. Curabitur dictum quam id massa finibus blandit. Nam malesuada metus ut massa ullamcorper luctus. Curabitur vitae dictum orci, a finibus sapien. Maecenas eget nisl tempus, pharetra enim eget, tempor urna. Suspendisse viverra felis bibendum neque rhoncus, id eleifend tortor sodales. Suspendisse sed magna pulvinar, laoreet turpis nec, ultrices enim. Vivamus at auctor arcu. Nunc vitae suscipit tellus. Etiam ut accumsan arcu.</p>
<p>Morbi faucibus, mauris sed blandit ultrices, turpis turpis dapibus quam, quis consectetur erat nibh cursus magna. Donec quis ullamcorper quam, a facilisis leo. Phasellus ut mauris eget risus ultrices lobortis. Pellentesque semper ante eu vehicula pharetra. Vestibulum congue orci non felis vehicula volutpat. Praesent vel euismod ligula. Sed vitae placerat ipsum, a hendrerit felis. Mauris vitae fermentum nunc, non tincidunt magna. Fusce nibh ex, porta sed ante ut, dapibus maximus urna. Nulla tristique magna ipsum, at sodales ipsum feugiat a. Mauris convallis mi vel arcu vehicula elementum. Aliquam aliquet hendrerit lectus, congue auctor ipsum sodales vitae. Phasellus congue, ex non viverra cursus, nunc est fermentum dui, ac tincidunt turpis mauris a tellus. Curabitur sollicitudin condimentum mauris consectetur tincidunt. Morbi vulputate ac augue ut maximus.</p>
<p>Nulla in auctor ligula. In euismod volutpat ex a eleifend. Sed eu elit et nulla faucibus fringilla. Sed posuere metus in elit gravida pharetra. Vivamus a ultricies ipsum. Mauris mollis est nisi, a convallis est iaculis id. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Etiam tincidunt blandit metus nec sagittis. Sed faucibus non urna in ullamcorper. Sed feugiat, tellus ut feugiat mollis, ligula neque molestie augue, vitae mattis ligula eros eget augue. Curabitur finibus sodales metus ac finibus. Sed id mollis ante. Phasellus vitae purus vel risus pulvinar aliquet. Vestibulum vitae elementum felis.</p>
<p>Nam ipsum ipsum, consequat in dictum vitae, malesuada eget est. Phasellus elementum lacinia maximus. Maecenas dictum neque ligula, et congue mauris venenatis eu. Pellentesque pretium tortor nec ligula rutrum, a aliquet eros aliquam. Etiam euismod varius ipsum, id molestie massa. Quisque elementum lacus at ipsum egestas facilisis. Maecenas arcu risus, euismod ac lacus ac, euismod dictum nunc. Aenean non felis aliquet mi tincidunt bibendum. Curabitur ultricies ullamcorper gravida. In pretium nibh non eleifend egestas. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin auctor lacus erat, sit amet vestibulum lorem mattis in. Aenean dapibus at risus ac lacinia. Vivamus fringilla nulla diam, vel facilisis magna mollis maximus. Sed quis dolor tempor magna pharetra scelerisque. Nam velit felis, mollis sit amet risus et, imperdiet interdum nibh.</p>
</article>
<footer>Footer should be 450px wide and appear to the right of everything else.</footer>
<!-- Google CDN jQuery with fallback to local -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- custom scrollbar plugin -->
<script src="../jquery.mCustomScrollbar.concat.min.js"></script>
<script>
(function ($) {
$(window).load(function () {
$.mCustomScrollbar.defaults.theme = "light-2"; //set "light-2" as the default theme
$("article").mCustomScrollbar({
axis: "x",
advanced: {autoExpandHorizontalScroll: true}
});
jQuery('article').css({'max-width': jQuery(window).width() - 581});
});
})(jQuery);
</script>
</body>
Related
Text ellipsis is not working [duplicate]
This question already has answers here: Limit text length to n lines using CSS (17 answers) Closed 2 years ago. Is there a solution to add ellipsis on last line inside a div with a fluid height (20%)? I found the -webkit-line-clamp function in CSS, but in my case the line number will be depending on window size. p { width:100%; height:20%; background:red; position:absolute; } <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed dui felis. Vivamus vitae pharetra nisl, eget fringilla elit. Ut nec est sapien. Aliquam dignissim velit sed nunc imperdiet cursus. Proin arcu diam, tempus ac vehicula a, dictum quis nibh. Maecenas vitae quam ac mi venenatis vulputate. Suspendisse fermentum suscipit eros, ac ultricies leo sagittis quis. Nunc sollicitudin lorem eget eros eleifend facilisis. Quisque bibendum sem at bibendum suscipit. Nam id tellus mi. Mauris vestibulum, eros ac ultrices lacinia, justo est faucibus ipsum, sed sollicitudin sapien odio sed est. In massa ipsum, bibendum quis lorem et, volutpat ultricies nisi. Maecenas scelerisque sodales ipsum a hendreritLorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed dui felis. Vivamus vitae pharetra nisl, eget fringilla elit. Ut nec est sapien. Aliquam dignissim velit sed nunc imperdiet cursus. Proin arcu diam, tempus ac vehicula a, dictum quis nibh. Maecenas vitae quam ac mi venenatis vulputate. Suspendisse fermentum suscipit eros, ac ultricies leo sagittis quis. Nunc sollicitudin lorem eget eros eleifend facilisis. Quisque bibendum sem at bibendum suscipit. Nam id tellus mi. Mauris vestibulum, eros ac ultrices lacinia, justo est faucibus ipsum, sed sollicitudin sapien odio sed est. In massa ipsum, bibendum quis lorem et, volutpat ultricies nisi. Maecenas scelerisque sodales ipsum a hendrerit.</p> I have this JSFiddle to illustrate the issue. https://jsfiddle.net/96knodm6/
Increase the -webkit-line-clamp: 4; to increase the number of lines: p { display: -webkit-box; max-width: 200px; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; } <p>Lorem ipsum dolor sit amet, novum menandri adversarium ad vim, ad his persius nostrud conclusionemque. Ne qui atomorum pericula honestatis. Te usu quaeque detracto, idque nulla pro ne, ponderum invidunt eu duo. Vel velit tincidunt in, nulla bonorum id eam, vix ad fastidii consequat definitionem.</p> Line clamp is a proprietary and undocumented CSS (webkit) : https://caniuse.com/#feat=css-line-clamp, so it currently works on only a few browsers. Removed duplicated 'display' property + removed unnecessary 'text-overflow: ellipsis'.
If you want to apply ellipsis (...) to a single line of text, CSS makes that somewhat easy with the text-overflow property. It's still a bit tricky (due to all the requirements – see below), but text-overflow makes it possible and reliable. If, however, you want to use ellipsis on multiline text – as would be the case here – then don't expect to have any fun. CSS has no standard method for doing this, and the workarounds are hit and miss. Ellipsis for Single Line Text With text-overflow, ellipsis can be applied to a single line of text. The following CSS requirements must be met: must have a width, max-width or flex-basis must have white-space: nowrap must have overflow with value other than visible must be display: block or inline-block (or the functional equivalent, such as a flex item). So this will work: p { width: 200px; white-space: nowrap; overflow: hidden; display: inline-block; text-overflow: ellipsis; border: 1px solid #ddd; margin: 0; } <p> This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. </p> jsFiddle version BUT, try removing the width, or letting the overflow default to visible, or removing white-space: nowrap, or using something other than a block container element, AND, ellipsis fails miserably. One big takeaway here: text-overflow: ellipsis has no effect on multiline text. (The white-space: nowrap requirement alone eliminates that possibility.) p { width: 200px; /* white-space: nowrap; */ height: 90px; /* new */ overflow: hidden; display: inline-block; text-overflow: ellipsis; border: 1px solid #ddd; margin: 0; } <p> This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. This is a test of CSS <i>text-overflow: ellipsis</i>. </p> jsFiddle version Ellipsis for Multiline Text Because CSS has no property for ellipsis on multiline text, various workarounds have been created. Several of these methods can be found here: jQuery dotdotdot... Line Clampin’ (Truncating Multiple Line Text) CSS Ellipsis: How to Manage Multi-Line Ellipsis in Pure CSS A pure CSS solution for multiline text truncation The Mobify link above was removed and now references an archive.org copy, but appears to be implemented in this codepen.
p { width:100%; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; background:#fff; position:absolute; } <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed dui felis. Vivamus vitae pharetra nisl, eget fringilla elit. Ut nec est sapien. Aliquam dignissim velit sed nunc imperdiet cursus. Proin arcu diam, tempus ac vehicula a, dictum quis nibh. Maecenas vitae quam ac mi venenatis vulputate. Suspendisse fermentum suscipit eros, ac ultricies leo sagittis quis. Nunc sollicitudin lorem eget eros eleifend facilisis. Quisque bibendum sem at bibendum suscipit. Nam id tellus mi. Mauris vestibulum, eros ac ultrices lacinia, justo est faucibus ipsum, sed sollicitudin sapien odio sed est. In massa ipsum, bibendum quis lorem et, volutpat ultricies nisi. Maecenas scelerisque sodales ipsum a hendreritLorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sed dui felis. Vivamus vitae pharetra nisl, eget fringilla elit. Ut nec est sapien. Aliquam dignissim velit sed nunc imperdiet cursus. Proin arcu diam, tempus ac vehicula a, dictum quis nibh. Maecenas vitae quam ac mi venenatis vulputate. Suspendisse fermentum suscipit eros, ac ultricies leo sagittis quis. Nunc sollicitudin lorem eget eros eleifend facilisis. Quisque bibendum sem at bibendum suscipit. Nam id tellus mi. Mauris vestibulum, eros ac ultrices lacinia, justo est faucibus ipsum, sed sollicitudin sapien odio sed est. In massa ipsum, bibendum quis lorem et, volutpat ultricies nisi. Maecenas scelerisque sodales ipsum a hendrerit.</p>
Please check this css for ellipsis to multi-line text body { margin: 0; padding: 50px; } /* mixin for multiline */ .block-with-text { overflow: hidden; position: relative; line-height: 1.2em; max-height: 6em; text-align: justify; margin-right: -1em; padding-right: 1em; } .block-with-text:before { content: '...'; position: absolute; right: 0; bottom: 0; } .block-with-text:after { content: ''; position: absolute; right: 0; width: 1em; height: 1em; margin-top: 0.2em; background: white; } <p class="block-with-text">The Hitch Hiker's Guide to the Galaxy has a few things to say on the subject of towels. A towel, it says, is about the most massivelyuseful thing an interstellar hitch hiker can have. Partly it has great practical value - you can wrap it around you for warmth as you bound across the cold moons of Jaglan Beta; you can lie on it on the brilliant marble-sanded beaches of Santraginus V, inhaling the heady sea vapours; you can sleep under it beneath the stars which shine so redly on the desert world of Kakrafoon; use it to sail a mini raft down the slow heavy river Moth; wet it for use in hand-to-hand-combat; wrap it round your head to ward off noxious fumes or to avoid the gaze of the Ravenous Bugblatter Beast of Traal (a mindboggingly stupid animal, it assumes that if you can't see it, it can't see you - daft as a bush, but very ravenous); you can wave your towel in emergencies as a distress signal, and of course dry yourself off with it if it still seems to be clean enough. More importantly, a towel has immense psychological value. For some reason, if a strag (strag: non-hitch hiker) discovers that a hitch hiker has his towel with him, he will automatically assume that he is also in possession of a toothbrush, face flannel, soap, tin of biscuits, flask, compass, map, ball of string, gnat spray, wet weather gear, space suit etc., etc. Furthermore, the strag will then happily lend the hitch hiker any of these or a dozen other items that the hitch hiker might accidentally have "lost". What the strag will think is that any man who can hitch the length and breadth of the galaxy, rough it, slum it, struggle against terrible odds, win through, and still knows where his towel is is clearly a man to be reckoned with.</p>
I took a look at how YouTube solves it on their homepage and simplified it: .multine-ellipsis { -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis; white-space: normal; } This will allow 2 lines of code and then append an ellipsis. Gist: https://gist.github.com/eddybrando/386d3350c0b794ea87a2082bf4ab014b
I finally found a solution to do what I want. As p a paragraphe and article the wrapper. If you want to apply ellipsis to p depending on article height (which also depends on window height), you need to get the height of the article, the line-height of the p and then articleHeight/lineHeight to find the number of line-clamp that can be added dynamically then. The only thing is the line-height should be declared in the css file. Check the following code. If you change the height of the window, the line-clamp will change. Can be great to create a plug-in aiming to do that. jsfiddle function lineclamp() { var lineheight = parseFloat($('p').css('line-height')); var articleheight = $('article').height(); var calc = parseInt(articleheight/lineheight); $("p").css({"-webkit-line-clamp": "" + calc + ""}); } $(document).ready(function() { lineclamp(); }); $( window ).resize(function() { lineclamp(); }); article { height:60%; background:red; position:absolute; } p { margin:0; line-height:120%; display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <article> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque lorem ligula, lacinia a justo sed, porttitor vulputate risus. In non feugiat risus. Sed vitae urna nisl. Duis suscipit volutpat sollicitudin. Donec ac massa elementum massa condimentum mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla sollicitudin sapien at enim sodales dapibus. Pellentesque sed nisl eu sem aliquam tempus nec ut leo. Quisque rutrum nulla nec aliquam placerat. Fusce a massa ut sem egestas imperdiet. Sed sollicitudin id dolor egestas malesuada. Quisque placerat lobortis ante, id ultrices ipsum hendrerit nec. Quisque quis ultrices erat.Nulla gravida ipsum nec sapien pellentesque pharetra. Suspendisse egestas aliquam nunc vel egestas. Nullam scelerisque purus interdum lectus consectetur mattis. Aliquam nunc erat, accumsan ut posuere eu, vehicula consequat ipsum. Fusce vel ex quis sem tristique imperdiet vel in mi. Cras leo orci, fermentum vitae volutpat vitae, convallis semper libero. Phasellus a volutpat diam. Ut pulvinar purus felis, eu vehicula enim aliquet vitae. Suspendisse quis lorem facilisis ante interdum euismod et vitae risus. Vestibulum varius nulla et enim malesuada fringilla. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque lorem ligula, lacinia a justo sed, porttitor vulputate risus. In non feugiat risus. Sed vitae urna nisl. Duis suscipit volutpat sollicitudin. Donec ac massa elementum massa condimentum mollis. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla sollicitudin sapien at enim sodales dapibus. Pellentesque sed nisl eu sem aliquam tempus nec ut leo. Quisque rutrum nulla nec aliquam placerat. Fusce a massa ut sem egestas imperdiet. Sed sollicitudin id dolor egestas malesuada. Quisque placerat lobortis ante, id ultrices ipsum hendrerit nec.</p></article>
I have just been playing around a little bit with this concept. Basically, if you are ok with potentially having a pixel or so cut off from your last character, here is a pure css and html solution: The way this works is by absolutely positioning a div below the viewable region of a viewport. We want the div to offset up into the visible region as our content grows. If the content grows too much, our div will offset too high, so upper bound the height our content can grow. HTML: <div class="text-container"> <span class="text-content"> PUT YOUR TEXT HERE <div class="ellipsis">...</div> // You could even make this a pseudo-element </span> </div> CSS: .text-container { position: relative; display: block; color: #838485; width: 24em; height: calc(2em + 5px); // This is the max height you want to show of the text. A little extra space is for characters that extend below the line like 'j' overflow: hidden; white-space: normal; } .text-content { word-break: break-all; position: relative; display: block; max-height: 3em; // This prevents the ellipsis element from being offset too much. It should be 1 line height greater than the viewport } .ellipsis { position: absolute; right: 0; top: calc(4em + 2px - 100%); // Offset grows inversely with content height. Initially extends below the viewport, as content grows it offsets up, and reaches a maximum due to max-height of the content text-align: left; background: white; } I have tested this in Chrome, FF, Safari, and IE 11. You can check it out here: http://codepen.io/puopg/pen/vKWJwK You might even be able to alleviate the abrupt cut off of the character with some CSS magic. EDIT: I guess one thing that this imposes is word-break: break-all since otherwise the content would not extend to the very end of the viewport. :(
This man have the best solution. Only css: .multiline-ellipsis { display: block; display: -webkit-box; max-width: 400px; height: 109.2px; margin: 0 auto; font-size: 26px; line-height: 1.4; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; }
Unfortunately no with current state of affairs in CSS. Ellipsis rendering has prerequisite white-space:nowrap that effectively means: ellipsis are drawn on single line text containers only.
I came up with my own solution for this: /*this JS code puts the ellipsis (...) at the end of multiline ellipsis elements * * to use the multiline ellipsis on an element give it the following CSS properties * line-height:xxx * height:xxx (must line-height * number of wanted lines) * overflow:hidden * * and have the class js_ellipsis * */ //do all ellipsis when jQuery loads jQuery(document).ready(function($) {put_ellipsisses();}); //redo ellipsis when window resizes var re_ellipsis_timeout; jQuery( window ).resize(function() { //timeout mechanism prevents from chain calling the function on resize clearTimeout(re_ellipsis_timeout); re_ellipsis_timeout = setTimeout(function(){ console.log("re_ellipsis_timeout finishes"); put_ellipsisses(); }, 500); }); //the main function function put_ellipsisses(){ jQuery(".js_ellipsis").each(function(){ //remember initial text to be able to regrow when space increases var object_data=jQuery(this).data(); if(typeof object_data.oldtext != "undefined"){ jQuery(this).text(object_data.oldtext); }else{ object_data.oldtext = jQuery(this).text(); jQuery(this).data(object_data); } //truncate and ellipsis var clientHeight = this.clientHeight; var maxturns=100; var countturns=0; while (this.scrollHeight > clientHeight && countturns < maxturns) { countturns++; jQuery(this).text(function (index, text) { return text.replace(/\W*\s(\S)*$/, '...'); }); } }); }
Please check this below code for pure css trick with proper alignment which supports for all browsers .block-with-text { overflow: hidden; position: relative; line-height: 1.2em; max-height: 103px; text-align: justify; padding: 15px; } .block-with-text:after { content: '...'; position: absolute; right: 15px; bottom: -4px; background: linear-gradient(to right, #fffff2, #fff, #fff, #fff); } <p class="block-with-text">The Hitch Hiker's Guide to the Galaxy has a few things to say on the subject of towels. A towel, it says, is about the most massivelyuseful thing an interstellar hitch hiker can have. Partly it has great practical value - you can wrap it around you for warmth as you bound across the cold moons of Jaglan Beta; you can lie on it on the brilliant marble-sanded beaches of Santraginus V, inhaling the heady sea vapours; you can sleep under it beneath the stars which shine so redly on the desert world of Kakrafoon; use it to sail a mini raft down the slow heavy river Moth; wet it for use in hand-to-hand-combat; wrap it round your head to ward off noxious fumes or to avoid the gaze of the Ravenous Bugblatter Beast of Traal (a mindboggingly stupid animal, it assumes that if you can't see it, it can't see you - daft as a bush, but very ravenous); you can wave your towel in emergencies as a distress signal, and of course dry yourself off with it if it still seems to be clean enough. More importantly, a towel has immense psychological value. For some reason, if a strag (strag: non-hitch hiker) discovers that a hitch hiker has his towel with him, he will automatically assume that he is also in possession of a toothbrush, face flannel, soap, tin of biscuits, flask, compass, map, ball of string, gnat spray, wet weather gear, space suit etc., etc. Furthermore, the strag will then happily lend the hitch hiker any of these or a dozen other items that the hitch hiker might accidentally have "lost". What the strag will think is that any man who can hitch the length and breadth of the galaxy, rough it, slum it, struggle against terrible odds, win through, and still knows where his towel is is clearly a man to be reckoned with.</p>
May be this can help you guys. Multi Line Ellipses with tooltip hover. https://codepen.io/Anugraha123/pen/WOBdOb <div> <p class="cards-values">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc aliquet lorem commodo, semper mauris nec, suscipit nisi. Nullam laoreet massa sit amet leo malesuada imperdiet eu a augue. Sed ac diam quis ante congue volutpat non vitae sem. Vivamus a felis id dui aliquam tempus </p> <span class="tooltip"></span> </div>
You can achieve this by a few lines of CSS and JS. CSS: div.clip-context { max-height: 95px; word-break: break-all; white-space: normal; word-wrap: break-word; //Breaking unicode line for MS-Edge works with this property; } JS: $(document).ready(function(){ for(let c of $("div.clip-context")){ //If each of element content exceeds 95px its css height, extract some first //lines by specifying first length of its text content. if($(c).innerHeight() >= 95){ //Define text length for extracting, here 170. $(c).text($(c).text().substr(0, 170)); $(c).append(" ..."); } } }); HTML: <div class="clip-context"> (Here some text) </div>
After many tries, I finally ended up with a mixed js / css to handle multiline and single line overflows. CSS3 code: .forcewrap { // single line ellipsis -ms-text-overflow: ellipsis; -o-text-overflow: ellipsis; text-overflow: ellipsis; overflow: hidden; -moz-binding: url( 'bindings.xml#ellipsis' ); white-space: nowrap; display: block; max-width: 95%; // spare space for ellipsis } .forcewrap.multiline { line-height: 1.2em; // my line spacing max-height: 3.6em; // 3 lines white-space: normal; } .manual-ellipsis:after { content: "\02026"; // '...' position: absolute; // parent container must be position: relative right: 10px; // typical padding around my text bottom: 10px; // same reason as above padding-left: 5px; // spare some space before ellipsis background-color: #fff; // hide text behind } and I simply check with js code for overflows on divs, like this: function handleMultilineOverflow(div) { // get actual element that is overflowing, an anchor 'a' in my case var element = $(div).find('a'); // don't know why but must get scrollHeight by jquery for anchors if ($(element).innerHeight() < $(element).prop('scrollHeight')) { $(element).addClass('manual-ellipsis'); } } Usage example in html: <div class="towrap"> <h4> <a class="forcewrap multiline" href="/some/ref">Very long text</a> </h4> </div>
Well you could use the line-clamp function in CSS3. p { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; line-height: 25px; height: 52px; max-height: 52px; font-size: 22px; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } Make sure you change the settings like you're own.
To bad CSS doesn't support cross-browser multiline clamping, only webkit seems to be pushing it. You could try and use a simple Javascript ellipsis library like Ellipsity on github the source code is very clean and small so if you do need to make any additional changes it should be quite easy. https://github.com/Xela101/Ellipsity
<!DOCTYPE html> <html> <head> <style> /* styles for '...' */ .block-with-text { width: 50px; height: 50px; /* hide text if it more than N lines */ overflow: hidden; /* for set '...' in absolute position */ position: relative; /* use this value to count block height */ line-height: 1.2em; /* max-height = line-height (1.2) * lines max number (3) */ max-height: 3.6em; /* fix problem when last visible word doesn't adjoin right side */ text-align: justify; /* place for '...' */ margin-right: -1em; padding-right: 1em; } /* create the ... */ .block-with-text:before { /* points in the end */ content: '...'; /* absolute position */ position: absolute; /* set position to right bottom corner of block */ right: 0; bottom: 0; } /* hide ... if we have text, which is less than or equal to max lines */ .block-with-text:after { /* points in the end */ content: ''; /* absolute position */ position: absolute; /* set position to right bottom corner of text */ right: 0; /* set width and height */ width: 1em; height: 1em; margin-top: 0.2em; /* bg color = bg color under block */ background: white; } </style> </head> <body> a <div class="block-with-text">g fdsfkjsndasdasd asd asd asdf asdf asdf asdfas dfa sdf asdflk jgnsdlfkgj nsldkfgjnsldkfjgn sldkfjgnls dkfjgns ldkfjgn sldkfjngl sdkfjngls dkfjnglsdfkjng lsdkfjgn sdfgsd</div> <p>This is a paragraph.</p> </body> </html>
p{ line-height: 20px; width: 157px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } or we can restrict the lines by using and height and overflow.
After looking all over the internet and trying a lot of these options, the only way to make sure that it is covered correctly with support for i.e is through javascript, i created a loop function to go over post items that require multi line truncation. *note i used Jquery, and requires your post__items class to have a fixed max-height. // loop over post items $('.post__items').each(function(){ var textArray = $(this).text().split(' '); while($(this).prop('scrollHeight') > $(this).prop('offsetHeight')) { textArray.pop(); $(this).text(textArray.join(' ') + '...'); } });
If you are using javascript, maybe you can do something like below. However, this does not account the height of the container... // whatever string const myString = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pellentesque sem ut consequat pulvinar. Curabitur vehicula quam sit amet risus aliquet, sed rhoncus tortor fermentum. Etiam ac fermentum nisi. Ut in lobortis eros. Etiam urna felis, interdum sit amet fringilla eu, bibendum et nunc.'; // you can set max string length const maxStrLength = 100; const truncatedString = myString.length > maxStrLength ? `${myString.substring(0, maxStrLength)}...` : myString; console.log(truncatedString);
My solution that works for me for multiline ellipsis: .crd-para { color: $txt-clr-main; line-height: 2rem; font-weight: 600; margin-bottom: 1rem !important; overflow: hidden; span::after { content: "..."; padding-left: 0.125rem; } }
If you also have multiple elements and you want a link with read more button after ellipsis, take a look on https://stackoverflow.com/a/51418807/10104342 If you want something like this: Every month first 10 TB are are not charged. All other traffic... Read more
Pros: + Cross browser (IE11, Edge, Chrome, Firefox, Safari, etc.) + Most natural looking Cons: - Adds lots of extra elements to the DOM I wasn't satisfied with any of the workarounds I had seen. Most of them use line-clamp which is currently only supported in webkit. So I played around with it until I came up with a solution. This pure javascript solution should be compatible with IE10 and greater and all modern browsers. This is untested outside of the stackoverflow example space below. I think this is a good solution. The one big caveat is that it creates a span for each word inside the container, which will impact layout performance, so your mileage may vary. //This is designed to be run on page load, but if you wanted you could put all of this in a function and addEventListener and call it whenever the container is resized. var $container = document.querySelector('.ellipses-container'); //optional - show the full text on hover with a simple title attribute $container.title = $container.textContent.trim(); $container.textContent.trim().split(' ').some(function (word) { //create a span for each word and append it to the container var newWordSpan = document.createElement('span'); newWordSpan.textContent = word; $container.appendChild(newWordSpan); if (newWordSpan.getBoundingClientRect().bottom > $container.getBoundingClientRect().bottom) { //it gets into this block for the first element that has part of itself below the bottom of the container //get the last visible element var containerChildNodes = $container.childNodes; var lastVisibleElement = containerChildNodes[containerChildNodes.length - 2]; //replace this final span with the ellipsis character newWordSpan.textContent = '\u2026'; //if the last visible word ended very near the end of the line the ellipsis will have wrapped to the next line, so we need to remove letters from the last visible word while (lastVisibleElement.textContent != "" && newWordSpan.getBoundingClientRect().bottom > $container.getBoundingClientRect().bottom) { lastVisibleElement.style.marginRight = 0; lastVisibleElement.textContent = lastVisibleElement.textContent.slice(0, -1); } //using .some() so that we can short circuit at this point and no more spans will be added return true; } }); .multi-line-container { border: 1px solid lightgrey; padding: 4px; height: 150px; width: 300px; } .ellipses-container { display: inline-flex; flex-wrap: wrap; justify-content: flex-start; align-content: flex-start; /* optionally use align-content:stretch, the default, if you don't like the extra space at the bottom of the box if there's a half-line gap */ overflow: hidden; position: relative; } .ellipses-container > span { flex: 0 0 auto; margin-right: .25em; } .text-body { display: none; } <div class="multi-line-container ellipses-container"> <div class="text-body ellipses-text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque luctus ut massa eget porttitor. Nulla a eros sit amet ex scelerisque iaculis nec vitae turpis. Sed pharetra tincidunt ante, in mollis turpis consectetur at. Praesent venenatis pulvinar lectus, at tincidunt nunc finibus non. Duis tortor lectus, elementum faucibus bibendum vitae, egestas bibendum ex. Maecenas vitae augue vitae dui condimentum imperdiet sit amet mattis quam. Duis eleifend scelerisque magna sed imperdiet. Mauris tempus rutrum metus, a ullamcorper erat fringilla a. Suspendisse potenti. Praesent et mi enim. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. </div> </div>
Troubles with CSS height in percentage
It's a bit difficult for me to explain my problem, so much better to just show an example (check the JSFiddle): #contacts { position: fixed; bottom: 0; width: 100%; max-height: 75%; } #contacts .tab-content { height: 100%; overflow: scroll; } JSFiddle no scroll As you see, there's a tab fixed on the bottom which toggles a panel (I'm using Bootstrap 3). The content of the panel is dynamically generated, so I need the panel to increase its height as the content is generated, up to a 75% of the page's height (not to cover it all). Now, when the content is too much, I need an inner scrollbar; as you can see, the scrollbar is there, but it's not working, because the #contacts div has no specific height, so the .tab-content's "height: 100%" is not working. If I try using "overflow: scroll" on #contacts instead of .tab-content, it works: JSFiddle scrolls label too But the problem, now, is that the scrollbar also scrolls the tab label, and that it's outside of the .tab-content, so when I click on it the div loses focus and the tab closes. Any idea how to solve this? Thanks!
Proof of Concept Solution I boiled down the design problem to the basics (without Bootstrap). The .fixed-wrapper is pinned to the bottom of the page using position: fixed, and apply overflow-y: scroll to enable scrolling. The .header tab element is also positioned fixed, but the trick is to set the bottom offset to the same value as the max-height value of .fixed-wrapper, 60% in this example. Then you toggle the content, you need to adjust the following: .fixed-wrapper { max-height: 0;} .header { bottom: 0;} .scroll-panel { display: none;} If you have an .active class to distinguish the display state, your CSS might look like: .fixed-wrapper.active { max-height: 60%;} .fixed-wrapper.active .header { bottom: 60%;} .fixed-wrapper.active .scroll-panel { display: bottom;} When applying this to a Bootstrap layout, make sure that your selectors are specific enough so that the Bootstrap classes do not override the key rules shown above. Note: There is a minor limitation to this solution. If the content is insufficiently tall to force scrolling, then the header element may hang at the 60% position even though the .scroll-panel does not reach the max-height. You may need some JavaScript to take care of that. body { margin: 0; } p { line-height: 2.0; } .fixed-wrapper { background-color: lightblue; max-height: 60%; position: fixed; bottom: 0; overflow-y: scroll; } .header { background-color: lightgray; position: fixed; bottom: 60%; right: 0; margin-right: 50px; width: auto; } .scroll-panel { background-color: lightblue; display: block; } <div class="fixed-wrapper"> <div class="header">header or tab...</div> <div class="scroll-panel"> <p>Some content...</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer facilisis velit ut neque tempor quis cursus tortor suscipit. Curabitur rutrum magna vitae arcu pharetra eget cursus ante accumsan. Nunc commodo malesuada adipiscing. Pellentesque consequat laoreet sagittis. Sed sit amet erat augue. Morbi consectetur, elit quis iaculis cursus, mauris nulla hendrerit augue, ut faucibus elit sapien vitae justo. In a ipsum malesuada nulla rutrum luctus. Donec a enim sapien. Sed ultrices ligula ac neque vulputate luctus. Suspendisse pretium pretium felis, in aliquet risus fringilla at. Nunc cursus sagittis commodo.</p> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer facilisis velit ut neque tempor quis cursus tortor suscipit. Curabitur rutrum magna vitae arcu pharetra eget cursus ante accumsan. Nunc commodo malesuada adipiscing. Pellentesque consequat laoreet sagittis. Sed sit amet erat augue. Morbi consectetur, elit quis iaculis cursus, mauris nulla hendrerit augue, ut faucibus elit sapien vitae justo. In a ipsum malesuada nulla rutrum luctus. Donec a enim sapien. Sed ultrices ligula ac neque vulputate luctus. Suspendisse pretium pretium felis, in aliquet risus fringilla at. Nunc cursus sagittis commodo.</p> </div> </div>
Ok so I looked at it again and it is indeed a pain, but this seems to work (a bit ugly though): Fiddle #contacts { position: fixed; bottom: 0; width: 100%; max-height: 75%; overflow-y: hidden; } #contacts .tab-content { background-color: #ccc; } .tab-pane { height:300px; overflow-y:scroll; } #contacts ul li { position: relative; float: right; margin-right: 15%; } #contacts > ul > li > a { background-color: #ccc; }
WordPress: Make sidebar match height of main content area
I'm taking an old WordPress site I designed years ago and now I'm making it responsive. Problem is I have a main content area on the site and a sidebar div and the issue is the sidebar div is not expanding down the entire height of the #contentWrap div on this site. I've already tried adding 100% heights to the #page, #contentWrap and #sidebar, all to no avail. On the old site design, I did a trick using background images, but that realistically won't work with a responsive desig.Any idea how I can make this work? Site in question: http://destinationbeershow.com/episode-guide/ Code: <div id="contentWrap"> <div id="content" class="narrowcolumn"> </div> <div id="sidebar"> </div> </div> CSS: #contentWrap { width: 856px; height: 100%; } #page { background-color: #ac4f23; text-align: left; margin: 0px auto; width: 856px; height: 100%; } .narrowcolumn { background-color: #ac4f23; float: left; padding: 0; margin: 0; width: 640px; color: #FFF; } #sidebar { padding: 16px 8px 10px 8px; float: right; width: 160px; height: 100%; font: 11px 'Lucida Grande', Verdana, Arial, Sans-Serif; border-left: 10px solid #fff; background-color: #ebd299; }
You can make everything collapse below your 856px hard width and use percentages inside that, or you can fiddle with the math. You also don't mention how you are doing your media queries, I'm assuming mobile first, which means that IE8 won't see the columns unless you learn more about that or use desktop first responsive design, however to make the columns the same height no matter what is inside either, here's one way (display:table/display:table-cell) which stacks below the 856px width you have on your #page. Use percentages. DEMO: http://jsbin.com/biyito/1/ CSS: .narrowcolumn { background-color: #ac4f23; color: #fff; box-sizing: border-box; padding: 10px 20px; } #sidebar { padding: 10px 20px; border-top: 10px solid #fff; background-color: #ebd299; box-sizing: border-box; } #media (min-width:856px) { #contentWrap { width: 100%; display: table; } .narrowcolumn { width: 80%; display: table-cell; } #sidebar { display: table-cell; padding: 10px; width: 20%; border-left: 10px solid #fff; border-top: 0px; } } HTML <div id="contentWrap"> <div id="content" class="narrowcolumn"> <h1>HTML Ipsum Presents</h1> <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.</p> </div> <div id="sidebar"> <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em> Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis.</p> </div> </div>
the #contentWrap has no height... i tried I really tried to make it responsive with your content but it just doesn't work. For now if you define the height of it, the bar will be end to end. In that page the height would be 1361px If you can place the content in http://jsfiddle.net/ is much more easy to find and get to the problem.
absolute positioning and scrollable DIV
I have this tricky CSS problem: I have this HTML: <div id="wrapper"> <div class="left"></div> <div id="scroll"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque faucibus volutpat turpis at iaculis. Proin at nisl leo. Morbi nec blandit leo? Pellentesque interdum nunc sed nisl rhoncus gravida. Nunc sollicitudin, mi sit amet porta mollis, metus erat ornare odio, eu accumsan mauris diam nec augue. Ut tincidunt dui at lorem consequat vitae consectetur sapien pharetra. Suspendisse potenti. Donec turpis enim, varius accumsan congue vitae, rhoncus ut justo. Curabitur tristique lobortis eros ut pharetra. Maecenas non condimentum justo. Integer tincidunt; velit quis auctor varius, magna lorem pharetra urna, eget pellentesque leo nibh at mi. Ut pretium bibendum dui vel venenatis. Proin vel sem vitae lacus tincidunt bibendum. Pellentesque blandit mauris sit amet mauris sollicitudin pretium. In molestie condimentum nisi placerat consequat. </div> <div class="right"></div> </div> With this CSS: #wrapper { position: relative; display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; height: 47px; } #scroll { position: relative; height: 100%; width: 10000px; } div.left, div.right { position: absolute; display: block; background-color: rgba(255, 0, 0, 0.5); width: 24px; height: 100%; z-index: 100; top: 0; } div.left { left: 0; } div.right { right: 0; } And the visual result is this: For some reason, the div.right is moving when I scroll the #scroll. I want it to always float at the boundary of #wrapper. This is what I get right now: Here is the jsfiddle: http://jsfiddle.net/b5fYH/ Thank you Edit Just because it wasn't obvious, it must work on mobile devices.
You have to know the difference between position: absolute and position: fixed. The first one means: place the element in absolute position within relative element and keep in in that place (relatively). The second: place the element in absolute position within window (frame) and keep it there no matter what happens. Check this fiddle: http://jsfiddle.net/b5fYH/1/
The problem is with how overflow-x changes the wrapper div width. The solution I found was: Demo: http://jsfiddle.net/5jWpG/ wrapping the whole thing with a new div with the id wrapper-container then adding the following CSS code: #wrapper-container { position: relative; } #wrapper { position: static; /* or remove position relative from your code */ } div.left, div.right { bottom: 16px; height: auto; /* or remove height: 100% from your code */ }
Transparent and expandable wrapper div, how?
I made an image to easier explain what Im after: Image Illustration http://bayimg.com/image/eabahaaci.jpg Ive read some other questions on the subject but Im not sure the solutions will work for me because my div needs to be expandable and grow as more content is added. Does anyone know how to accomplish this in a simple way?
#body {background: transparent url(background/image.png) 0 0 repeat-y; } #content-wrap {width: 60%; margin: 0 auto; background: transparent url(partially/transparent/60percent-opaque.png) 0 0 repeat; } #main-content {width: 90%; margin: 1em auto 0 auto; background-color: #fff; } #footer {width: 90%; margin: 1em auto 0 auto; background-color: #fff; } This sets a partially-transparent .png image as the background for the #content-wrap section, with a solid color background for the divs (I've used #main-content and #footer, but they've got the same style so you could just use #content-wrap div and shorten the css a little. <div id="content-wrap"> <!-- this is the outer wrapping div --> <div id="main-content"> <!-- this I'm assuming is the main content portion --> </div> <div id="footer"> <!-- the name explains my assumption, I think... --> </div> </div> body { background: #fff url(http://i.stack.imgur.com/9uIxu.png) 0 0 repeat; } #content-wrap { width: 60%; margin: 1em auto; padding: 1em 0; background-color: rgba(0, 0, 0, 0.3); -moz-border-radius: 1em; -webkit-border-radius: 1em; } #content-wrap div { width: 90%; margin: 1em auto; background-color: #fff; } #content-wrap div p { margin: 1em 0; } <div id="content-wrap"> <div id="main-content"> <p>I presume the main content will sit here...</p> <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim.</p> <p>Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras dapibus. Vivamus elementum semper nisi. Aenean vulputate eleifend tellus.</p> <p>Aenean leo ligula, porttitor eu, consequat vitae, eleifend ac, enim. Aliquam lorem ante, dapibus in, viverra quis, feugiat a, tellus. Phasellus viverra nulla ut metus varius laoreet. Quisque rutrum. Aenean imperdiet. Etiam ultricies nisi vel augue. Curabitur ullamcorper ultricies nisi.</p> <p>Nam eget dui. Etiam rhoncus. Maecenas tempus, tellus eget condimentum rhoncus, sem quam semper libero, sit amet adipiscing sem neque sed ipsum. Nam quam nunc, blandit vel, luctus pulvinar, hendrerit id, lorem. Maecenas nec odio et ante tincidunt tempus. Donec vitae sapien ut libero venenatis faucibus. Nullam quis ante. Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed fringilla mauris sit amet nibh. Donec sodales sagittis magna. Sed consequat, leo eget bibendum sodales, augue velit cursus nunc,</p> </div> <div id="footer"> <p>This'd be the footer. And so on...</p> </div> </div> ...if you know that your audience will be using FF3.x (and probably webkit based browsers), you could use background-color: rgba(0,0,0, 0.6); to define the background-colour (red=0, green=0, blue=0, alpha=0.4 or 40% opaque (or 60% transparent) -the values being between 0 (entirely transparent) and 1 (entirely opaque).) Using the rgba for colour prevents problems from using opacity to make the parent div transparent, while trying to make the children visible. But it's got limited use because of browser adoption, of course... A working demo is over at my site: http://www.davidrhysthomas.co.uk/so/transparent.html
You will need an 1px high image slice for the transperncy and one for the rounded corders at the bottom .background{ background:url(/image/path); } .wrapper{ background:url(/image/path/trans.png) repeat-y; width:500px; position:relative; } .wrapper .bottom{ background:url(path/to/image) no-repeat; position:absolute; bottom:0; left:0; height:20px; } .inner{ background:#fff; margin:10px; } I have made the widths and margins up. You should put in the right sizes yourself