Convert all occurrences of px to rem for responsive design - css

I am a noob web developer and made a big mistake.
I am creating a website for a college project, it needs to be responsive. I have tons of CSS written all in px units. But now for responsiveness, I want to convert all the px to rem. It would be a tiring task to do it one by one. Is there any tool that can help me?

I don't know of any tool that would automatically change all px to rems but you can make the changes quickly if you do something like this:
body {
font-size: 0.625rem;
{
Now 1 rem will be equal to 10 px, if you use Vscode you can enter a shortcut Ctrl + F and choose a Use Regular Expression option in Find input.
Then you can type (\d*)?(\d).?(\d*)?px in Find field, and $1.$2$3rem in Replace field.
But be alert, this regex doesn't work for sizes beginning with dot like .5px.
The search bar should look like this:
If you want to learn how this regular expression works click here.

Regex shouldn't be used this way, but...
This function should work but the predicament you are in is usually a one time thing and I normally advise against using Regex in this manner. The function pxToRem():
Finds all occurrences of a number (even with a decimal) adjacent to the letters 'px'.
Then a replacer function takes the number part and divides it by 16
Next it suffixes the new number with 'rem' and replaces the old number and 'px'.
Usage
Open your stylesheet, select as much of the text you need to change and copy it.
Next, paste it on a blank .html or .js file.
Wrap the text in grave marks ``` on a QWERTY keyboard it's the key located upper left hand corner `~
Assign the string to a variable.
Copy and paste pxToRem() code to the same page.
let css = `.box {width: 32px; height: 16px; border: 6px; padding 2.5px;}`;
function pxToRem(CSSString) {
const rgx = new RegExp(/(\d+\.?\d*)px/, 'g');
return CSSString.replace(rgx, (match, n) => (n / 16) + 'rem');
}
console.log(pxToRem(css));
Keep in mind that rem are relative to the font-size set on :root/html and if that font-size happens to be absolute (like the default of 16px) then the styles with rem aren't responsive, but they have the potential to be responsive. If you use a vmin units all rem will react immediately to any changes to the viewport. This not for the faint of heart.

Related

A potential bug involving Background Image and Media Query

This current class works fine:
bg-[url('https://d2kcw0xpn7sann.cloudfront.net/[GLOBAL]/sellout-vbox-inner-bg.svg')]
But this one does not work:
lg:bg-[url('https://d2kcw0xpn7sann.cloudfront.net/[GLOBAL]/sellout-vbox-inner-bg.svg')]
Here is the tailwind play link if you wanna checkout for yourself
enter link description here
It is not about media query + background image but pattern. Try this
<div class="h-64 w-64 md:bg-[url('https://picsum.photos/200/300')]"></div>
You'll see it working
This instead does not (image on hover)
<div class="h-64 w-64 hover:bg-[url('https://d2kcw0xpn7sann.cloudfront.net/[GLOBAL]/sellout-vbox-inner-bg.svg')]"></div>
If you hover you class in TailwinPlay you should notice it is generates property but fail to generate class name
But if you replace : or one of brackets [ with any symbol it will generate class properly (of course image link will be broken in that case)
Why does this happen? I'm not entirely sure but I believe it because this image link meet Tailwind's pattern. Most common pattern for Tailwind's arbitrary values is
variant:utility-[value]
e.g.
lg:bg-[red]
your case
lg : bg- [ url(link) ]
lg - modifier
: - separator
bg- - utility
[] - arbitrary value wrapper
url(link) - arbitrary value
Also Tailwind supports variants combination e.g. md:hover:[some]:. If you look closer to your class lg:bg-[url('https://d2kcw0xpn7sann.cloudfront.net/[GLOBAL]/sellout-vbox-inner-bg.svg')] - it may be consider as two variants plus arbitrary value
lg: - variant 1
bg-[url('https: - variant 2
//d2kcw0xpn7sann.cloudfront.net/ - utility
[GLOBAL] - arbitrary value
So I think Tailwind confused here in a regex and don't know what to generate. Submit an issue in Tailwind's repository for that
Mean time if you need to fix it just encode square brackets
lg:bg-[url('https://d2kcw0xpn7sann.cloudfront.net/%5BGLOBAL%5D/sellout-vbox-inner-bg.svg')]
DEMO

How to set froala to calc height using css

I have the following CSS which I use to set the height of CodeMirror which works well across browsers :
.CodeMirror {
/* Firefox */
height: -moz-calc(100vh - 190px);
/* WebKit */
height: -webkit-calc(100vh - 190px);
/* Opera */
height: -o-calc(100vh - 190px);
/* Standard */
height: calc(100vh - 190px);
}
Now, I am moving to froala which appears to be the only WYSIWYG editor that supports CodeMirror as the 'view code' portion.
I have no problem embedding and setting up CodeMirror to work with this, and the style that I applied works with the embedded CodeMirror, however I am unable to apply the Height to the requisite CSS file in the manner I have done with CodeMirrors CSS file.
There are height, heightMax, heightMin, and fullPage properties for froala which can be set during JavaScript initialization, however this does not support calculated values.
Before using CSS's calc() method, I was using JavaScript to size CodeMirror with mixed results, and a lot of extra checks in place which was much more "jumpy" and often either going out of bounds (box going beyond the containing elements height), or falling just short (leaving a gap between the editor element and the containing elements height).
What I would like to do, is override the containing elements height via CSS (I don't mind editing the froala_editor.css file (or other files directly part of the project) to do this. To figure this out for CodeMirror took a rather long time to find the ONE spot where the height calc css would go into the .CodeMirror block. With froala, I do not know where or what the equivalent is called to size the editable area.
I have tried placing the size code in several places including .fr-box.fr-basic .fr-element, to no avail.
The height parameter of froala accepts valid CSS values like 100px, 100, or 100%. As a result, you can use browser detection to fairly effectively decide which value to set.
Following is one example on how this can be done, while still maintaining the calc method in CSS without the need to modify any of froala's CSS files :
// set the default calc value
var codeHeight = 'calc(100vh - 96px)';
// prepend any browser engine specific names if needed
if((navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf('OPR')) != -1 ) {
codeHeight = '-o-' + codeHeight;
} else if(navigator.userAgent.indexOf("Chrome") != -1 ) {
codeHeight = '-webkit-' + codeHeight;
} else if(navigator.userAgent.indexOf("Safari") != -1) {
codeHeight = '-webkit-' + codeHeight;
} else if(navigator.userAgent.indexOf("Firefox") != -1 ) {
codeHeight = '-moz-' + codeHeight;
}
// Initialize froala using calc for height
$('.code').froalaEditor({
height: codeHeight
});
While the above is a hackish way to accomplish this, there are other browser detection methods which could be applied. This just demonstrates how this can be done as elegantly as possible without touching any of froala's sources.
In summary, this works as follows :
Detect the browser (above case uses JavaScript and UserAgent)
Set an accessible variable to the detected browser supported calc CSS method
Pass the accessible variable to froala's height init parameter.

Is it possible to make .tt-input wider?

The typeahead example on the typeahead website seems to limit the width of the .tt-input using 3em !important in the style of the element, so that when you type something which is longer than 3em it starts to scroll out of view in this tiny input.
How can I make .tt-input wider?
Here is a screenshot to help explain what I'm talking about: http://oi57.tinypic.com/2vvt9qc.jpg.
This appears to be hardcoded into bootstrap-tagsinput.js, see lines 46-47:
var inputWidth = (this.inputSize < 3 ? 3 : this.inputSize) + "em";
this.$input.get(0).style.cssText = "min-width: " + inputWidth + " !important;";
inputSize is computed based on the placeholder text. If there is none, it will default to 3em. You might want to change these lines to obtain a different value, or remove the attribute altogether. I'm not entirely sure why it's there.
set the class to this:
input.tt-input {
width:auto !important;
}
... make sure you put it AFTER the typehead css so that it's overwritten.
I had the same problem and Eepzy is correct: bootstrap-tagsinput.js does use the placeholder text to determine the size of the input field, but the 3em is only used if you don't have a placeholder text that is a least 3 characters long.
I think editing a 3rd party js is not good practice in general.
There is a different solution to our problem: just use a placeholder text.
<input type="text" class="tagsinput" placeholder="Type here..."/>
Any text (except whitespaces) will do as long as it is at least 3 characters long.

How can I render moon phase icons in CSS?

We are adding moon phase icons to a website.
We want to show an image for each percentage of the moon- so 100% will be a full moon, 5% a thin crescent, etc. Similar example
The current plan is to generate 100 png images of the moon in percentage stages of shadow, and point to these as required.
I've found code for a CSS animation, which is brilliant, but we really want static images.
Can I render an image of the moon in percentage shadowed increments, using CSS?
Might not be exactly what you are looking for, but I've written a JavaScript library to generate moon/planet phase discs.
The JS code really just calculates the size and position of the 2 discs, as described by #jcaron in his answer, so if you didn't want to use scripting for this you could just use the library to work out the correct CSS values and hand-code those into your page.
It's just a matter of having two discs, one over the other, with the right offset between the two. You can draw a disc in CSS by having a box with a 0-size contents (and padding) and corner-radius set to the width of the border.
I realize this is an old question but I was looking for a similar solution and developed an answer for PHP based off the CSS animation OP had linked to. I am using a script called MoonPhase.php from https://github.com/solarissmoke/php-moon-phase, which among other things provides the number of days into the current lunar cycle (returns a number between 0 and approximately 29.53, with 0 being the start of the new moon). I used this to create a function that gives me the adjustments for the CSS. It appears that the range of numbers for the CSS are based on the size of the drawn disc, so I made the entries variable based around vw numbers to allow for automatic screen sizing. This required pushing out the block through php, and in a real page you would want to keep this within the of course.
<?php
include("MoonPhase.php");
$moonSize = 10; // output in vw, 10 would equal 10% of screen width
$moon = new Solaris\MoonPhase();
$age = $moon->age(); // or you can provide a number between 0 - 29.53
$pos = moon_pos($age, $moonSize);
echo <<<EOT
<div class="moon"></div>$age
<style>
body {background: #111;}
.moon {
background: #111;
border-radius: 50%;
box-shadow: inset {$pos}vw 0 1px #f5f5f5, 0 0 3px #444;
display: inline-block;
height: {$moonSize}vw;
transform: rotate({$pos}deg);
width: {$moonSize}vw;
}
</style>
EOT;
function moon_pos($age, $sz) {
$cycle = 29.53058868;
$pos = ($age - ($cycle / 2)) * (($sz * 2) / $cycle);
$pos = ($pos >= 0) ? $sz - $pos : -$sz - $pos;
return $pos;
}
I have made changes to the CSS to not rely on color names. I also added a small faded border so that you can always see the outline of the moon, plus some blurring of the black disc edges. The final output gives a near pixel-perfect rendering of the current moon phase.
The magic of moon_phase() is getting the correct numbers to work with the CSS. The CSS has a range of -$moonSize to +$moonSize, with the new moon (completely black) at 0. That happens to be the opposite of the current cycle age which has the full moon in the middle of the range, so I had to make a 2-step adjustment to squeeze the 29 days into the right range and then flip the output to get the proper transition from -10 to +10. There is probably a more elegant way to do this, but the current code worked.

Using percent for font size?

I've read a fair bit about resizing fonts recently, most of it deriding using px as an unforgivable crime (ok, maybe not that bad, you get the idea) because it doesn't resize properly in older browsers.
I really want to have a standard that I use myself, in the past that has been px, simply because it's simple, easy to understand and fairly easy to achieve the exact font sizes that are specified in designs - but I'm now doubting using px.
I used em on a project recently because it needed text-resizing functionality which I made using jQuery. But I found it quite frustrating because of the way that em amplifies if you have two elements inside of each other both with an em size specified (hope that makes sense)
So I was wondering about using % for font resizing, I've seen a couple of big websites use this technique (namely, Yahoo) and from what I understand it seems to have all of the advantages of em without the incredibly annoying amplification thing.
So in short, I'm just wondering if there are any issues with using % for font-sizing in CSS? Would it be better than using PX in terms of font-resizing? And are there any noticeable draw backs?
Apologies if the blurb before the question is a little much :/ I'm still kind of getting used to the whole QA thing
In CSS3, use rem (root em). Sizing will not be affected by em size of the parent element.
The root font size is set by setting the font size on the :root pseudo-element, like so:
:root {
font-size: 16px;
}
try using this
body {
margin: 0px;
padding: 0px;
font-size: 62.5%;
}
body>#wrapper {
font-size:1em;
}
so, when you say something like 1em inside the "wrapper" you'll have a size very similar to 10px. here's a example table:
3em == 30px
.5em == 5px
8.5em == 85px
This will help you in the transition
P.d: of course, you need a wrapper tag after the body
The standard in web design as far as I have experienced it is to use a percent to set the font size in the body, then to use ems to change the font sizing after that. You could use percents outside the body tag with no adverse side effects, but I think many developers find ems easier to work with (anyone is free to check me on this).
The danger comes if you use ems to set the body font size; older browsers choke and incorrectly display the text, especially when zoomed.
There's a jQuery plugin called FitText. It resizes text based on percents. If the visitor for some reason has JavaScript disabled, it'll just display as normal, so set a reasonable PX or EM backup.
It depends on jQuery, so you'll need to include that in your page (if you don't have it already).
jquery.fittext.js for reference:
/*global jQuery */
/*!
* FitText.js 1.0
*
* Copyright 2011, Dave Rupert http://daverupert.com
* Released under the WTFPL license
* http://sam.zoy.org/wtfpl/
*
* Date: Thu May 05 14:23:00 2011 -0600
*/
(function( $ ){
$.fn.fitText = function( kompressor, options ) {
var settings = {
'minFontSize' : Number.NEGATIVE_INFINITY,
'maxFontSize' : Number.POSITIVE_INFINITY
};
return this.each(function(){
var $this = $(this); // store the object
var compressor = kompressor || 1; // set the compressor
if ( options ) {
$.extend( settings, options );
}
// Resizer() resizes items based on the object width divided by the compressor * 10
var resizer = function () {
$this.css('font-size', Math.max(Math.min($this.width() / (compressor*10), parseFloat(settings.maxFontSize)), parseFloat(settings.minFontSize)));
};
// Call once to set.
resizer();
// Call on resize. Opera debounces their resize by default.
$(window).resize(resizer);
});
};
})( jQuery );
Maybe will this make more sense of making a font-resize script.
I had made a script that did exactly what you desire, but I cant find it any more.
Pseudo-code:
var fontSize = 15; // (em) input
var fontResize = -1;// (em)input
fontSize = fontSize+fontResize; //current div
for(every inherent parent classname == 'classname-em')
document.classnameParentSize[numberofclass] = classnameChildSize[numberOfClass]/100*90;
So explained in words. The script needs to resize some fonts, when that is done it will also look for some parent divs to resize those fonts too, except they will be resized 10% less than its inherent. With some puzzling you will have the right conversion. Also try to avoid paddings and border widths.

Resources