How to make two-coloured stripe using CSS? - html

I want to make the following stripe. What is the right way of doing that?

Looks like you are looking for gradients. This is typically used when you want to style with multiple colors.
Gradients are displayed by default vertically. To display it horizontally, we need to use the optional direction parameter. In this case, it is to right.
I can't make out what the colors used in the image are, but they look like darkgreen and lime.
#colored {
background: linear-gradient(to right, DarkGreen 70%, lime);
width: 100%;
height: 50px;
}
<div id="colored"></div>

Alternately, you can use a gradient:
var progress = document.getElementById('progress');
var complete = 0;
var c1 = '#75ae2c', c2 = '#9dd156';
var timer = setTimeout(function loop() {
var bg = 'linear-gradient(to right, ' + c1 + ' 0%,' + c1 + ' ' + complete + '%,' + c2 + ' ' + complete + '%,' + c2 + ' 100%)';
progress.style.background = bg;
progress.innerHTML = 'Process is ' + complete + '% complete';
complete++;
if (complete <= 100) setTimeout(loop, 100);
}, 0);
#progress {
padding: 10px;
width: 200px;
text-align: center;
}
<div id="progress">
</div>
It is a tiny bit more complex, but the advantage over div-inside-div is that it doesn't interfere with the content.

All you need is a short div with darker color inside another with lighter color.
That's how Bootstrap implement its progress bar.
HTML:
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="70" aria-valuemin="0" aria-valuemax="100" style="width:70%">
<span class="sr-only">70% Complete</span>
</div>
</div>
CSS:
.progress {
height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
}

Have a div with 2 div's inside
HTML:
<div class="stripe">
<div class="stripe-left"></div>
<div class="stripe-right"></div>
</div>
CSS
.stripe {
height: 20px;
width: 200px;
}
.stripe-left {
display: inline-block;
height: 100%;
width: 60%;
background-color: red;
}
.stripe-right {
display: inline-block;
height: 100%;
width: 40%;
background-color: blue;
}

Related

SCSS - Conditional include not working and all the blocks gets executed

I am trying to do conditional include in scss. Here is the code:
HTML
<div class="test" data-active data-label data-comment >1</div>
<div class="test" data-active data-label>2</div>
<div class="test" data-active data-comment >3</div>
<div class="test" data-active data-comment data-label>4</div>
<div class="test" data-active>5</div>
SCSS
.test[data-active]{
background : red;
width: 50px;
height: 50px;
display: inline-block;
$margin: 0px;
&[data-label]{
background : blue;
$margin: $margin + 10px;
}
&[data-comment]{
background: yellow;
$margin: $margin + 10px;
}
&[something]{
$margin: $margin + 100px;
}
margin-right : $margin;
}
Here is the codepen link: https://codepen.io/gaurav-neema/pen/VwpPBxY
In the code, you can see that even if the element does not contain the attribute, all the blocks get executed and the margin is included.
Can anyone help in indentifying what's wrong with the code?
You are redefining $margin every time, you cannot use selectors like if statements.
Redefining with:
$margin: $margin + 10px;
$margin: $margin + 100px;
You are setting all margin-right: 100px;
I think you might want:
SCSS
$margin: 0px;
.test[data-active] {
background: red;
width: 50px;
height: 50px;
display: inline-block;
&[data-label] {
background : blue;
margin: $margin + 10px;
}
&[data-comment] {
background: yellow;
margin: $margin + 10px;
}
&[something] {
margin: $margin + 100px;
}
margin-right: $margin;
}
What you are looking for is CSS custom properties. SCSS is not dynamic and there for renders at compile. CSS custom properties are dynamic so they get applied once the condition is for filled, meaning when your class is applied it will change the value then.
Read about the difference at:
css-tricks.com
Read about CSS custom properties at:
MDN
ishadeed.com
daverupert.com
This is just 3 of so many articles about the subject.
Now demo time, I changed the property to be background-color to make it more clear for the demo.
.test[data-active] {
--background-color: aqua;
background: var(--background-color);
width: 50px;
height: 50px;
display: inline-block;
}
.test[data-label] {
--background-color: deeppink;
}
.test[data-something] {
--background-color: deepskyblue;
}
<div class="test" data-active data-label data-comment>1</div>
<div class="test" data-active data-label>2</div>
<div class="test" data-active data-comment>3</div>
<div class="test" data-active data-comment data-label>4</div>
<div class="test" data-active data-something>5</div>

