How to scale text size compared to container - css

How would you scale text size based on container size. Other questions state it can't be done with css, if not how would you go about it?

Here is a way to set the text to fit the width of the container. It works by incrementally increasing the font size of a hidden div until it is smaller than the width of the container for which you want to text to fit inside. It then sets the font size of the container to that of the hidden div.
This is a little inefficient and could be optimized by caching the old width of the container, then incrementing from the old font size to either larger or smaller values based on how the width of the container changed.
jsFiddle: http://jsfiddle.net/sarathijh/XhXQk/
<div class="scale-text styles">
This is a test of scaling text to fit the container. Lorem Ipsum Dolor Sit Amet.
</div>
<div id="font-metrics"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
var fontMetrics = document.getElementById('font-metrics');
var scaleTexts = $('.scale-text');
$(window).on('resize', updateFontSize);
updateFontSize();
function updateFontSize()
{
scaleTexts.each(function()
{
var $scaleText = $$(this);
fontMetrics.innerHTML = this.innerHTML;
fontMetrics.style.fontFamily = $scaleText.css('font-family');
fontMetrics.style.fontWeight = $scaleText.css('font-weight');
fontMetrics.style.fontStyle = $scaleText.css('font-style');
fontMetrics.style.textTransform = $scaleText.css('text-transform');
var fontSize = 50; // max font-size to test
fontMetrics.style.fontSize = fontSize + 'px';
while ($$(fontMetrics).width() > $scaleText.width() && fontSize >= 0)
{
fontSize -= 1;
fontMetrics.style.fontSize = fontSize + 'px';
}
this.style.fontSize = fontSize + 'px';
});
}
/**
* A simple caching function for jQuery objects.
*/
function $$(object)
{
if (!object.jquery)
object.jquery = $(object);
return object.jquery;
}
</script>

You should be able to do this using jQuery -- something like..
$('#cooldiv').css('font-size', '100%')
and
$("#cooldiv").animate({
'width' : (xWidth * (35 / 100)) + 'px',
'minWidth' : (xWidth * (35 / 100)) + 'px',
'maxWidth' : (xWidth * (35 / 100)) + 'px',
'fontSize' : (xWidth * (35 / 100)) + '%'
}, 1000);

I couldn't work out how to do it with CSS, so I used pure JS (don't need jquery).
var els = document.getElementsByClassName('abc')
for (var i = 0; i < els.length; i++){
els[i].style.fontSize = els[i].clientHeight + 'px'
}
Example: http://jsfiddle.net/nickg1/H64mQ/

Here's how I accomplished it- I wrapped the text in a span and scaled that down with a CSS transform:
<div id="fit-text-in-here">
<span>Scale this text to fit inside the parent div.</span>
</div>
jQuery:
$(function(){
var textWidth = $('#fit-text-in-here span').width(),
fitWidth = $('#fit-text-in-here').width();
if (textWidth > fitWidth) {
var scaleTo = fitWidth / textWidth,
offset = (fitWidth - textWidth)/2;
$('#fit-text-in-here span').css({
'-moz-transform': 'scale('+scaleTo+')',
'-webkit-transform': 'scale('+scaleTo+')',
'-o-transform': 'scale('+scaleTo+')',
'transform': 'scale('+scaleTo+')',
'margin-left': offset,
'display': 'inline-block'
});
}
});

Related

width attribute not working with d3 style

