Media Queries
On this page
Media queries are a great feature that allows for the development of responsive user interfaces. Certain CSS styles will be enabled/disabled according to the current properties of the Cohtml View - the width
and the height
. Through media queries, UI designers can radically change how the user interface looks on certain resolutions, or when a handheld device is in portrait/landscape mode. Designers can opt for high-resolution images on powerful devices while going for low-res on less capable ones - all within the same UI.
Prysm supports part of version 3 of the Media Query standard, namely the following media features:
aspect-ratio
,min-aspect-ratio
,max-aspect-ratio
min-height
,max-height
min-width
,max-width
orientation
You can learn more about media queries here.
The expressions in the media query use the Width and Height of the View to evaluate.
.mybutton
{
background-color: red;
}
// Media expression - CSS rules will be activated if the expression in the media rules is true
@media (min-width: 1280px)
{
.mybutton
{
background-color: blue;
}
}
The example above shows a simple media query. All DOM elements with the class mybutton
will by default be red
, however, if the width
of the View is above 1280px, the media query rules will take effect and the color will change to blue
. If the width
shrinks below 1280px, the media rules will again get disabled and the elements revert to being red
.
Size-related expressions that Prysm supports include min-width,max-width,min-height, max-height, orientation. You can also chain multiple expressions with the and
operator.
The orientation expression supports the values landscape and portrait and can be used to alter the UI design depending on the width
/height
ratio of the View.
Nesting of media queries
Additionally Prysm supports CSS Conditional Rules Module Level 3 which allows nesting of at-rules
within a media query. Ordering of at-rules
within nested medias is not well supported at the moment, therefore developers should always put their nested medias at the end of their stylesheets.
Example:
@media(min-width: 500px) {
@keyframes anim {
0% {
transform: scale(1) rotate(0deg);
background-color: #3498db;
}
100% {
transform: scale(1) rotate(360deg);
background-color: #3498db;
}
}
}
@keyframes anim {
0% {
background-color: indianred;
}
100% {
background-color: navajowhite;
}
}
The second anim
should override the one defined inside the @media
rule but it does not. Putting the nested @media
at the end works as expected:
@keyframes anim {
0% {
background-color: indianred;
}
100% {
background-color: navajowhite;
}
}
div {
animation: anim 2s infinite;
}
@media(min-width: 500px) {
@keyframes anim {
0% {
transform: scale(1) rotate(0deg);
background-color: #3498db;
}
100% {
transform: scale(1) rotate(360deg);
background-color: #3498db;
}
}
}
Custom media features
Additionally we allow for custom media features to be part of the media query and to be enabled trough a C++ API.
@media (myFeature: myValue) {
.mybutton {
background-color: green;
}
}
The example above shows a custom media feature being defined in the query. This feature will be evaluated as false by default and the rules defined in the media query won’t be applied until the feature is enabled through the C++ API.
bool View::SetCustomMediaFeature(const char* name, const char* value);
The custom media feature name and value should adhere to the same naming conventions as CSS selectors. They are case-insensitive if they contain only ASCII symbols.
You cannot enter nullptr
for the feature name. The method returns a flag to let you know if the operation was executed successfully.
These queries are evaluated following the standard rules for media query expressions. Designers can use multiple values per feature name.
@media (language: en) {
.mybutton {
background-color: red;
}
}
@media (language: de) {
.mybutton {
background-color: yellow;
}
}
Multiple values concerning one feature are mutually exclusive and cannot be active at the same time. This means that if (language: en)
is enabled then (language: de)
will be disabled and vice-versa. These are persisted per view and for it’s lifetime, so refreshing the page or loading other pages will not reset them.
Adding a feature with no value through CSS will be considered enabled by default
@media (enabled) {
.mybutton {
background-color: red;
}
}
This will consider enabled
to be true, until you disable it.
Disabling a feature can be accomplished using
View->SetCustomMediaFeature("myFeature", nullptr);
This will cause the feature to always evaluate to false and will disable all previously applied rules inside the media query.
There’s also a method for disabling all media features at once.
void View::ResetCustomMediaFeatures()
The custom media features can be used to add whole css files conditionally as well.
<link rel="stylesheet" media="(myFeature: myValue)" href="your.css" />
You can mix standard features with custom ones like:
@media (language: en) and (max-width: 300px) {
font-size: 50px;
}
Using dynamic-range
, color-gamut
and color
as names for the custom features is accepted but note that the accepted values are high
and standard
for dynamic-range
. For color-gamut
they are srgb
, p3
and rec2020
. And for color
- characters for floating point numbers. Feature names min-color
and max-color
are not allowed. Using the API like so will result in failure and a message will be outputted.
myView->SetCustomMediaFeature('dynamic-range', 'myVal');
For the following css
@media (dynamic-range: high) {
div {
background-color: red;
}
}
@media (dynamic-range: standard) {
div {
width: 300px;
}
}
if there’s a custom feature named dynamic-range
that was set through the C++ API using high
as it’s value then both rules will match. If it’s overridden with the value standard
then only the second rule will match. This is consistent with the the behavior described in the standard.
The behavior of color-gamut
is also compliant with the HTML spec.
min-color
and max-color
may be used normally in the css and they will be matched based upon the color
custom media feature’s value
@media(min-color: 2) {
...
}
@media(max-color: 7) {
...
}
if a custom media feature has been enabled like so
myView->SetCustomMediaFeature('color', '7');
then both rules are matched as color
is set to be at most 7. The same is true for rules such as
@media(color >= 2) {
...
}
Whether the rule matches will depend on the value of the color
custom media feature that you have set.
Enabling or disabling custom features will cause a full style recalculation of the page.