Stylus not parsing all variables in the same way - stylus

I'm trying to parse a list in Stylus (latest version), but it's having odd results.
$small = 200px
$medium = 400px
$large = 600px
$list = small $small,
medium $medium,
large $large
for ham in $list
#media screen and (min-width: ham[1])
.{ham[0]}
width ham[1]
yields
#media screen and (min-width: ham[1]) {
.small {
width: 200px;
}
}
#media screen and (min-width: ham[1]) {
.medium {
width: 400px;
}
}
#media screen and (min-width: ham[1]) {
.large {
width: 600px;
}
}
The ham[1] variable isn't getting parsed in the media query regardless of whether I wrap it in {} or not, but it's parsed elsewhere just fine. What am I missing here?

Currently, media queries do not allow for interpolation. What you can do however is use one variable. Just construct the query beforehand for now :
$small = 200px
$medium = 400px
$large = 600px
$list = small $small,
medium $medium,
large $large
for ham in $list
query = 'screen and (min-width: %s)' % ham[1]
#media query
.{ham[0]}
width ham[1]
UPDATE :
With Stylus 0.44 (or 0.45), they now do !

Related

Global media queries on a react project

I'm trying to generate a general structure of styles on scss with global breakpoints as media queries on a react project, It is possible to reuse an structure to follow media queries that we declare as global.
I'm a little bit lost on this one, any ideas?
When I mean global is that we can define the breakpoints at the root of the project and we can use any reference on the components.
Thanks in advance.
There are three ways that come to mind:
You can create a variables.scss file in which you can write the value of your breakpoints:
$sm: 576px;
$md: 768px;
$lg: 992px;
$xl: 1200px;
And the use the following variables in your scss:
#media only screen and (min-width: $sm) {
.container {
.max-width: 450px;
}
}
#media only screen and (min-width: $md) {
.container {
.max-width: 650px;
}
}
#media only screen and (min-width: $lg) {
.container {
.max-width: 900px;
}
}
#media only screen and (min-width: $xl) {
.container {
.max-width: 1000px;
}
}
Or you can the mentioned variables in your mixins.scss file to create some media query mixins:
#mixin small {
#media only screen and (min-width: $sm) {
#content;
}
}
And then, use these mixins in your main scss codes:
.container {
#include small {
max-width: 450px;
}
...
}
Or if the use cases of these media queries are limited (e.g. hiding and showing elements), you can define other mixins that include all the variations:
$displays: none inline inline-block block table table-cell table-row flex inline-flex;
$sizes: (
sm: $sm,
md: $md,
lg: $lg,
lg: $xl
);
#each $display in $displays:
#each $size-key $size in $sizes {
.display-#{size-key}-#{display} {
display: $display !important;
}
}
}
A note on importing files: I personally would import all my helper scss (variables, mixins, etc.) in a file called styles/index.scss in the root of my project among with normalizing and other global rules that I want to define, and then import this file in my other scss files:
// styles/index.scss
#import './variables.scss';
#import './mixins.scss';
...
// container.scss
#import './styles/index.scss';

How do I implement responsive typography with Bootstrap 4?

