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>
Related
Is it possible to limit a text length to "n" lines using CSS (or cut it when overflows vertically).
text-overflow: ellipsis; only works for 1 line text.
original text:
Ultrices natoque mus mattis, aliquam, cras in pellentesque
tincidunt elit purus lectus, vel ut aliquet, elementum nunc
nunc rhoncus placerat urna! Sit est sed! Ut penatibus turpis
mus tincidunt! Dapibus sed aenean, magna sagittis, lorem velit
wanted output (2 lines):
Ultrices natoque mus mattis, aliquam, cras in pellentesque
tincidunt elit purus lectus, vel ut aliquet, elementum...
There's a way to do it using unofficial line-clamp syntax, and starting with Firefox 68 it works in all major browsers.
body {
margin: 20px;
}
.text {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2; /* number of lines to show */
line-clamp: 2;
-webkit-box-orient: vertical;
}
<div class="text">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam consectetur venenatis blandit. Praesent vehicula, libero non pretium vulputate, lacus arcu facilisis lectus, sed feugiat tellus nulla eu dolor. Nulla porta bibendum lectus quis euismod. Aliquam volutpat ultricies porttitor. Cras risus nisi, accumsan vel cursus ut, sollicitudin vitae dolor. Fusce scelerisque eleifend lectus in bibendum. Suspendisse lacinia egestas felis a volutpat.
</div>
Unless you care about IE users, there is no need to do line-height and max-height fallbacks.
What you can do is the following:
.max-lines {
display: block;/* or inline-block */
text-overflow: ellipsis;
word-wrap: break-word;
overflow: hidden;
max-height: 3.6em;
line-height: 1.8em;
}
<p class="max-lines">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vitae leo dapibus, accumsan lorem eleifend, pharetra quam. Quisque vestibulum commodo justo, eleifend mollis enim blandit eu. Aenean hendrerit nisl et elit maximus finibus. Suspendisse scelerisque consectetur nisl mollis scelerisque.</p>
where max-height: = line-height: × <number-of-lines> in em.
Working Cross-browser Solution
This problem has been plaguing us all for years.
To help in all cases, I have laid out the CSS only approach, and a jQuery approach in case the css caveats are a problem.
Here's a CSS only solution I came up with that works in all circumstances, with a few minor caveats.
The basics are simple, it hides the overflow of the span, and sets the max height based on the line height as suggested by Eugene Xa.
Then there is a pseudo class after the containing div that places the ellipsis nicely.
Caveats
This solution will always place the ellipsis, regardless if there is need for it.
If the last line ends with an ending sentence, you will end up with four dots....
You will need to be happy with justified text alignment.
The ellipsis will be to the right of the text, which can look sloppy.
Code + Snippet
jsfiddle
.text {
position: relative;
font-size: 14px;
color: black;
width: 250px; /* Could be anything you like. */
}
.text-concat {
position: relative;
display: inline-block;
word-wrap: break-word;
overflow: hidden;
max-height: 3.6em; /* (Number of lines you want visible) * (line-height) */
line-height: 1.2em;
text-align:justify;
}
.text.ellipsis::after {
content: "...";
position: absolute;
right: -12px;
bottom: 4px;
}
/* Right and bottom for the psudo class are px based on various factors, font-size etc... Tweak for your own needs. */
<div class="text ellipsis">
<span class="text-concat">
Lorem ipsum dolor sit amet, nibh eleifend cu his, porro fugit mandamus no mea. Sit tale facete voluptatum ea, ad sumo altera scripta per, eius ullum feugait id duo. At nominavi pericula persecuti ius, sea at sonet tincidunt, cu posse facilisis eos. Aliquid philosophia contentiones id eos, per cu atqui option disputationi, no vis nobis vidisse. Eu has mentitum conclusionemque, primis deterruisset est in.
Virtute feugait ei vim. Commune honestatis accommodare pri ex. Ut est civibus accusam, pro principes conceptam ei, et duo case veniam. Partiendo concludaturque at duo. Ei eirmod verear consequuntur pri. Esse malis facilisis ex vix, cu hinc suavitate scriptorem pri.
</span>
</div>
jQuery Approach
In my opinion this is the best solution, but not everyone can use JS.
Basically, the jQuery will check any .text element, and if there are more chars than the preset max var, it will cut the rest off and add an ellipsis.
There are no caveats to this approach, however this code example is meant only to demonstrate the basic idea - I wouldn't use this in production without improving on it for a two reasons:
1) It will rewrite the inner html of .text elems. whether needed or not.
2) It does no test to check that the inner html has no nested elems - so you are relying a lot on the author to use the .text correctly.
Edited
Thanks for the catch #markzzz
Code & Snippet
jsfiddle
setTimeout(function()
{
var max = 200;
var tot, str;
$('.text').each(function() {
str = String($(this).html());
tot = str.length;
str = (tot <= max)
? str
: str.substring(0,(max + 1))+"...";
$(this).html(str);
});
},500); // Delayed for example only.
.text {
position: relative;
font-size: 14px;
color: black;
font-family: sans-serif;
width: 250px; /* Could be anything you like. */
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="text">
Old men tend to forget what thought was like in their youth; they forget the quickness of the mental jump, the daring of the youthful intuition, the agility of the fresh insight. They become accustomed to the more plodding varieties of reason, and because this is more than made up by the accumulation of experience, old men think themselves wiser than the young.
</p>
<p class="text">
Old men tend to forget what thought was like in their youth;
</p>
<!-- Working Cross-browser Solution
This is a jQuery approach to limiting a body of text to n words, and end with an ellipsis -->
As far as I can see, this would be possible only using height: (some em value); overflow: hidden and even then it wouldn't have the fancy ... at the end.
If that is not an option, I think it's impossible without some server side pre-processing (difficult because text flow is impossible to predict reliably) or jQuery (possible but probably complicated).
The following CSS class restricts text to two lines, and inserts an ellipsis to indicate overflowing text.
.two-line-ellipsis {
overflow: hidden;
width: 325px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
The solution from this thread is to use the jquery plugin dotdotdot. Not a CSS solution, but it gives you a lot of options for "read more" links, dynamic resizing etc.
This works for me:
div {
width: 200px;
}
p {
display: block; /* Fallback for non-webkit */
display: -webkit-box;
height: 2.6em; /* Fallback for non-webkit, line-height * 2 */
line-height: 1.3em;
-webkit-line-clamp: 2; /* if you change this, make sure to change the fallback line-height and height */
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
<div>
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
</p>
<div>
For the react guys using inline styles:
<p
style={{
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
lineClamp: 2,
WebkitLineClamp: 2,
WebkitBoxOrient: 'vertical',
}}
>Some Text</p>
.class{
word-break: break-word;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
line-height: 16px; /* fallback */
max-height: 32px; /* fallback */
-webkit-line-clamp: 2; /* number of lines to show */
-webkit-box-orient: vertical;
}
Currently you can't, but in future you will be able to use text-overflow:ellipis-lastline. Currently it's available with vendor prefix in
Opera 10.60+: example
I have a solution which works well but instead an ellipsis it uses a gradient. It works when you have dynamic text so you don't know if it will be long enough to need an ellipse. The advantages are that you don't have to do any JavaScript calculations and it works for variable width containers including table cells and is cross-browser. It uses a couple of extra divs, but it's very easy to implement.
Markup:
<td>
<div class="fade-container" title="content goes here">
content goes here
<div class="fade">
</div>
</td>
CSS:
.fade-container { /*two lines*/
overflow: hidden;
position: relative;
line-height: 18px;
/* height must be a multiple of line-height for how many rows you want to show (height = line-height x rows) */
height: 36px;
-ms-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
word-wrap: break-word;
}
.fade {
position: absolute;
top: 50%;/* only cover the last line. If this wrapped to 3 lines it would be 33% or the height of one line */
right: 0;
bottom: 0;
width: 26px;
background: linear-gradient(to right, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%);
}
blog post: http://salzerdesign.com/blog/?p=453
example page: http://salzerdesign.com/test/fade.html
As of (almost) 2023, some older css rules are no longer needed.
These show the minimum required, and work cross browser despite the prefixed syntax:
.line-clamp { overflow:hidden; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:1; }
.line-clamp-2 { overflow:hidden; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:2; }
.line-clamp-3 { overflow:hidden; display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; }
I really like line-clamp, but no support for firefox yet.. so i go with a math calc and just hide the overflow
.body-content.body-overflow-hidden h5 {
max-height: 62px;/* font-size * line-height * lines-to-show(4 in this case) 63px if you go with jquery */
overflow: hidden;
}
.body-content h5 {
font-size: 14px; /* need to know this*/
line-height:1,1; /*and this*/
}
now lets say you want to remove and add this class via jQuery with a link, you will need to have an extra pixel so the max-height it will be 63 px, this is because you need to check every time if the height greather than 62px, but in the case of 4 lines you will get a false true, so an extra pixel will fix this and it will no create any extra problems
i will paste a coffeescript for this just to be an example, uses a couple of links that are hidden by default, with classes read-more and read-less, it will remove the ones that the overflow is not need it and remove the body-overflow classes
jQuery ->
$('.read-more').each ->
if $(this).parent().find("h5").height() < 63
$(this).parent().removeClass("body-overflow-hidden").find(".read-less").remove()
$(this).remove()
else
$(this).show()
$('.read-more').click (event) ->
event.preventDefault()
$(this).parent().removeClass("body-overflow-hidden")
$(this).hide()
$(this).parent().find('.read-less').show()
$('.read-less').click (event) ->
event.preventDefault()
$(this).parent().addClass("body-overflow-hidden")
$(this).hide()
$(this).parent().find('.read-more').show()
If you want to focus on each letter you can do like that, I refer to this question
function truncate(source, size) {
return source.length > size ? source.slice(0, size - 1) + "…" : source;
}
var text = truncate('Truncate text to fit in 3 lines', 14);
console.log(text);
If you want to focus on each word you can do like that + space
const truncate = (title, limit = 14) => { // 14 IS DEFAULT ARGUMENT
const newTitle = [];
if (title.length > limit) {
title.split(' ').reduce((acc, cur) => {
if (acc + cur.length <= limit) {
newTitle.push(cur);
}
return acc + cur.length;
}, 0);
return newTitle.join(' ') + '...'
}
return title;
}
var text = truncate('Truncate text to fit in 3 lines', 14);
console.log(text);
If you want to focus on each word you can do like that + without space
const truncate = (title, limit = 14) => { // 14 IS DEFAULT ARGUMENT
const newTitle = [];
if (title.length > limit) {
Array.prototype.slice.call(title).reduce((acc, cur) => {
if (acc + cur.length <= limit) {
newTitle.push(cur);
}
return acc + cur.length;
}, 0);
return newTitle.join('') + '...'
}
return title;
}
var text = truncate('Truncate text to fit in 3 lines', 14);
console.log(text);
.word-limit{
display: block;
text-overflow: ellipsis;
white-space: nowrap;
word-wrap: break-word;
overflow: hidden;
}
Basic Example Code, learning to code is easy. Check Style CSS comments.
table tr {
display: flex;
}
table tr td {
/* start */
display: inline-block; /* <- Prevent <tr> in a display css */
text-overflow: ellipsis;
white-space: nowrap;
/* end */
padding: 10px;
width: 150px; /* Space size limit */
border: 1px solid black;
overflow: hidden;
}
<table>
<tbody>
<tr>
<td>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla egestas erat ut luctus posuere. Praesent et commodo eros. Vestibulum eu nisl vel dui ultrices ultricies vel in tellus.
</td>
<td>
Praesent vitae tempus nulla. Donec vel porta velit. Fusce mattis enim ex. Mauris eu malesuada ante. Aenean id aliquet leo, nec ultricies tortor. Curabitur non mollis elit. Morbi euismod ante sit amet iaculis pharetra. Mauris id ultricies urna. Cras ut
nisi dolor. Curabitur tellus erat, condimentum ac enim non, varius tempor nisi. Donec dapibus justo odio, sed consequat eros feugiat feugiat.
</td>
<td>
Pellentesque mattis consequat ipsum sed sagittis. Pellentesque consectetur vestibulum odio, aliquet auctor ex elementum sed. Suspendisse porta massa nisl, quis molestie libero auctor varius. Ut erat nibh, fringilla sed ligula ut, iaculis interdum sapien.
Ut dictum massa mi, sit amet interdum mi bibendum nec.
</td>
</tr>
<tr>
<td>
Sed viverra massa laoreet urna dictum, et fringilla dui molestie. Duis porta, ligula ut venenatis pretium, sapien tellus blandit felis, non lobortis orci erat sed justo. Vivamus hendrerit, quam at iaculis vehicula, nibh nisi fermentum augue, at sagittis
nibh dui et erat.
</td>
<td>
Nullam mollis nulla justo, nec tincidunt urna suscipit non. Donec malesuada dolor non dolor interdum, id ultrices neque egestas. Integer ac ante sed magna gravida dapibus sit amet eu diam. Etiam dignissim est sit amet libero dapibus, in consequat est
aliquet.
</td>
<td>
Vestibulum mollis, dui eu eleifend tincidunt, erat eros tempor nibh, non finibus quam ante nec felis. Fusce egestas, orci in volutpat imperdiet, risus velit convallis sapien, sodales lobortis risus lectus id leo. Nunc vel diam vel nunc congue finibus.
Vestibulum turpis tortor, pharetra sed ipsum eu, tincidunt imperdiet lorem. Donec rutrum purus at tincidunt sagittis. Quisque nec hendrerit justo.
</td>
</tr>
</tbody>
</table>
I've been looking around for this, but then I realize, damn my website uses php!!!
Why not use the trim function on the text input and play with the max length....
Here is a possible solution too for those using php:
http://ideone.com/PsTaI
<?php
$s = "In the beginning there was a tree.";
$max_length = 10;
if (strlen($s) > $max_length)
{
$offset = ($max_length - 3) - strlen($s);
$s = substr($s, 0, strrpos($s, ' ', $offset)) . '...';
}
echo $s;
?>
¡Hello! I've looking for some questions like this, but i only found this one, and its solution is useless for me.
I have a website where some books are shown, it is edicionesparalelo.com, and another one where people can buy those books: tienda.edicionesparalelo.com I'd want to put a button under each book image which says "Ir a la tienda" (Go to the store), but i don't know how can i align the button under the image and keep the text like it is now. I've tried floating and positioning but no way.
An example of the book pages in this link. What i want is to put a button under the image.
I strangely feel that this will be duplicated, but i sware i searched the web for a whole hour.
Could you help me? Thanks!
Here is one way of creating the layout that you need. Create two block level elements, one to hold the image and the button and the other to hold the content (header and text).
Float the .thumb-panel to the left and keep the .text-panel as a regular inflow element.
Adjust margins, borders and padding as needed.
.content-panel{
overflow: auto; /* keep the float contained within this panel */
border: 1px dotted blue;
}
.thumb-panel {
float: left;
width: 100px;
border: 1px solid gray;
text-align: center;
margin-right: 20px; /* for example */
}
.thumb-panel img {
display: inline-block;
margin-bottom: 20px; /* for example */
}
.thumb-panel button{
display: inline-block;
margin-bottom: 20px;
}
.text-panel {
overflow: auto; /* prevents text flow wrapping around floated panel */
border: 1px solid gray;
}
<div class="content-panel">
<div class="thumb-panel">
<img src="http://placehold.it/80x120">
<button>Button</button>
</div>
<div class="text-panel">
<h1>Lorem Ipsum</h1>
<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>
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;
}
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>
I have a fixed div with 100% height, and within that, a child-div that's relatively positioned. The child-div holds text that can be changed, so it doesn't have a fixed height.
I want the child-div to scroll vertically if its content overflows out of the screen. I played around with the min and max height properties to achieve this, but it isn't an ideal solution, and doesn't always work.
EDIT: min and max height seemed to be ignored, almost. I calculated how much vertical area the textBox would take up for the minimum 'allowable' screen height, and set that as the height. Adding min and max height made no difference to this. The only problem with this solution is that the box is always around ~60%, so even when it doesn't need to scroll, it does. This works, but isn't ideal. If there's a way to get around this it would be great.
This is what I have so far:
<div class="content">
<div id="textbox"> some text
</div>
</div>
.content { position: fixed; height: 100%; top: 0px; right: 0px; }
#textBox {
position: relative;
top: 165px;
height: 61.5%;
overflow-y: auto;
}
Is there a better, more fool-proof way for doing this?
The following worked perfectly for me:
<style type="text/css">
#fixed {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
border: 1px solid black;
overflow: hidden;
background: white;
}
#scrolling {
overflow: auto;
max-height: 98%;
}
</style>
<div id="fixed">
<div contenteditable id="scrolling">
<p>Pellentesque habitant morbi tristique 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. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien
ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, 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. Praesent dapibus, neque id cursus faucibus, tortor neque egestas
augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor,
facilisis luctus, metus</p>
</div>
</div>
The div's content is editable, so just add text until it scrolls. It would work on decent browser.
Live Example
Basically You have to set the overflow of your fixed element as you can see in this example, and there's a jsfiddle to play with the possibilities.
I have found a solution by testing and it seems to work. It requires 3 DIVs. First and uppermost div will be your fixed element. It will contain another div as its child, which will be positioned relatively. It will another div and this div will contain your content, it has to be positioned absolutely
Code: https://codepen.io/ltorvalds024/pen/GxKdeO