CSS3 flexbox layout with ellipsis doesn't work on mobile Safari - css

The following demo (submitted as an SO answer) illustrates usage of ellipsis with flexbox layout. However, it doesn't seem to work on mobile Safari - the text is not shortened at all (tested on iPhone 5, iPhone X and iOS 11.4 emulator in XCode). It works on all desktop browsers including Safari.
http://jsfiddle.net/Blender/kXMz7/1/
.parent-div {
display: -webkit-flex;
display: -moz-flex;
display: flex;
}
.text-div {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.icon-div {
-webkit-flex: 1;
-moz-flex: 1;
flex: 1;
}
<div class="parent-div">
<div class="icon-div">X</div>
<div class="text-div">This is text I'd like to truncate when space doesn't permit</div>
</div>
Is this a known problem?

https://www.w3schools.com/css/tryit.asp?filename=trycss3_text-overflow, sets width to truncate the characters when the given width isn't enough.
Although while using flex, setting 'width' is not recommended. I just added flex-basis: 40%; in 'text-div' class and I could see the truncation happening.

Related

Display flex not getting 100% height in firefox [duplicate]

This question already has answers here:
Percentage Height HTML 5/CSS
(7 answers)
Closed 3 years ago.
I am trying to display a div instead of element in fullcalendar using html and css via jquery as follows:
$(element).css("display", "none");
$('.fc-day[data-date="' + event.start.format("YYYY-MM-DD") + '"]').append("<div class='booked'><span>Booked <br><small>for date</small></span></div>");
And css
.booked{
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
background-color: #CD5C5C;
cursor: not-allowed;
pointer-events: none;
color: #fff;
}
Although, its working fine as intended on chrome but not on other browsers such as firefox.
Chrome:
Firefox
Update:
If I inspect each container:
In chrome
<td class="fc-day fc-widget-content fc-sun fc-future" data-date="2019-06-23">
<div class="booked"><span>Booked <br><small>for date</small></span></div>
</td>
But in case of firefox, its not showing inner element i.e div .booked
CODEPEN LINK
You can check this link its showing my problem, you can check in chrome and firefox.
CODEPEN LINK
What you mising is, you forget making the td height 100% too. So you need add css for the td. In my opinion, try to add this css
.fc-bg td {
height: 100%;
}
and it will work.
Already trying on the pen, and it's working. CodePen

Make the code-mirror block fill the rest of the page in Safari

I want to make a page that satisfies the following conditions:
it contains some texts in the first part and a
code-mirror in the second part
the texts in the first part are almost fixed (so their height is almost fixed), and I want the height of the code-mirror to fill exactly the rest of the page. If there are many texts in the code-mirror, then use scroll.
Then, I make this plunker:
<style>
.rb {
display: flex;
flex-direction: column;
height: 100%;
}
.rb .CodeMirror {
flex: 1;
}
</style>
<div class="rb">
1<br/>2<br/>3<br/>4<br/>
<textarea ng-model="body" ui-codemirror="option"></textarea>
</div>
It works perfectly in Chrome, it however does not work in Safari: the height of the code-mirror is incorrect; we see immediately the problem:
Does anyone know how to fix this? I used to have a solution with calc(minus a fixed px), but I cannot find it anymore.
Why don't you use height: 100% instead of flex: 1?
.rb .CodeMirror {
height: 100%;
}
Update:
For the sake of future users, the above didn't work, but with calc it did for both Safari and Chrome, so:
.rb .CodeMirror {
calc(100% - 80px); /* notice the spaces around "-" */
}
where 80px is the height of the "first part" as described in the original post.
Plunker
It would like to give question a try.
You may want to use em instead of vh.
1em = approx 16px
Also from what I read from w3schools: https://www.w3schools.com/cssref/css3_pr_flex.asp
You will need to also import the browser property. I am guessing the correction should be:
<style>
// just in case you didn't
<!--
html,body{
height: 100%; // or 100vh
}
-->
.rb {
display: -webkit-flex; // for Safari
display: flex;
-webkit-flex-direction: column;
flex-direction: column;
// remove this height: 100%;
// otherwise should set 100vh to height
}
.rb .CodeMirror {
// You may want to try auto instead of 1.
// As the size of the chrome for each browser is different.
-webkit-flex: 1; // for Safari
-ms-flex: 1; // for IE
flex: 1;
}
</style>
<div class="rb">
1<br/>2<br/>3<br/>4<br/>
<textarea ng-model="body" ui-codemirror="option"></textarea>
</div>
Please let me know if it works or not. thanks!

Table cell width declaration is ignored

I have an horizontal menu bar that can have from 1 to 4 links.
I would like that that each link will have a width of 25% not depending by number of them (so in case of only 3 links, menu bar should be only 75% of another one with 4 links).
Using floats reach the target but in case of longer text spanned across 2 rows, is not possible to adjust other links' height accordingly, so I use display:table-cell that solve this issue, but in case of 3 links, completely ignore width:25% and it renders like if width would be 33%.
<div class="container">
<div class="block">
Link 1
</div>
<div class="block">
Link 2
</div>
<div class="block">
<a href="#">
Link 3 with very long text tha span across 2 rows
</a>
</div>
</div>
.container {
display: table;
width: 100%;
border:solid 1px blue;
}
.block {
border: 1px solid red;
display: table-cell;
width: 25%;
}
Please, look at this jsFiddle in order to see both cases.
Desired result is that second menubar links continue to have the same width of first one, not becoming 33%.
I tried also to add table-layout:fixed as read in other threads but was unuseful
How to solve this?
When you ask a browser to display a three-column table so that the width of each column is 25% of the total width, you are making a logically impossible request. You cannot have the width of a table to be 75% of itself. Browsers then tend to divide the space evenly to the columns.
A simple fix is to remove width: 100% from the rule for .container and to set width: 75% on the second “table” (div element formatted as a table).
How about using flexbox?
.container {
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
border:solid 1px blue;
}
.block {
border: 1px solid red;
max-width: 25%;
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
-moz-box-flex: 1; /* OLD - Firefox 19- */
-webkit-flex: 1; /* Chrome */
-ms-flex: 1; /* IE 10 */
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
a{
display: block;
padding: 10px;
}
In this way you can easily adjust your .block element's height accordingly...
here's a fiddle with my solution: http://jsfiddle.net/o462q4ce/
Please check this.
var n = $(".container .block").length;
var w = (100/n);
$(".container .block").width(w+'%');
See jsFiddle. Hope it helps.
Using a combination of :last-child and :nth-child() selector you can target exactly the div.block you need to modify.
Unfortunately using table layout doesn't allow you to manage margin and width as I wish...
anyway here is a solution could fit for your needs
.block:last-child:nth-child(3) {width:auto; padding-right:25%;}
.block:last-child:nth-child(2) {width:auto; padding-right:50%;}
.block:last-child:nth-child(1) {width:auto; padding-right:75%;}
in this jsFiddle you can see these selectors in action: http://jsfiddle.net/5t0fq1sy/

Using box model to contain items within its parent div

Using the following HTML and CSS3 rules, I'm trying to make sure that the following criteria are adhered to:
I have all of the criteria working except for item 1 where the
children are exceeding their parent's width. Question: How to keep children within their parent?
li items cannot exceed their parent width i.e. 400px
img, label, and currency content must be centred vertically within their span
currency should not wrap and should always be displayed in full
currency should always be displayed as close as possible to the
label span.
the label text should be clamped at 2 lines with ellipsis displayed where it exceeds 2 lines.
Note: Only needs to work in Chrome and Safari webkit-based browsers.
It should look like:
However, it looks like this at the moment:
Any ideas?
********************* JS Fiddle example ************************
<ul>
<li>
<span class="img"></span>
<span class="label">Acclaim</span>
<span class="currency">(USD 50)</span>
</li>
<li>
<span class="img"></span>
<span class="label">Acclaim 1 11 111 1111 11111</span>
<span class="currency">(USD 50)</span>
</li>
<li>
<span class="img"></span>
<span class="label">Acclaim 1 11 111 1111 11111 2 22222 2222 22222 3 33 333 3333 33333 4 44 444 4444 44444 5 55 555 5555 55555 6 66 666 6666 66666</span>
<span class="currency">(USD 50)</span>
</li>
</ul>
ul {
width: 400px;
background-color: yellow;
padding: 0;
margin: 0;
}
li {
display: -webkit-box;
padding-right: 50px;
}
.label {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
overflow: hidden;
white-space: normal;
word-wrap: break-word;
line-height: 1.3em;
margin-right: 0.2em;
background-color: pink;
}
.currency {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-box-pack: center;
white-space: nowrap;
background-color: lightgreen;
}
.img {
display: block;
width: 40px;
height: 40px;
margin-right: 0.1em;
background-image:url('data:image/png;base64,iVBOR...);
}
The following will work, providing the price doesn't get wider:
http://jsfiddle.net/WDjZ3/4/
I simply converted the margin-right to pixels so I knew the space taken up by the content other than the label, then added a max-width for the remainder:
.label {
margin-right: 3px;
max-width: 294px;
}
if the price or image are variable width, you will need js to read their widths, remove from 400px and add that value to max-width.
Here is an example using JavaScript to dynamically set the max-width: http://jsfiddle.net/WDjZ3/7/
I haven't checked all dimensions, so that should be added to make it fully accurate, otherwise the margins will make the price no longer fit.
I basically checked the width of the other elements:
function getWidth(el) {
return parseInt(window.getComputedStyle(el,null).getPropertyValue("width"));
}
I then removed this width from 400px, and set the maxWidth:
for (var i=0; i<imgs.length; i++) {
var width = 400 - (getWidth(imgs[i]) + getWidth(currencies[i])) + "px";
labels[i].style.maxWidth = width;
}
I’ve solved this to work without JavaScript. However, it only works in more modern browsers, including Chrome and Opera. It will not work in Safari. It will work in Firefox once it updates to the latest spec. I can probably get it to work in IE10, but I have to look into that more. The ellipsis only works in Chrome/Safari as it is vendor specific.
The demo is at http://jsfiddle.net/uLm92/1/
First of all we want to make the li as a flexbox container and set it to 400px, so the flex items will try to fit that size (more on that later):
li {
/* make all items inside li as flex items */
display: -webkit-flex;
display: flex;
height: 40px;
max-width: 400px;
}
Now the child items are flex items, the key to getting the label to fit is setting the image and the price to not flex. For the price, we know it wants to always be 40xp wide, so I set the following:
.img {
width: 40px;
height: 40px;
-webkit-flex-basis: 40px;
flex-basis: 40px;
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
This says that the preferred with id 40px and never make it smaller.
Then we want to also tell the price to never shrink, and to also centre the anonymous box (the content):
.currency {
/* make anonymous box vertically centred */
display: -webkit-flex;
display: flex;
-webkit-align-items: center;
align-items: center;
/* make sure it never shrinks */
-webkit-flex-shrink: 0;
flex-shrink: 0;
}
Lastly, we want to also center the label text. As you need the ellipsis hack, I've used the old Flexbox syntax for WebKit. Without using old flexbox, the line-clamp property does not work:
.label {
/* need to use old flexbox for line-clamp to work
it is a *horrible hack* */
display: -webkit-box;
display: flex;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow : hidden;
text-overflow: ellipsis;
-webkit-box-pack: center;
align-items: center;
}
As the other two items will never shrink, the .label element is the only one that can, so it reduces in size if there is no space left.

display: table-cell centering with two elements, rather than three

I have a working example of vertically centering elements of unknown height, using three elements:
<section>
<div>
<img src="http://placehold.it/100x100"/>
</div>
</section>​
And the CSS:
section {
display: table;
width: 100%;
height: 100%;
position: absolute;
text-align: center;
}
div {
display: table-cell;
vertical-align: middle;
}
There's also a JSFiddle example here: http://jsfiddle.net/Y6KS9/
However I'd like to avoid using unnecessary wrappers if possible. Eg, having the img itself display as table-cell:
div {
display: table;
width: 100%;
height: 100%;
position: absolute;
text-align: center;
}
img {
display: table-cell;
vertical-align: middle;
}
​
However this doesn't work - see the JSFiddle example at http://jsfiddle.net/U2c9R/ - the img is not centered within the div.
Is it possible to vertically center an image of unknown size within its parent using only two elements?
Edit: I'm aware of Flexbox, and intending to throw out the table cell hack completely once IE9 dies. But right now I need to support old browsers.
You could try to use the CSS3 Flexible Box Model.
You should check the browser availability. As you can see by the -webkit vendor prefix my Example currently works only in -webkit-based render engines. But i'm pretty sure it'll work in most modern browsers.
Here is an overview of browsers which supporting the Flexible Box Model: http://caniuse.com/#feat=flexbox
div {
display: -webkit-box;
-webkit-box-pack: center;
-webkit-box-align: center;
height:100%;
width:100%;
position:absolute;
}
Example: http://jsfiddle.net/U2c9R/4/
Update
For Cross-browser support for the CSS3 Flexible Box Model you could use Modernizr and a proper Polyfill which adds support for IE 6-9 and Opera 10.0+. The only hint is, this wouldn't work without JavaScript. But maybe this is an option?

Resources