I'm building a responsive web app with Bootstrap 4. I want the font size of all text to be reduced on mobile devices compared to desktop, so I added the following to my base css file as per the Bootstrap documentation (https://getbootstrap.com/docs/4.0/content/typography/):
html {
font-size: 1rem;
}
#include media-breakpoint-up(sm) {
html {
font-size: 1.2rem;
}
}
#include media-breakpoint-up(md) {
html {
font-size: 1.4rem;
}
}
#include media-breakpoint-up(lg) {
html {
font-size: 1.6rem;
}
}
However the font size remains fixed. What am I doing wrong?
As of Bootstrap 4.3.1, there is now RFS (Responsive Font Sizing)! However, as explained in the docs, you must enable it using the $enable-responsive-font-sizes SASS variable.
RFS Demo: https://www.codeply.com/go/jr8RbeNf2M
Before Bootstrap 4.3.1, you'd can implement responsive text using SASS. However you need to specify the desired appropriate selector(s) for text that you want to resize...
#import "bootstrap/functions";
#import "bootstrap/variables";
#import "bootstrap/mixins";
html {
font-size: 1rem;
}
#include media-breakpoint-up(sm) {
html {
font-size: 1.1rem;
}
}
#include media-breakpoint-up(md) {
html {
font-size: 1.2rem;
}
}
#include media-breakpoint-up(lg) {
html {
font-size: 1.3rem;
}
}
#import "bootstrap";
Demo: https://www.codeply.com/go/5pZDWAvenE
This could also be done using CSS only (no SASS):
Demo: https://www.codeply.com/go/E1MVXqp21D
I think the easiest way is to use #media Queries. Suppose you want to change the font size responsively for a content with class "class-name" or even for entire html tag, just add your media queries to end of your css file or any place inside it.
Sample code:
/*
####################################################
M E D I A Q U E R I E S
####################################################
*/
/*
::::::::::::::::::::::::::::::::::::::::::::::::::::
Bootstrap 4 breakpoints
*/
/* Small devices (landscape phones, 544px and up) */
#media (min-width: 544px) {
.class-name {font-size: 16px;}
}
/* Medium devices (tablets, 768px and up) */
#media (min-width: 768px) {
.class-name {font-size: 30px;}
}
/* Large devices (desktops, 992px and up) */
#media (min-width: 992px) {
.class-name {font-size: 40px;}
}
/* Extra large devices (large desktops, 1200px and up) */
#media (min-width: 1200px) {
.class-name {font-size: 48px;}
}
more information can be found here
This is a Sass feature.
To have access to the media-breakpoint mixins and the size variables, you need to:
add a custom.scss file
#import "node_modules/bootstrap/scss/bootstrap";
and setup a Sass compiler
https://getbootstrap.com/docs/4.0/getting-started/theming/
Not a complete answer, but a good starting point is to enable responsive font sizes in v.4.5
$enable-responsive-font-sizes: true;
#import "../../../node_modules/bootstrap/scss/bootstrap";
Here is an alternative approach with loop
#import "bootstrap/functions";
#import "bootstrap/variables";
#import "bootstrap/mixins";
$font-sizes: (
html: ( xs: 1rem, sm: 1.2rem, md: 1.3rem),
);
#each $breakpoint in map-keys($grid-breakpoints) {
#include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
#each $name, $values in $font-sizes {
#each $n, $value in $values {
#if($infix == "-#{$n}" or ($infix == "" and $n == 'xs')) {
#{$name} { font-size: $value; }
}
}
}
}
}

Not able to solve the media query issue (responsive design)

I tried the following code for making my page responsive, but still the elements are moving out. Can anyone lease have a look at it and help me out?
#media only screen and (max-width: 500px) {
.top-bar-section ul {
margin-top: 15px;
}
}
#media only screen and (min-width: 300px) and (max-width: 500px) {
.widget-area {
display: none;
}
.stat {
margin-bottom: 30px;
}
.clients-style-2 .slides li .client-logo {
margin-bottom: 5px;
}
#clients .slides li .client-logo {
margin-bottom: 5px;
}
#icategories li {
margin-bottom: 10px;
}
}
Ref url: http://7drives.in/dsq/index.html
You have a YouTube video in an iframe, and that iframe has a hard coded width of 500px, so this will be a problem on narrower viewports.
CSS Tricks has one solution to this, jQuery below. There are other solutions for responsive iframes, I like that this is a simple drop fix which doesn't require any changes to your HTML, and also that it resizes both the width and the height of your video.
Hope this helps!
// By Chris Coyier & tweaked by Mathias Bynens
$(function() {
// Find all YouTube videos
var $allVideos = $("iframe[src^='http://www.youtube.com']"),
// The element that is fluid width
$fluidEl = $("body");
// Figure out and save aspect ratio for each video
$allVideos.each(function() {
$(this)
.data('aspectRatio', this.height / this.width)
// and remove the hard coded width/height
.removeAttr('height')
.removeAttr('width');
});
// When the window is resized
// (You'll probably want to debounce this)
$(window).resize(function() {
var newWidth = $fluidEl.width();
// Resize all videos according to their own aspect ratio
$allVideos.each(function() {
var $el = $(this);
$el
.width(newWidth)
.height(newWidth * $el.data('aspectRatio'));
});
// Kick off one resize to fix all videos on page load
}).resize();
});

Stylus: prevent media tag from interpreting strings