I'm trying to display bar graphs with width of each bar representing age. but using style method in d3, i am unable to apply width attribute to the bars (as checked by doing inspect element in browser). other attributes applied using style are working fine.
function showData(clients){
let max = d3.max(clients, (d) => {
return (parseInt(d.age));
})
//console.log(max);
let scale = d3.scaleLinear().domain([0, parseInt(max)]).range([0, 100]);
//console.log(scale);
let join = container.selectAll('div').data(clients);
join.enter().append('div')
.text((d) => {
return d.name + ' : ' + scale(parseInt(d.age));
})
.style('background-color', 'blue')
.style('margin', '5px')
.style('color', 'white')
.style('width', (d) => {
return parseInt(d.age)
});
}
css width is not just a number:
width: 150px;
width: 20em;
width: 75%;
width: auto;
I believe you want:
.style('width', (d) => {
return parseInt(d.age) + 'px';
});
If you're applying width or height to svg or svg elements, use .attr() instead of .style(). In this case, you can use numbers, no px needed. If you don't specify any unit, it will be assumed to be px. If you're using width and height in style attribute, you must specify a unit, no matter what element.
const width = 400,
height = 200;
const svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.style("background", "steelblue")
.append("rect")
.attr("width", 100)
.attr("height", 200)
.attr("fill", "tomato");
<script src="https://unpkg.com/d3#6.3.1/dist/d3.min.js"></script>
<svg></svg>

paper.setup changes the canvas size? Bug in PaperJS?

when I do
paper.setup(imageCanvas);
the width and height of imageCanvas changes from 2048 * 1536 to 681 * 511 I tried to to understand the code by debugging it and
_setViewSize: function(size) {
var element = this._element,
pixelRatio = this._pixelRatio,
width = size.width,
height = size.height;
element.width = width * pixelRatio;
element.height = height * pixelRatio;
if (pixelRatio !== 1) {
if (!PaperScope.hasAttribute(element, 'resize')) {
var style = element.style;
style.width = width + 'px';
style.height = height + 'px';
}
this._context.scale(pixelRatio, pixelRatio);
}
},
is the area where it changes the size of the element by multiplying it by pixelRatio, which is somehow 0.3330000042915344.
Can anybody explain why paperjs would try to change the dimensions?
This is hilarious!
I figured out why the pixelRatio is 0.333... it is because I zoomed out the browser and hence it was changing the canvas size.

How to position an element absolute to the window regardless of its DOM position?

I am creating a pop-up overlay modal and am having problems getting the positioning/scrolling working correctly.
I can set my modal to be position:fixed but then if the modal's height is too much, then the modal overflows off of the window and you cannot see the bottom of it.
If I set the modal to be position:absolute then the element becomes positioned relative to the closest ancestor with position:relative, correct? (or at least thats what it appears to do) Instead I want the modal to ALWAYS be relative to the window so that I can center it easily.
Is there a way to make the below .modal positioned relative to the window ( or element) even if the element is nested deep inside the DOM like this:
<body ng-app="myapp" ng-controller="mycontroller">
<div>
<div>
<div ui-view>
<div class=".modal"></div>
</div>
</div>
</div>
</body>
If you insist on having it in that same markup and nested in the same manner, your best bet is in JavaScript.
Here's some JS code that gives a good method of accomplishing what you asked for:
function ShowDivInCenter()
{
try
{
divWidth = 100;
divHeight = 100;
divId = 'divLogin'; // id of the div that you want to show in center
// Get the x and y coordinates of the center in output browser's window
var centerX, centerY;
if (self.innerHeight)
{
centerX = self.innerWidth;
centerY = self.innerHeight;
}
else if (document.documentElement && document.documentElement.clientHeight)
{
centerX = document.documentElement.clientWidth;
centerY = document.documentElement.clientHeight;
}
else if (document.body)
{
centerX = document.body.clientWidth;
centerY = document.body.clientHeight;
}
var offsetLeft = (centerX - divWidth) / 2;
var offsetTop = (centerY - divHeight) / 2;
// The initial width and height of the div can be set in the
// style sheet with display:none; divid is passed as an argument to // the function
var ojbDiv = document.getElementById(divId);
ojbDiv.style.position = 'absolute';
ojbDiv.style.top = offsetTop + 'px';
ojbDiv.style.left = offsetLeft + 'px';
ojbDiv.style.display = "block";
}
catch (e) {}
}
You can then call the function through any event, for example:
<body onload='ShowDivInCenter();' onresize='ShowDivInCenter();'>
if you want it to be dynamic.

