Font scaling based on width of container with js libs - css

I'm trying to implement font-size scaling based on width of container (I want my long h1 to be in one line).
Here is my HTML with bootstrap 3:
<div class="someclass">
<div class="container">
<div class="row">
<div class="col-md-12">
<h1 class="responsive-headline">LONG TEXT IS
LOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOONG</h1>
<ul class="breadcrumbs">
...
</ul>
</div>
</div>
</div>
</div>
CSS styles:
.responsive-headline {
margin: 0px 0px 3px;
color: #fff;
text-transform: uppercase;
font-size: 32px;
letter-spacing: 1.7px;
line-height: 1.4;
}
Ok. Let's start from FitText.js library:
jQuery(document).ready(function($) {
$('.responsive-headline').fitText();
});
Result font-size: 114px;! What?
Add some parameters:
$('h1.responsive-headline').fitText(1.2, { minFontSize: '18px',
maxFontSize: '32px' });
Result font-size: 32px;. Better but not what I want, I need smaller font-size. Also tried to add width: 1000px; display: block; white-space: nowrap; to h1 without success.
Second library that I tried is FlowType.js. Add some code:
jQuery(document).ready(function($) {
$('h1.responsive-headline').flowtype();
});
Result font-size: 32.5714px;. Little bigger than default.
And with parameters:
$('h1.responsive-headline').flowtype({
minFont : 12,
maxFont : 32
});
Result font-size: 32px;.
Why my h1 becomes bigger but not smaller?

Might it be because you are calculating the font-size on (document).ready?
If you're looking for a more dynamic sizing "responsive", maybe try the resize() method?
https://api.jquery.com/resize/
My appologies if im misunderstanding.

Related

Scale font to size when text exceeds container?

