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.
Related
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.
A few years ago I made some CSS code customization on my forum. Since then (probably, due to updates or some other reason), right now it doesn't show it right (the way it was). The idea is that I've got one color of a bg where there's a name of a poster and his avatar and then there's another color where there's text that he writes (verbiage of the post itself). I'm attaching the print screen on which I show what exactly do I mean.
Also I would tell what I did so far to achieve the effect (though it's not exactly right at the moment).
In file Themes/default/css/index.css (line 1921) I added this line of code:
background:url('http://idevsky.com/images/post_bg.png') repeat-y;
And also I changed the height to 0px from 11px in two places:
line 972 and line 987
You can see it if you go to:
http://idevsky.com/forum/index.php
Test account credentials:
j.smith qwerty
Then you click on John Smith (the only board) and then you go to "test" thread (the only one there).
There're 3 different colors:
1) the one where the poster name and avatar is (#dfecf5), it's the way it should be.
2) then there's one that covers the majority of post text area (#ebf3fb), it's the right color, it just doesn't spread right
3) then there's one irrelevant (wrong) color (#f0f4f7) which you can hardly see in the second post (the one that j.smith wrote) and it starts from the arrow point to the right.
print screen
Just remove your image and give it a background color also give your poster class a background color.
.post_wrapper {
background: white;
}
.poster {
background: aliceblue;
}
Search index.css and you change the background-color of .windowbg and .windowbg2 in the CSS file to #ebf3fb as the following:
.windowbg, #preview_body {[enter image description here][1]
color: #000;
background-color: #ebf3fb;
}
.windowbg2 {
color: #000;
background-color: #ebf3fb;
}
Check out this picture to help you find the code:
http://i.stack.imgur.com/MfJaB.png
I'm pretty new to this Qt thing and its whole stylesheet system. My background of HTML/CSS helps a little to understand the system, but a lot of things just happens for no apparent reason....or don't happen.
Anyway, the mystery of the HLINE and the VLINE and how to change the lines' color is just a mystery for me. I learned from other questions and various fora that it's linked to the QFrame elements. And I can change the color of the line if I just use something like
QFrame
{
color: red;
}
But this of course changes the color of tons of other things that uses a QFrame as well. I could of course go into the HLINE element and put color: red; in there and that works fine, but my app requires that I put everything in a single stylesheet that gets loaded into the app. So styling individual elements is not an option.
A solution would look something like
QFrame HLine, QFrame VLine
{
color: red;
}
QFrame[frameShape="4"] /* QFrame::HLine == 0x0004 */
{
color: red;
}
QFrame[frameShape="5"] /* QFrame::VLine == 0x0005 */
{
color: green;
}
HLine and VLine are tricky to style. It's worth taking a look at the "Detailed Description" section of the documentation. For a quick fix, I found that this set of rules allows customizing the appearance of such lines via stylesheet in a reliable and relatively clean manner:
QFrame[frameShape="4"],
QFrame[frameShape="5"]
{
border: none;
background: red;
}
This works regardless of the frameShadow property, which otherwise affects their appearance and the effect of style rules. Keep in mind that the width of the lines are not 1px by default -- this can be changed using the min-width, max-width, min-height or max-height properties, as appropriate.
For a more detailed overview of my findings, read along.
Most QFrames have the QFrame::Plain frameShape by default, but HLine and VLine's default frameShape is QFrame::Sunken. This means that they are not really lines, but thin boxes that contain a mid-line that's used to provide the 3D effect. From the documentation:
The mid-line width specifies the width of an extra line in the middle of the frame, which uses a third color to obtain a special 3D effect. Notice that a mid-line is only drawn for Box, HLine and VLine frames that are raised or sunken.
If you set the frameShape to Plain, this midline is still visible, and can be styled with the color property (note: that's not a background-color or border-color!)
But this doesn't work for a HLine/VLine that's left with the default Sunken appearance. One way to fix this could be to set separate styles for Plain and Sunken QFrames by using attribute selectors with the decimal values of the property enums (which are described in the documentation in hehadecimal), like so:
/* Reference (from doc.qt.io/qt-5/qframe.html#types):
* - frameShape[4] --> QFrame::HLine = 0x0004
* - frameShape[5] --> QFrame::VLine = 0x0005
* - frameShadow[16] --> QFrame::Plain = 0x0010 (default for most widgets)
* - frameShadow[48] --> QFrame::Sunken = 0x0030 (default for HLine/VLine)
*/
QFrame[frameShape="4"][frameShadow="16"],
QFrame[frameShape="5"][frameShadow="16"]
{
...
}
QFrame[frameShape="4"][frameShadow="48"],
QFrame[frameShape="5"][frameShadow="48"]
{
...
}
but since the styles that work for HLine/VLine with QFrame::Sunken also work for those with QFrame::Plain, it's usually a waste to do so. I show them above for educational value only about how to use attribute selectors.
The best approach is to treat the QFrame as the box that it is, and either (1) set border-top or border-right coupled with a max-height: 0px (or max-width for a VLine), to ensure the inside of the box doesn't take up space in the layout; or (2) use a background color coupled with border: none (in which case, max-height/width should be 1 or larger, otherwise the QFrame is invisible). The latter is the solution I'd recommend, as shown in the first code block above.
Hope this helps!
According to QDarkStyleSheet issue, You could use:
QFrame[width="3"], QFrame[height="3]
These selectors, they seem to work cross-platform, and they are unlikely to change.
Probably better than using enum values as ints, as they are likely to change with Qt versions, and line styling are not, as they fulfill certain requirements.
but my app requires that i put everything in a single stylesheet that
gets loaded into the app.
You can use Conflict Resolution. Suppose that you have a QMainWindow object with lots of widgets on it . Set these style sheets for the maindionw style sheet :
QLabel#label{
background-color: rgb(255, 170, 255);
}
QPushButton#pushButton{
color: rgb(0, 0, 255);
}
QFrame#line{
background-color: rgb(0, 170, 255);
}
The first css just changes a QLabel name label on your mainwindow and set its back color to rgb(255, 170, 255). The next will change text color of a QPushButton named pushButton to (0,0,255);. The third one change property of a line.Lines are just a QFrame.
So the solution that I can offer is to place your css in a file and then load this file using QFile and QTextStream and then set the contents of the file for css of your main winodw or main widget using setStyleSheet ( const QString & styleSheet ) function. or If you are using creator just right click on your main window and select change stylesheet and then paste your css. But bear in mind that you should use conflict resolution.
You can leave Qt's hlines and build up your own very easy. For frames you want looks like hline add property "class" as "HLine" (for example), in designer or in c++ code:
frame->setProperty("class", "HLine")
.
Then, you can define in main view's or in global app stylesheet something like this:
QFrame.HLine {
border: none;
border-bottom: 2px solid red;
}
and you will get horizontal two pixels red line.
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.
I'm having an issue with horizontally centering sprites using Compass Sprites.
I have a bunch of sprites that are of different sizes for icons and I want them to be centered on the container they're in so they're a left hand side icon for instance.
If I do this:
$sprite-position: 50%;
#import "sprite/*.png";
then the images are centered on the generated sprite.png but the CSS is actually something like:
background-position: -9px -223px;
rather than the expected:
background-position: 50% -223px;
What's the point of centering it on the sprite if its going to have the location specifically declared like that? Right now I'm hardcoding it as 50% and the Y-axis which sucks because when I add a new sprite then I have to change them all which completely defeats the purpose.
Am I doing this wrong in Compass, CSS or does it just not work as its supposed to?
The only way I can see this being done is by having it specify the dimensions then contain the icon and center it within there. The 50% left value is there though so you don't need to do this... right?
Just a note... it sucks that Compass doesn't support JPEG sprites as well -.- Got about 6 promotion images on the front page and it would be nice to have them sprited up where you can just replace the images in the folder and its sorted!
Thanks, Dom
Just stubmled upon your question. I get your point and had the same problem. I also tried to find a general solution. But it doesn't seem to be possible atm.
For me the position offset option works, but it's not perfect cause you have to apply it to each sprite:
#import "socialmedia/*.png";
a.twitter {
#include socialmedia-sprite("twitter");
#include socialmedia-sprite-position("twitter", 50%);
}
a.facebook {
#include socialmedia-sprite("facebook");
#include socialmedia-sprite-position("facebook", 50%);
}
This is overwriting the horizontal value but keeps the vertical value.
As I said, not perfect but works if you don't need to adjust a huge amount of spites. You could write a mixin though. But still... would be great if Compass itself would provide such an option.
Just to check if I'm getting you right: You created a sprite for all the icons you want to center. Within the sprite all icons are centered, so you can use x:50% and the according y-value, right?
Since compass set's the wrong background-position you could use other method. At least, thats what I did. If you don't need to support IE6/7 you could use compasses inline-data-feature: http://compass-style.org/reference/compass/helpers/inline-data/
This way you reduce the HTTP-Requests which is the main purpose of a sprite but at the same time you get all the benefits a normal image would give you.
If you build a smart mixin this is very, very handy. And even smarter than sprites.
I had the same issue. I wanted to center a horizontal sprite vertically (e.g. creating icon using :after on an inline element).
Unfortunately Compass converted my 50% to 50px so I created these functions:
#function _sprite-position-nth($map, $sprite, $n) {
$positions: sprite-position($map, $sprite);
#return nth($positions, $n);
}
#function sprite-position-x($map, $sprite) {
#return _sprite-position-nth($map, $sprite, 1);
}
#function sprite-position-y($map, $sprite) {
#return _sprite-position-nth($map, $sprite, 2);
}
Example usage:
$icons: sprite-map("icons/*.png", $layout: horizontal);
a.arrow:after {
background: $icons sprite-position-x($icons, arrow-right) 50%;
//...
}
I hope I could help.