CSS Conditional Formatting with a colour range

I am looking to create a basic chart using divs and spans and want to apply conditional formatting to each column in the chart depending on the value setting its height. The trick which I haven't been able to crack is that I want to have it function a bit like Excel conditional formatting in the example here:
Where the colours are in a range (light to dark).
Is there a simple way of doing this? I can see how I could apply static values to static colours but was hoping I could do something with colour ranges like this excel example.
So, the below screenshot shows a column chart where each column has a different shade of orange determined by the value of the column:
The closer to 25 the column is, the darker the colour.. Like-wise, the lower the value, the lighter the shade of orange is.
It sounds like your goal is to color a bar somewhere between two colors depending on a value. If that's the case, you can use css animations to simulate the color gradient.
The idea is this:
Set up an animation setting the background to be one of two colors. This effectively calculates a gradient between the two colors. You do this with #keyframes and animation.
Pause the animation, since we don't want it to actually play. This is done with animation-play-state.
Select a specific frame in the animation to get the correct in-between color. This can be done with a negative animation-delay.
.bars {
display: flex;
justify-content: space-evenly;
}
.bar {
animation: color-gradient 25s linear 1;
animation-fill-mode: forwards;
animation-play-state: paused;
width: 3em;
}
#keyframes color-gradient {
from { background: red; }
to { background: blue; }
}
<div class="bars">
<div class="bar" style="height: 5em; animation-delay: -5s;"></div>
<div class="bar" style="height: 10em; animation-delay: -10s;"></div>
<div class="bar" style="height: 15em; animation-delay: -15s;"></div>
<div class="bar" style="height: 20em; animation-delay: -20s;"></div>
<div class="bar" style="height: 25em; animation-delay: -25s;"></div>
</div>
The granularity can be adjusted by making the animation duration longer than 25 seconds if need be.
I am going to provide two options and maybe you can provide some more details based on these on exactly what you need.
This first one may not be what you want as it sets a specific gradient based on a specific height. Only going to provide a Codepen for this one. https://codepen.io/jfirestorm44/pen/yLMNPPM?editors=1100
This next one is more of what I think you want. If you know the max height of the bar graph you can use that to set the gradient breaks on your linear-gradient.
UPDATED:
HTML
<div id="container">
<div id="first" class="bar"></div>
<div id="second" class="bar"></div>
<div id="third" class="bar"></div>
<div id="fourth" class="bar"></div>
<div id="fifth" class="bar"></div>
</div>
SCSS
.bar {
#for $i from 1 through 5 {
$height: 20px * $i;
$light: 75% + $i * -5;
&:nth-child(#{$i}) {
position: absolute;
bottom: 50%;
left: 20% + ($i * 10%);
width: 20px;
height: $height;
font-size: 25px;
transform: translate(-80%, 0);
background: hsl(35, 100%, $light);
}
}
}
Updated Codepen: https://codepen.io/jfirestorm44/pen/jOBPopj?editors=1100
ADDING a JS Option:
let inputNum = document.getElementById("number");
let button1 = document.getElementById("button1");
let border = document.getElementById("border");
let dropDown = document.getElementById("cars");
function color() {
if (inputNum.value > 0) {
let bar = document.createElement("div");
bar.classList.add("bar");
border.appendChild(bar);
let bars = document.getElementsByClassName("bar");
let carName = document.createElement("p");
carName.classList.add("carType");
carName.textContent = cars.options[cars.selectedIndex].text;
border.appendChild(carName);
let names = document.getElementsByClassName("carType");
let height = inputNum.value * 26;
for (let i = 0; i < bars.length; i++) {
names[names.length - 1].style.top = "275px";
names[names.length - 1].style.left = -5 + i * 30 + "px";
bars[bars.length - 1].style.height = height + "px";
bars[bars.length - 1].style.backgroundColor =
"hsl(35, 100%," + (75 - height / 5.2) + "%)";
bars[bars.length - 1].style.left = 10 + i * 30 + "px";
}
}
}
#container {
position: absolute;
top: 40px;
left: 0;
width: 400px;
height: 300px;
}
#border {
position: relative;
left: 100%;
top: 0;
width: 90%;
height: 90%;
border-left: 2px solid grey;
border-bottom: 2px solid grey;
transform: translate(-100%, 0);
}
#numberContainer {
position: relative;
left: -5%;
}
.num {
line-height: 10px;
}
.num:before {
content: "";
position: absolute;
left: 18px;
width: 100%;
height: 10px;
border-bottom: 1px lightgrey solid;
}
.bar {
position: absolute;
bottom: 0;
width: 20px;
}
#button1 {
position: relative;
top: 0;
width: 60px;
height: 20px;
}
.car {
position: absolute;
top: 10px;
}
.carType {
position: absolute;
bottom: -85px;
writing-mode: vertical-rl;
text-orientation: upright;
}
<div id="container">
<div id="border">
<div id="numberContainer">
<p class="num">10</p>
<p class="num">9</p>
<p class="num">8</p>
<p class="num">7</p>
<p class="num">6</p>
<p class="num">5</p>
<p class="num">4</p>
<p class="num">3</p>
<p class="num">2</p>
<p class="num">1</p>
<p class="num">0</p>
</div>
</div>
</div>
<input type="number" min="0" max="10" value="0" id="number"/>
<label for="cars">Choose a car:</label>
<select name="cars" id="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
<button type="button" onclick="color()" id="button1">Submit</button>
[edit] This answer only colors the bars from left to right, having the lightest color to the left.
I would let the container have a white background and the bars to be black, and then add a gradient over everything, with help of a pseudo-element that have set mixed-blend-mode: lighten to only colorize the black bars.
As a bonus, I added another pseudo-element with a repeating linear gradient consisting of a really light grey to create the horizontal lines. I then added mixed-blend-mode: darken to this element to make them appear "under" the bars.
I also randomized the height of the bars, by randomizing a CSS property for each bar.
This solution scales, so it doesn't matter how many bars you got, you still get a gradient over all the of bars without having to change the CSS code.
let bars = document.querySelectorAll('.bar');
function randomize(max, min) {
min = min || 0;
return Math.floor(Math.random() * (max - min) + min);
}
for (const bar of bars) {
bar.style.setProperty('--bar-height', `${randomize(10, 2)}rem`);
}
.container {
position: relative;
display: inline-flex;
margin-left: 4.5rem;
align-items: flex-end;
background-color: #fff;
padding: 0px 1rem;
}
.container::before,
.container::after {
content: '';
position: absolute;
top: 0px;
bottom: 0px;
left: 0px;
right: 0px;
}
.container::before {
background: linear-gradient(to right, #fbe5d6, #843c0c);
mix-blend-mode: lighten;
}
.container::after {
background: repeating-linear-gradient(to top, #f4f1f1, #f4f1f1 1px, transparent 1px, transparent 1rem);
z-index: 10;
mix-blend-mode: darken;
}
.bar {
width: 1.5rem;
height: var(--bar-height);
background-color: #000;
}
.bar + .bar {
margin-left: 3rem;
}
<div class="container">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
Using a combination of my and Justin's answers, but for vanilla CSS.
This answer is using HSL and CSS variables to set the color and the height.
Randomized values
let bars = document.querySelectorAll('.bar');
function randomize(max, min) {
min = min || 0;
return Math.floor(Math.random() * (max - min) + min);
}
for (const bar of bars) {
let maxValue = 25;
let randomValue = randomize(maxValue, 2);
let height = randomValue/2;
let hue = '24deg';
let saturation = '82%';
let maxHue = 90;
let minHue = 30;
let hueRange = maxHue - minHue;
let lightness = `${maxHue - hueRange * (randomValue/maxValue)}%`;
bar.style.setProperty('--bar-height', `${height}rem`);
bar.style.setProperty('--color-background-bar', `hsl(${hue}, ${saturation}, ${lightness})`);
}
.container {
display: inline-flex;
margin-left: 4.5rem;
align-items: flex-end;
padding: 0px 1rem;
background: repeating-linear-gradient(to top, #eee, #eee 1px, transparent 1px, transparent 1rem);
}
.bar {
width: 1.5rem;
height: var(--bar-height);
background-color: var(--color-background-bar);
}
.bar + .bar {
margin-left: 3rem;
}
<div class="container">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>
Increasing values
Static values ranging from 5 to 25, as seen in the OP's pic.
let bars = document.querySelectorAll('.bar');
bars.forEach((bar, index) => {
let maxValue = 25;
let customValue = 5 + index * 5;
let height = customValue/2;
let hue = '24deg';
let saturation = '82%';
let maxHue = 90;
let minHue = 30;
let hueRange = maxHue - minHue;
let lightness = `${maxHue - hueRange * (customValue/maxValue)}%`;
bar.style.setProperty('--bar-height', `${height}rem`);
bar.style.setProperty('--color-background-bar', `hsl(${hue}, ${saturation}, ${lightness})`);
});
.container {
display: inline-flex;
margin-left: 4.5rem;
align-items: flex-end;
padding: 0px 1rem;
background: repeating-linear-gradient(to top, #eee, #eee 1px, transparent 1px, transparent 1rem);
}
.bar {
width: 1.5rem;
height: var(--bar-height);
background-color: var(--color-background-bar);
}
.bar + .bar {
margin-left: 3rem;
}
<div class="container">
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
<div class="bar"></div>
</div>

Background larger than its container

I am trying to achieve this layout but I'm having problems with setting a background, which should be 50% of the screen size. I thought of setting up an image as background, but there are different colors that should be different on each page.
Is it possible to achieve it using only background-color?
This is how I set the HTML, TS & CSS so far:
<div [class]="getBackground(title)">
<div class="background-header">
<img [src]="'assets/assess/Custom.png'" alt="">
{{title}}
</div>
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide" *ngFor="let theme of pillar.data; let i = index">
<button rh-btn-theme full-btn [ngClass]="{'ripple': true}" [issue]="theme" (click)="presentModal($event, theme);"></button>
</div>
</div>
</div>
</div>
TS
getBackground(pillar) {
switch (pillar) {
case "People":
return "background-people";
case "Land":
return "background-land";
case "Crop":
return "background-crop";
case "Business":
return "background-business";
default:
return "background-custom";
}
}
CSS
.background-header {
width: 100%;
height: 80%;
display: block;
position: relative;
img {
display: inherit;
background-color: #000;
}
}
.background-people {
background-color: #335F6E;
}
.background-land {
background-color: #006533;
}
.background-crop {
background-color: #7F4020;
}
.background-business {
background-color: #F8DC0B;
}
.background-custom {
background-color: map-get($colors, primary);
}
Yes you can do it by background gradient:
.content {
width: 100%;
height: 300px;
border: solid 2px #123;
background: linear-gradient( red, red 50%, white 50%, white);
}
<div class='content'></div>
Dont forget genarte cross-browser css. See about background gradient here

Display custom message using CSS - alternate approach to Bootstrap modals

I want to display a custom message box that an item was added to the cart.I have tried using Bootstrap modals but would want to use CSS instead.The message box should slide from the header and display the message and then dissapear(similar to Bootstrap modals).
<div>
<button type="button" id="notifyProductName" ></button>
</div>
<script>
var display = document.getElementById("notifyProductName");
display.innerHTML = productName + " was added to cart";
</script>
I'm not sure but if you are looking for simple CSS animation.
If you are I think you can use 'transition' property.
Please try this HTML code:
<body>
<div id="popup-msg">
<h4>Product Notification</h4>
<button type="button" id="notifyProductName">OK</button>
</div>
<button onclick="popupMsg()">pop</button>
<script>
var popupMsg = function() {
document.getElementById("popup-msg").style['opacity'] = '1';
document.getElementById("popup-msg").style['top'] = '50px';
}
</script>
</body>
And CSS:
#popup-msg {
position: absolute;
top: -200px;
left: calc(50% - 200px);
width: 400px;
height: 200px;
padding: 10px;
border-style: solid;
border-color: lightgray;
border-width: 1px;
border-radius: 10px;
background-color: white;
box-shadow: 5px 5px 10px #AAAAAA;
opacity: 0;
transition: 0.25s;
}
When you change 'opacity' and 'top' properties from Javascript, it takes some time defined by 'transition' property.
You can make simple animation using this.
Here is my JS fiddle: https://jsfiddle.net/wiany11/07gks6x9/

How to do centered <h1> with <hr/> on both sides over a background image

How do I create centered <h1> with <hr/> on both sides over a background image?
I also need it to handle various text lengths, scale well for mobile viewing and have the <hr/> go to 100% width of its container.
I want this look, but over a background image.
There are lots of answers (here, here here and here) for text with lines on either side but all of them rely on using a solid background colour behind the text, which doesn't work for me as the page I want to put this on has a background image.
Here is how I achieve the look above, which handles various lengths of text and scales well:
CSS
.title-box {
height: 2px;
background-color: rgb(215, 0, 0);
text-align: center;
}
.title-outer {
background-color:rgb(230, 230, 230);
position: relative;
top: -0.7em;
}
.title-inner {
margin:0px 20px;
font-size: 17.5px;
font-weight:bold;
color:rgb(100, 100, 100);
}
HTML
<div class="title-box">
<span class="title-outer">
<span class="title-inner">OUR STORY</span>
</span>
</div>
I have tried the method below and it kind of works but it doesn't handle various text widths or scale well due to the <h1> and the <hr/>s being in seperate <div>s:
HTML
<div class="row">
<div class="span4"><hr /></div>
<div class="span4"><h4>OUR STORY</h4></div>
<div class="span4"><hr /></div>
</div>
Note: This is example is using the Bootstrap grid system but that is not part of the problem/solution.
So any ideas how I can get the same look and behaviour but without the backgound colour for the text so it can sit over a background image?
No need JS, here is a pure CSS solution.
CSS
.title-hr hr {
display: inline-block;
width: 30%;
margin: 5px 10px;
border-top: 1px solid #e5e5e5;
}
HTML
<h1 class="title-hr"><hr />My Title<hr /></h5>
Result: http://jsfiddle.net/yptmftr4/
Ok, I've played a bit with this code and here is my solution. Yes, it's a bit dirty because I've used :before and :after, but works.
HTML
<div class="title-box">
<span id="first" class="title-inner">OUR LOOOoo oooo oOONG STORY</span>
</div>
<div class="title-box">
<span id="second" class="title-inner">OUR STORY</span>
</div>
<div class="title-box">
<span id="third" class="title-inner">STORY</span>
</div>
CSS
.title-box {
text-align: center;
}
.title-inner {
margin:0px 20px;
font-size: 17.5px;
font-weight:bold;
position: relative;
color:rgb(100, 100, 100);
}
.title-inner:after, .title-inner:before {
content:"";
float: right;
position: relative;
top: 8px;
height: 2px;
background: red;
}
.title-inner:before {
float: left;
}
jQuery
$(document).ready(function () {
function work() {
$(".title-inner").each(function () {
var full_width = $(window).width();
var id = $(this).attr("id");
var title_width = $("#" + id).width();
var new_width = (full_width - title_width) / 2 - 40;
$('head').append("<style>#" + id + ":before, #" + id + ":after{width:" + new_width + "px !important;}</style>");
});
}
work();
$(window).resize(function () {
work();
});
});
http://jsfiddle.net/ffb3X/4/
Because :before and :after are not part of DOM, I've used .append() function to append style tags in head for every title.
This code will on page load calculate everything, so it's responsive.
This code was posted originally by Arbel but his/her answer disappeared for some reason? I am reposting it (including some mods I've made) because it was the solution I ended up using. Credit where credit is due.
Working jsFiddle: http://jsfiddle.net/pA5Gu/
HTML
<div class="title-box">
<fieldset class="title-outer">
<legend id="titleInner" class="title-inner">OUR STORY</legend>
</fieldset>
</div>
CSS
.title-box {
background-image: url('http://imagezo.com/images/1302-green-bubbles-awesome-background-wallpaper.jpg');
height:100%;
}
.title-outer {
border-top:2px solid rgb(215, 0, 0);
background-color: transparent;
}
.title-inner {
width:auto;
padding:0px 20px;
border: 0;
background-color: transparent;
font-size: 17.5px;
font-weight:bold;
color:rgb(255, 255, 255);
}
jQuery
$(document).ready(function() {
var legendWidth = $('#titleInner').outerWidth();
var margin = 'calc((100% - '+legendWidth+'px) / 2)';
$('#titleInner').css('margin-left', margin);
$('#titleInner').css('margin-right', margin);
});
http://jsfiddle.net/habo/HrfuH/1/
<div class="title-box">
<div class="myContent">
<div class="title-outer"><hr /></div>
<div class="title-inner "><h4>OUR STORY</h4></div>
<div class="title-outer"><hr /></div>
</div>
</div>
.myContent{
display:block;
width:600px;
margin:0 auto;
}
.title-box {
background:#eee;
height:60px;
}
.title-outer{
}
hr {
height: 2px;
background-color:rgb(215, 0, 0);
margin: 2em 0;
width:25%;
float:left;
}
.title-inner {
margin:0px 20px;
font-size: 17.5px;
font-weight:bold;
color:rgb(100, 100, 100);
float:left;
}