I want font size to be 54px if the text fits inside the container, otherwise it should be 36px.
I was considering whether I can achieve this with a pure CSS solution, using the scale function to collapse to either of the two. If the container can be assumed to be full with, I guess I could use vw as a base for a calculation?
But I am very much stuck on this. Could anyone give me a hint, as to how I can achieve this or something close to it.
If you would like to put some text inside a container and have it size itself to fill that container, then CSS Tricks has an article on Fitting Text to a Container that will cover your options.
You could also use Viewport Sized Typography which take advantage of viewport units such as:
1vw = 1% of viewport width
1vh = 1% of viewport height
1vmin = 1vw or 1vh, whichever is smaller
1vmax = 1vw or 1vh, whichever is larger
One unit of any v* is 1% of the viewport axis. Where the “Viewport” == browser window size == window object. If the viewport is 50cm wide, 1vw == 0.5cm. Using viewport units alone such as font-size: 4vw; can make the text appear too big or too small when varying the window width and bring accessibility issues (as the user preferences are not taken into account).
Lastly, you could use clamp() to achieve Simplified Fluid Typography. Clamp takes three values, a min, max, and a flexible unit in the middle that it will use in case the value is between the min and max.
If you want the font size to be a minimum of 36px and maximum 54px, you could use clamp() like this and vary the "flexible unit" to your liking. Here is an example of fluid typography for an <h1> element inside a container.
body {
font-size: 1rem;
margin: 0 auto;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.container {
border: .2rem solid #f06;
padding: .5rem;
height: 100%;
width: auto;
}
.container h1 {
font-size: 36px; /* fallback */
font-size: clamp(36px, 10vw, 54px);
}
<body>
<div class="container">
<h1>Heading text</h1>
</div>
</body>
Browser support for clamp() is pretty good, but you’d probably want to put a font-size declaration before it to set an acceptable fallback value.
In conclusion, if you needed to set an explicit width and height for said container, you might want to use media queries along with viewport units, calc(), or clamp() depending on the size of the content box in which the text resides.
i think it's nearly impossible to calculate it without js.
below is an code example how i would do it in jquery or you could use the following jquery plugin, but i never tested this plugin before: FitText.js
for (let container of $('.text-container')){
container = $(container);
let textInner = $(container).find('.text-inner');
console.log(container.width());
console.log(textInner.width());
if (container.width()<textInner.width()){
textInner.addClass('fs-36');
textInner.removeClass('fs-54');
} else {
textInner.addClass('fs-54');
textInner.removeClass('fs-36');
}
}
.text-container,
.text-container-before{
position: relative;
width: 250px;
height: 60px;
background: #333;
color: #090;
overflow: visible;
margin: 20px 0;
}
.text-inner,
.text-before{
position: absolute;
top: 0;
left: 0;
height: 100%;
background: #0399;
word-break: keep-all;
white-space: nowrap;
}
.fs-54{
font-size: 54px;
}
.fs-36{
font-size: 36px;
}
/* just added because console window is hiding running code snipped */
.spacer{
height: 80px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>before</h1>
<div class="text-container-before">
<div class="text-before fs-54">a bit longer text</div>
</div>
<div class="text-container-before">
<div class="text-before fs-54">shorter text</div>
</div>
<h1>after</h1>
<div class="text-container">
<div class="text-inner fs-54">a bit longer text</div>
</div>
<div class="text-container">
<div class="text-inner fs-54">shorter text</div>
</div>
<div class="spacer"></div>
This question awsers was not exactly what I was looking for, so here is a solution to scale down the text if it would exceed the size of the parent container, by making it smaller until it fits the container.
for(const element of document.getElementsByClassName("shrink"))
{
var size = parseInt(getComputedStyle(element).getPropertyValue('font-size'));
const parent_width = parseInt(getComputedStyle(element.parentElement).getPropertyValue('width'))
while(element.offsetWidth > parent_width)
{
element.style.fontSize = size + "px"
size -= 1
}
}
.container{
border:1px dashed #ccc;
display:flex;
align-items:center;
justify-content:center;
width:200px;
height:50px;
margin:10px;
}
.shrink{
white-space: nowrap;
font-size:80px;
}
<div class="container"><span class="shrink">long text to shrink</span></div>
<div class="container"><span class="shrink">small text</span></div>
try word-break: break-all;, I think this will solve your problem
Not, Sure about CSS solution. But, My JS solution can resolve your problem.
Refer below code. Class class-54 and class-36 will change based on content:
// creating node
function createNode(element) {
return document.createElement(element);
}
// creating append
function append(parent, el) {
return parent.appendChild(el);
}
var getPageTitle = document.getElementById("pageTitle"),
textLengthWidth = 0;
const getPageTitleText = getPageTitle.textContent;
getPageTitle.innerHTML = "";
for (let index = 0; index < getPageTitleText.length; index++) {
const span = createNode("span");
span.innerHTML = getPageTitleText.charAt(index);
append(getPageTitle, span);
if (index == getPageTitleText.length - 1) {
calcFontSize();
}
}
function calcFontSize() {
var listOfSpan = document.querySelectorAll("#pageTitle span");
listOfSpan.forEach(element => {
textLengthWidth += element.offsetWidth;
});
console.log("total DIV width: " + getPageTitle.offsetWidth);
console.log("total Content width: " + textLengthWidth);
getPageTitle.offsetWidth < textLengthWidth ? getPageTitle.classList.add("class-36") : getPageTitle.classList.add("class-54");
}
* {
padding: 0;
margin: 0;
font-size: 14px;
}
.title {
display: block;
width: 100vw;
}
h1, h1 span {
font-size: 54px;
}
.class-54 span {
font-size: 54px;
}
.class-36 span {
font-size: 36px;
}
<div class="title">
<h1 id="pageTitle">Hello World! Hello World!</h1>
</div>
Try this
.thingy {
font-size:54px;
overflow-wrap: break-word;
}
<h1 class="thingy">Hel000000000000000000ooo</h1>

Width of Dates are not the same because width of number 1 and 2 are different?

I am working on a react project, and I list some operations ( objects ) in a Table, everything looks fine but the client for something I found very weird and hard, here is how it looks :
But that is not how he wanted the datatable dates looks, he wants something like this :
Is there a CSS property that can make that possible ?
Any help would be much appreciated.
there is too much code to write, but those parts are enough :
HTML :
<div class="co-operations-contrat__date">
<span class="co-operations-contrat__date-text">04/07/2018</span>
</div>
SASS :
.co-operations-contrat {
&__date {
a {
margin-right: 5px;
display: inline-block;
cursor: pointer;
+.co-operations-contrat__date-text {
margin-left: 0;
}
}
&-text {
margin-left: 25px;
font-family: "Poppins", monospace;
}
}
}
Like others have said monospace for the dates would be best. If you can't change the font are you able to wrap each part of the date?
If so what you could do is something like this;
https://jsfiddle.net/8mLwot25/3/
Basically, I've set a width on each span and aligned them with flex on the parent container. (You could also float each span). But by doing this would align the items in a better way.
It's not perfect but its a solution.
.container {
display: flex;
}
.container span {
text-align: center;
width: 20px;
}
.container span:last-child {
width: auto;
}
<div class="container">
<span>01</span>/
<span>04</span>/
<span>2019</span>
</div>
<div class="container">
<span>01</span>/
<span>05</span>/
<span>2018</span>
</div>
<div class="container">
<span>13</span>/
<span>04</span>/
<span>2019</span>
</div>
Maybe letter-spacing can help you with that. I'm not sure if you can achieve a pixel perfect result with that but this property may be usefull.
The issue is related to the Poppins font you are using for these dates. The font is not monospaced (it is sans-serif only).
If using a regular monospace font, the issue no longer appears
See demo below
.co-operations-contrat__date a {
margin-right: 5px;
display: inline-block;
cursor: pointer;
}
.co-operations-contrat__date .co-operations-contrat__date-text {
margin-left: 0;
}
.co-operations-contrat__date-text {
margin-left: 25px;
font-family: "Poppins", monospace;
}
#no-poppins .co-operations-contrat__date-text {
margin-left: 25px;
font-family: monospace;
}
<link href="https://fonts.googleapis.com/css?family=Poppins" rel="stylesheet">
<h2>Poppins In</h2>
<div class="co-operations-contrat__date">
<span class="co-operations-contrat__date-text">30/06/2018</span><br/>
<span class="co-operations-contrat__date-text">31/03/2018</span><br/>
<span class="co-operations-contrat__date-text">04/07/2018</span><br/>
<span class="co-operations-contrat__date-text">31/01/2011</span><br/>
</div>
<h2>Poppins Out</h2>
<div id="no-poppins" class="co-operations-contrat__date">
<span class="co-operations-contrat__date-text">30/06/2018</span><br/>
<span class="co-operations-contrat__date-text">31/03/2018</span><br/>
<span class="co-operations-contrat__date-text">04/07/2018</span><br/>
<span class="co-operations-contrat__date-text">31/01/2011</span><br/>
</div>
<h1>Other workarounds include </h1>
<h2>Usign <TT></h2>
<div class="co-operations-contrat__date">
<tt>30/06/2018</tt><br/>
<tt>31/03/2018</tt><br/>
<tt>04/07/2018</tt><br/>
<tt>31/01/2011</tt><br/>
</div>
<h2>Using <PRE></h2>
<div class="co-operations-contrat__date">
<span>30/06/2018</pre>
<pre>31/03/2018</pre>
<pre>04/07/2018</pre>
<pre>31/01/2011</pre>
</div>
Of course, you can choose any monospaced font of your choosing, I just went the browser's defaults for the demo.

Logout button is not responsive

I am trying to put the logout button at the left toolbar , i have done it by position but it is not reponsive nd by smalling the chrome this button disappers , i have tried margin also but of no use!! How can I do it ??
My HTML
<div class="user-button-container at-xl-12 "#userButton>
<button class="user-button " md-button [mdMenuTriggerFor]="menu">
<div fxLayout="row" fxLayoutAlign="start center">
<at-icon class="at-display-block"backgroundColor="purple" backgroundType="border"size="40px" fontSize="30px"></at-icon>
<span class="name" fxHide="true" fxHide.gt-sm="false"></span>
<md-icon></md-icon>
</div>
</button>
</div>
My CSS
.user-button-container {
height: 100%;
font-weight: 400;
.user-button {
height: 100%;
border-radius: 0;
position: relative;
left: 1050px;
md-icon {
font-size: 16px;
width: 16px;
height: 16px;
}
.name {
margin: 0 8px 0 10px;
}
} }
looks like you have the design specified for xl-format, but not for smaller formats. as far as I know you should always start from small (xs) to large (lg) and not the other way around. so maybe just changing the following could help:
div class="user-button-container at-xs-12 "#userButton>
instead of
div class="user-button-container at-xl-12 "#userButton>
if you are using bootstrap use following class for desktop or mobile
<div class="user-button-container col-md-12 col-xs-12">
</div>
also, it appears you are not closing your css items - make sure you are using {}

How to remove paragraph spacing with CSS? [duplicate]

This question already has answers here:
How to remove the space between inline/inline-block elements?
(41 answers)
Closed 6 years ago.
I am working on a project that needs an aligned letter grid. It must be peppered with tags so i can mess with individual words using css classes.
This is what i've tried so far:
#import 'https://fonts.googleapis.com/css?family=Fira+Mono';
.clockContainer {
margin: auto;
color: black;
letter-spacing: 5px;
}
.clockLetter {
font-family: 'Fira Mono', monospace;
display: inline-block;
margin: 0;
padding: 0;
}
.clockLetter::after {
display: none;
margin: 0;
padding: 0;
}
.clockLetter::before {
display: none;
margin: 0;
padding: 0;
}
<div class="clockContainer">
<!-- First row -->
<div class="clockLetter" id="clockIts">ITS</div>
<div class="clockLetter" id="clockIgnore">Z</div>
<div class="clockLetter" id="clockA">A</div>
<div class="clockLetter" id="clockIgnore">T</div>
<div class="clockLetter" id="clockHalf">HALF</div>
<div class="clockLetter" id="clockIgnore">B</div>
<br/>
<!-- Second row -->
<div class="clockLetter" id="clockIgnore">IP</div>
<div class="clockLetter" id="clockTen">TEN</div>
<div class="clockLetter" id="clockQuarter">QUARTER</div>
<br/>
</div>
Look at how the letters line up until a div is closed then a weird unsolicited blank space appears, ruining the alignment. How can i prevent/remove that?
I am already using a monospaced font so that's not the problem.
EDIT:
I've managed to circumvent the problem by wrapping the rows in a .clockRow element and adding this css rule:
.clockRow>.clockLetter:not(:nth-child(1)) {
margin-left: -9px;
}
It's not an optimal solution so i am still open to better answers.
(Took a page out of CSSTricks' book: https://css-tricks.com/fighting-the-space-between-inline-block-elements/)
use below code and adjust your spacing..
letter-spacing: 0 px;
Change your letter spacing in css as below
.clockLetter {
letter-spacing: 0.01em;
}

Sencha Touch: selected list styling doesn't work

It's probably very simple question, but for some reason I can't find a problem in my code. I have a Sencha Touch app. I define a itemCls in particular list class definition:
xtype: 'list',
store: 'Tenders',
itemCls: 'tenders',
onItemDisclosure: false,
itemTpl: [
'<div class="name">{name}</div>',
'<div class="description">{description}</div>'
].join(''),
And then I have some custom CSS definition where I'm trying to customize this particular list (not all lists in the application):
.tenders {
padding: 0.7em 0.7em;
}
.tenders .name {
padding: 0em 1.5em 0em 0em;
font-size: large;
font-weight: bold;
}
.tenders .description {
font-size: small;
font-weight: light;
padding: 0em 0em 0em 0em;
}
.tenders .x-item-selected {
background-color: green;
}
However selected item is not green. I can see in Chrome debugger the following classes attached to the selected item in the list:
<div class="x-list-item-first x-list-header-wrap x-list-item x-stretched x-list-item-tpl tenders x-list-item-relative x-item-selected" id="ext-simplelistitem-211" style="min-height: 50px !important;">
<div class="x-unsized x-list-disclosure x-item-hidden" id="ext-component-436" style="display: none !important;"></div>
<div class="x-innerhtml" id="ext-element-563">
<div class="name">Name</div>
<div class="description">Description</div>
</div>
</div>
I also can see that .tenders { padding: 0.7em 0.7em } style is being applied, but not the .tenders .x-item-selected.
Any idea what am I doing wrong?
use:
.tenders.x-item-selected {
background-color: green;
}
to make your code more important that standard Sencha css either use the full path
.tenders.x-list-item.x-item-selected.x-list-item-tpl
or
background-color:green!important;
Do not add a space between tenders and x-item-seleced as they are on the same level, while name and description are inside the tenders div

Resources