What I am trying to do is create this in Qml (w/o using any images):
Specification
It is a button that has:
a linear gradient as background
two borders
each has a width of 1px
the colors have an alpha, so the background will effect the actual visible color of each pixel
the outer border is above the general background of the application
the inner border is above the gradient
the colors of the inner and outer border of the left side is interchanged compared to the bottom and right border (i.e. color of inner border left = color of outer border bottom, etc.)
on the bottom left and bottom right (but not on the top!) there is a 3px radius
In CSS (the reference implementation is a browser single-page application) it is done with this code:
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
box-shadow: rgba(152, 182, 219, 0.15) 0px 0px inset, rgba(2, 2, 4, 0.4) -1px 0px inset, rgba(2, 2, 4, 0.4) 0px -1px inset, rgba(152, 182, 219, 0.15) 1px 0px inset;
background: linear-gradient(rgb(47, 72, 99) 30%, rgb(36, 51, 71) 100%) padding-box;
border-bottom: 1px solid rgba(152, 182, 219, 0.15);
border-left: 1px solid rgba(2, 2, 4, 0.4);
border-right: 1px solid rgba(152, 182, 219, 0.15)
I am having trouble recreating this in Qml. As the radius property of the rectangle can only be set equal for all corners, I followed the idea mentioned in https://stackoverflow.com/a/39971599 . The result without using borders looks like this:
no borders
And this is the code I use for it:
Button {
id: headerConfigButton
// ...
background: Rectangle {
color: "transparent"
Rectangle {
height: headerConfigButton.height - headerConfigButtonLowerBackground.radius
width: headerConfigButton.width
}
Rectangle {
id: headerConfigButtonLowerBackground
radius: 3
height: headerConfigButton.height
width: headerConfigButton.width
color: "#242e3a"
}
LinearGradient {
source: parent
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(0, parent.height)
gradient: Gradient {
GradientStop {
position: 0.0
color: "#344a62"
}
GradientStop {
position: 1.0
color: "#293749"
}
}
}
}
}
Applying the borders was a little clumsy - I made a rectangle ("1px line") for each side and each border. Without the radius it looks like as in this picture:
no radius
Please note that the alpha values of the borders are not respected in this imgage; I found it easier to see what happens without using them.
The code for this:
Button {
id: headerConfigButton
// ...
background: Rectangle {
color: "transparent"
Rectangle { // left outer border
width: 1
height: headerConfigButton.height
color: "#181e26"
}
Rectangle { // left inner border
x: 1
width: 1
height: headerConfigButton.height - 1
color: "#4d637d"
}
Rectangle { // bottom outer border
x: 1
y: headerConfigButton.height - 1
width: headerConfigButton.width - 2
height: 1
color: "#344151"
}
Rectangle { // bottom inner border
x: 2
y: headerConfigButton.height - 2
width: headerConfigButton.width - 4
height: 1
color: "#181e26"
}
Rectangle { // right inner border
x: headerConfigButton.width - 2
width: 1
height: headerConfigButton.height - 1
color: "#181e26"
}
Rectangle { // right outer border
x: headerConfigButton.width - 1
width: 1
height: headerConfigButton.height
color: "#344151"
}
Rectangle { // gradient fill
id: headerConfigButtonGradientFill
x: 2
width: headerConfigButton.width - 4
height: headerConfigButton.height - 2
LinearGradient {
source: parent
anchors.fill: parent
start: Qt.point(0, 0)
end: Qt.point(0, parent.height)
gradient: Gradient {
GradientStop {
position: 0.0
color: "#344a62"
}
GradientStop {
position: 1.0
color: "#293749"
}
}
}
}
}
}
But now I struggle to create the round corners in conjunction with the borders. One issue is that the color of the outer and inner borders are not the same on each side. In conjunction with the opacity of the border colors, I have no idea how to get the colors in the corners right. Additionally, the gradient needs to be cropped as well.
The colors of the gradient and borders shall be themeable later on. Thus, using a background image or recreating the corners pixel by pixel with fixed colors taken from the spec is not an option.
Has anyone got an idea how to solve this? Maybe I am completely off and there is a much better and easier way to do this?
Thanks in advance!
Related
On my project, users have the possibility to select an accent color for their profile page (var(--color-main)). Is there a possibility to create a gradient background using only that main color, for example by using the main color + a % applied to this color to make it darker (or lighter) and use this as second color to make the gradient. Is that possible?
.TabsHeader-module--wrapper--BMiDm .TabsHeader-module--bgBlock--qXkLH {
background-color: var(--color-main);
border-radius: 0 0 20rem 0;
height: 21.6rem;
position: absolute;
top: 0;
width: 100%;
}
This is an example with two custom properties defined:
--color is your main color
--alpha is the opacity quota (0-1) applied to --color for having the second gradient color
The background-image style attribute is set using a gradient shading from --color to --color(alpha)
That was made possible with rgba to define colors MDN
:root {
--color: 240, 0, 0;
--alpha: .5;
}
.gradient{
background-image:
linear-gradient(
to right,
rgba(var(--color), 1),
rgba(var(--color), var(--alpha))
);
width: 100%;
height: 200px;
text-align: center;
}
<div class="gradient"></div>
I have found that you can use variable colors with opacity control only if you give the value as RGB decimals, which are 3 numbers (e.g. 240, 240, 240). And later you can give it a 4th value, which will control the opacity of the color (i.e. will make it darker or lighter).
Here is an example:
:root {
--color: 190,190,190;
}
div {
background: linear-gradient(to right, rgba(var(--color), 0.8), rgba(var(--color), 0.3));
}
Thanks to Thankful Teira from codegrepper.com
I have a rectangle of white color whose top and bottom should be at 20% opacity, sort of a faded effect. I tried gradient property by using hexadecimal values, tried Qt.rgba() but there seems to be no effect. Is there something I am doing wrong or is there any other way?
A minimal code is as follows:
Rectangle{
width: 400
height: 400
gradient: Gradient{
GradientStop{ position : 0 ; color: "#33FFFFFF" }
GradientStop{ position : 0.4;color: "#FFFFFFFF"}
GradientStop { position : 0.8 ; color: "#33FFFFFF"}
}
}
Based on your edit, I think your gradient is backwards. You want opacity of 0 in the middle and 100% at the top and bottom. And then you want to use that Rectangle as an overlay on top of your text. I would make it something like this:
Rectangle{
width: 400
height: 400
gradient: Gradient{
GradientStop{ position : 0.0; color: "#FFFFFFFF" }
GradientStop{ position : 0.2; color: "#33FFFFFF" }
GradientStop{ position : 0.4; color: "#00FFFFFF"}
GradientStop{ position : 0.6; color: "#00FFFFFF"}
GradientStop{ position : 0.8; color: "#33FFFFFF"}
GradientStop{ position : 1.0; color: "#FFFFFFFF"}
}
}
The following is my HTML markup where I add the title as a prop for Bootstrap card. I've tried z-index as well, but I wasn't able to achieve the desired result.
<b-col>
<div class="card-container">
<b-card
overlay
img-src="/images/ajm.jpg"
img-alt="Card Image"
class="product-card"
title="Linear Motors"
title-tag="h5"
align="center"
></b-card>
</div>
</b-col>
CSS ----->
.product-card {
height: 353px;
border-radius: 0px;
border: 0;
color: #0c1c35;
}
.card-container {
width: 100%;
height: 100%;
:hover {
background: -webkit-linear-gradient(
90deg,
hsla(217, 100%, 50%, 1) 0%,
hsla(186, 100%, 69%, 1) 100%
);
opacity: 0.8;
color: white;
}
}
Another thought I had was that the opacity field actually effects child elements as explained in w3 schools:
If you do not want to apply opacity to child elements, like in our example above, use RGBA color values. The following example sets the opacity for the background color and not the text:
From seeing your CSS I see you're using opacity, so this might work if you use the RGBA - CSS.
.card-container {
background-color: rgba(255, 255, 255, 0.5);
}
Hope this helps
I'm attempting to style the borders of my context menus in JavaFX with CSS.
The Problem
I want a 1 pixel, solid black line as the border of the context menu. Instead, I'm getting a 2 pixel, solid black line as the border of the context menu.
Here are two images showing the pixel border.
100%
1000%
Clearly, there are 2 pixels being rendered instead of 1 pixel for the border.
CSS
I'm setting the border with the following CSS:
.context-menu {
-fx-skin: "com.sun.javafx.scene.control.skin.ContextMenuSkin";
-fx-background-color: red;
-fx-background-radius: 0;
-fx-background-insets: 0;
-fx-effect: null;
-fx-border-width: 1; /* I also tried 1px here */
-fx-border-color: black;
-fx-border-style: solid outside line-cap square;
-fx-padding: 0;
}
I also set the child nodes to transparent borders and backgrounds just to rule out that they were responsible:
.context-menu .menu-item,
.context-menu .menu-item .label {
-fx-background-color: transparent;
-fx-border-color: transparent;
}
Question(s)
Why am I getting a 2 pixel border, instead of a 1 pixel border?
How can I get a 1 pixel border, instead of this 2 pixel border?
There are a couple of answers already on StackOverflow that explain why the strokes can't seem to render a 1px border all of the time:
JavaFX graphics “blurred” or anti-aliased? (No effects used)
What are a line's exact dimensions in JavaFX 2?
The best workaround I've found for this issue is to not use borders at all. Instead, I use multiple backgrounds and -fx-background-insets to simulate a border:
.context-menu {
-fx-skin: "com.sun.javafx.scene.control.skin.ContextMenuSkin";
-fx-background-color: black, red;
-fx-background-insets: 0, 1;
}
That's all it takes for a clean, 1 pixel, hard border
<style>
* {
background: red;
}
.blackbalk{
background:black;
ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=85)";
filter:alpha(opacity=85);
-khtml-opacity:.85;
-moz-opacity:.85;
opacity:.85;
width: 985px;
margin: 0 auto;
height:255px;
color: white;
}
</style>
<div class="blackbalk">Text </div>
Now my text gets pink, why?
How can i get it white again?
Greetings
Edit: JS Fiddle to make it clear: http://jsfiddle.net/WFxbH/
You can do it by instead using an rgba background on your element:
Live Demo - this will work "in every browser you care about", and my jsFiddle includes the recommended IE conditional comment to make it also work in that browser.
.blackbalk {
/* Fallback for web browsers that doesn't support RGBa */
background: rgb(0, 0, 0);
/* RGBa with 0.6 opacity */
background: rgba(0, 0, 0, 0.85);
/* For IE 5.5 - 7*/
filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#D8000000, endColorstr=#D8000000);
/* For IE 8*/
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#D8000000, endColorstr=#D8000000)";
}
Thew, opacity affects the entire element and its contents, not just the background color. If you just want the background color to be 85% black, you should specifiy it with an RGBA color, like so:
.blackbalk {
background: rgba(0, 0, 0, 0.85);
width: 985px;
margin: 0 auto;
height: 255px;
color: white;
}
EDIT: cant over ride the cascading of opacity. Best alternative in my pinion is to use a single pixel 85% opacity black png as the background image. option 2 would be to make the inner content actually outside of the div then position it over but that's a lot finickier. You can even get the transparent png to work in IE without much trouble.
IGNORE:Not positive, as I can't test it right now but I assume the text is becoming translucent with the opacity change. Perhaps if you put your text inside a span with background-color:none and color:white; it might work it out. May have to set the spans opacity to 100% to override.