We have an interesting dilemma.
I have a PR open for the rupture project to namespace the functions it exports in order to add a no-conflict mode.
First the actors
There are two functions (or mixins) that are named landscape and portrait. The PR namespaces them to rupture-landscape and rupture-portrait. The #media mixin is used throughout.
And now the scene.
With some of the functions created by rupture, a string is assembled to be used with the media tag. The end result should be a normal css media query.
The problem lies with the stylus #media mixin. It seems to automatically attempt to interpret the string and expand any keywords that might exist in the scope.
Since both landscape and portrait are within scope when not using no-conflict-mode, when ever the #media tag is used with a composed string and orientation: portrait or orientation: landscape the result will prefix both the words portrait and landscape with rupture.
I've created a trivial example with a couple of attempts to fix the issue on codepen here.
Here is the code as well:
Stylus
$landscape = 'notlandscape'
$string = "only screen and (orientation landscape)"
$unquote = unquote($string)
$s = s($string)
.foo
// this is the main issue
#media $string
color: blue
These two are attempts to fix the issue
#media $unquote
color: blue
#media $s
color: blue
and the compiled result in CSS
#media only screen and (orientation: 'notlandscape') {
.foo {
color: #00f;
}
}
#media only screen and (orientation: 'notlandscape') {
.foo {
color: #00f;
}
}
#media only screen and (orientation: 'notlandscape') {
.foo {
color: #00f;
}
}
The actual desired output:
#media only screen and (orientation: landscape) {
.foo {
color: #00f;
}
}
Is there a way to prevent or circumvent this behavior?
You can try interpolation. The referenced #media page also has a section about Interpolations and variables that will provide more info and examples.
landscape = 'notlandscape'
$string = "only screen and (orientation landscape)"
.foo
#media ({$string})
color: blue
Live #codepen
Parenthesis are essential here. So it's not exactly desired output but it's still valid CSS. How to avoid that (or if it's necessary) depends on use case. One idea:
landscape = 'notlandscape'
$string = "orientation: landscape"
.foo
#media only screen and ({$string})
color: blue
Live #codepen

Responsive video player

I need a video player for responsive layout website which is developed by using bootstrap. That means when i do re-size the screen or viewing the page in different size screens the player should be automatically fit to the screen.
I had tried with jwplayer and flowplayer but it didn't work.
http://www.longtailvideo.com/support/forums/jw-player/setup-issues-and-embedding/24635/responsive-video-internet-explorer-100-widthheight
note: The player should be able to play the youtube videos....
Is there anyway to make jwplayer/flowplayer responsive?
Better version of Luka's answer:
$(window).resize(function() {
var $width = $("#holder").width();
var $height = $width/1.5;
jwplayer().resize($width,$height);
});
User the resize function from the JW Player API:
http://www.longtailvideo.com/support/jw-player/29411/resizing-the-player
Another solution:
Check their Responsive Design Support documentation: http://www.longtailvideo.com/support/jw-player/32427/responsive-design-support
<div id="myElement"></div>
<script>
jwplayer("myElement").setup({
file: "/uploads/myVideo.mp4",
image: "/uploads/myPoster.jpg",
width: "100%",
aspectratio: "12:5" // Set your image ratio here
});
</script>
you can change by simple css style
/* Video small screen */
.video {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
}
.video iframe,
.video object,
.video embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
I am using jQuery for resizing. #holder is your div where movie is positioned (#videocontainer).
Structure:
<div id="holder">
<div id="videocontainer"></div>
</div>
It takes #holder size and give it to #videocontainer. It works in ie9, ie8, ...
$(window).resize(function() {
var $width = $("#holder").width();
var $height = $width/1.5;
jwplayer("videocontainer").setup({
flashplayer: "jwplayer/player.swf",
file: "###.mp4",
width: $width,
height: $height,
image: "###.jpg"
});
});
Hope it helps!
Try FitVids: http://fitvidsjs.com/
If you want to make jwPlayer responsive, try adding this to your CSS file:
#video-jwplayer_wrapper {
position: relative;
padding-bottom: 56.25%; /* 16:9 format */
padding-top: 30px;
height: 0;
overflow: hidden;
}
#video-jwplayer_wrapper iframe, #video-jwplayer_wrapper object, #video-jwplayer_wrapper embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
source: http://webdesignerwall.com/tutorials/css-elastic-videos
When calling jwplayer, you might also need to set width to 100%:
jwplayer("myElement").setup({
width: 100%
});
The easiest way is to use javascript
function sizing() {
$('#player').css('width', $('#container').outerWidth());
$('#player').css('height',$('#player').outerWidth() / 1.33);
}
$(document).ready(sizing);
$(window).resize(sizing);
Don't forget to include jquery library and to change the aspect ration (1.33 is for 4:3, 1,77 is for 16:9).
This work well for me
JW Player goes here
<script type="text/javascript">
if($( window ).width() <= 400){
pl_width = 300;
pl_heith = 150;
}else if($( window ).width() <= 600){
pl_width = 500;
pl_heith = 250;
}else{
pl_width = 700;
pl_heith = 350;
}
//alert(pl_width);
jwplayer("video_top").setup({
flashplayer: "<?php echo $player_path; ?>",
file: "<?php echo $your_file; ?>",
controlbar: "bottom",
height:pl_heith,
width:pl_width
});
You can just use YouTube videos in your site and use the FitVid.Js plugin to make it responsive.

Resources