Background Image - how to scale properly with just css

I have this site in development, http://melanie.3drexstaging.com/
The client wants the background to scale up or down (to a point) depending on the browser size.
I have gotten it to work halfway decent with some jquery hacks to adjust sizing of elements as the browser resizes, but I would much prefer a css only option.
We have 3 images, one is the fixed aspect ratio center image that should always show in entirety, and to the left and right we have the images that continue the pattern.
Thanks in advance for any tips!
My SAD javascript hacks:
<script type="text/javascript">
$(document).ready(function () {
fixBg();
});
$(window).load(function () {
fixBg();
});
$(window).resize(function () {
fixBg();
});
function fixBg()
{
var mh = Math.max($(window).height(), 768);
if ($("#ControlBar").length > 0) {
mh -= 54;
}
var mw = Math.round((mh / 768) * 1264);
var winW = Math.max(1264, $(window).width());
$("#bgCenter").height(mh).width(mw);
$("#shade").height(mh).width(mw).css("left", ((winW - mw) / 2) + 10);
var extra = ((winW - mw) / 2) + 10;
$(".bgFillers").width(extra).height(mh);
var bgw = (mh / 768) * 360;
$(".bgFillers").css("background-size", bgw + "px " + mh + "px");
//$("#siteContent").css("min-height", mh - $("#header").height() - $("#footer").height() - 20);
}
</script>
And the basic markup:
<div id="master">
<div id="bg">
<div id="bgLeft" class="bgs bgFillers"></div>
<div id="bgCenter" class="bgs">
</div>
<div id="bgRight" class="bgs bgFillers"></div>
</div>
<div id="shade"></div>
<div id="centeredSite">
</div>
</div>
have you tried making the size relative?
you just use % instead of px (or any other option)
100% is full element, 50% is half your element (if you put it in a div you set to 50% it'll take half of the div that's taking up half of your page, so 1/4th of your page)
otherwise i'll need some more information

How to set offset on (selectmenu) overlays in jQuery Mobile [using a fixed header toolbar]?

Is there a way to define the offset JQM uses for selectmenu overlay?
Other options can be set via prototyping like this:
$.mobile.page.prototype.options.addBackBtn = true;
$.mobile.page.prototype.options.backBtnTheme = "a";
Problem description
jQuery Mobile determines the size of the screen and decides how to display the overlay for select menus. Unfortunately this seems to work only without using a fixed header toolbar, because JQM is generation the source over here always with the top-offset of 30px style="left: 741.65px; top: 30px;.
There is no ways to overwrite this with CSS only, because the specificity of the css rules are always lower than the ones of an style-attribute!
I don't want to change the JQM sourcecode, because I'd have to change it again with every release. And I don't use the uncompressed sources.
Generated source from JQM
<div class="ui-selectmenu ui-overlay-shadow ui-corner-all ui-body-a pop in"
style="left: 741.65px; top: 30px;">
Sample
http://jsfiddle.net/V8AAB/
JQM Source code
This is the corresponding code from jQuery Mobile 1.0RC2:
self.menuType = "overlay";
self.screen.height( $(document).height() ).removeClass( "ui-screen-hidden" );
// Try and center the overlay over the button
var roomtop = btnOffset - scrollTop,
roombot = scrollTop + screenHeight - btnOffset,
halfheight = menuHeight / 2,
maxwidth = parseFloat( self.list.parent().css( "max-width" ) ),
newtop, newleft;
if ( roomtop > menuHeight / 2 && roombot > menuHeight / 2 ) {
newtop = btnOffset + ( self.button.outerHeight() / 2 ) - halfheight;
} else {
// 30px tolerance off the edges
newtop = roomtop > roombot ? scrollTop + screenHeight - menuHeight - 30 : scrollTop + 30;
}
Suggested Fix:
.ui-selectmenu { z-index: 1100 !important; }

Resources