Create Chevron with border in AgularJS [duplicate] - css

This question already has answers here:
CSS triangle custom border color
(5 answers)
Closed 5 years ago.
I am using below example to create a chevron but I am not able to create a black border around each chevron.
http://jsfiddle.net/Ez6Q3/25/
HTML:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script>
<div class="well">
Click the chevrons to see the different colors.
</div>
<div ng-controller="MyCtrl">
<progressbar steps="steps.all"></progressbar>
</div>
CSS:
body {
font-family: Arial, Helvetica, sans-serif;
font-weight: normal;
-webkit-font-smoothing: antialiased;
}
h1 {
font-size: 12pt;
}
div.chevrons {
text-align: center;
}
ul.chevrons {
font-size: xx-large;
margin-bottom: 1em;
padding: 0;
margin: 0;
list-style: none;
overflow: hidden;
display: inline;
}
ul.chevrons li:last-child {
border-color: red;
}
ul.chevrons li {
height: 40px;
width: 160px;
font-size: 15px;
display: inline-block;
font-weight: bold;
margin-left: -10px;
}
ul.chevrons li:first-child {
margin-left: 0px;
}
/* adjust the first item to not have a chevron on the left
.chevrons li:first-child:before {
border:none
}*/
/*
adjust the last arrow to have no arrow on the right hand side
.chevrons li:last-child:after {
border:none
}
*/
ul.chevrons li:before {
content: "";
border-top: 20px solid #309dd4;
border-bottom: 20px solid #309dd4;
border-left: 10px solid transparent;
height: 0;
position: absolute;
}
ul.chevrons li:after {
content: '';
border-top: 20px solid transparent;
border-bottom: 20px solid transparent;
border-right: 10px solid transparent;
border-left: 10px solid #309dd4;
height: 0;
position: absolute;
}
ul.chevrons li span {
padding-top: 10px;
background: #309dd4;
text-align: center;
margin-left: 10px;
height: 40px;
width: 130px;
padding-left: 10px;
padding-right: 10px;
display: inline-block;
}
ul.chevrons li.success a {
color: #ffffff;
}
ul.chevrons li.success span {
background: #67b646;
}
ul.chevrons li.success:after {
border-left: 10px solid #67b646;
}
ul.chevrons li.success:before {
border-top: 20px solid #67b646;
border-bottom: 20px solid #67b646;
}
ul.chevrons li.failure a {
color: #ffffff;
}
ul.chevrons li.failure span {
background: #b84c4c;
}
ul.chevrons li.failure:after {
border-left: 10px solid #b84c4c;
}
ul.chevrons li.failure:before {
border-top: 20px solid #b84c4c;
border-bottom: 20px solid #b84c4c;
}
ul.chevrons li.inprogress a {
color: #ffffff;
}
ul.chevrons li.inprogress span {
background: #e8ca2b;
}
ul.chevrons li.inprogress:after {
border-left: 10px solid #e8ca2b;
}
ul.chevrons li.inprogress:before {
border-top: 20px solid #e8ca2b;
border-bottom: 20px solid #e8ca2b;
}
ul.chevrons a {
color: #ffffff;
}
Angular Script:
angular.module('myApp', ['frolicProgress']).controller('MyCtrl', function ($scope, ProgressSteps) {
$scope.steps = new ProgressSteps($scope)
$scope.$on('progress:step:clicked', function (event, step) {
if (step.operation == 'query') step.status = 'inprogress';
if (step.operation == 'transform') step.status = 'failure';
if (step.operation == 'visualize') step.status = 'success';
});
});
angular.module('frolicProgress', []).directive('progressbar', function () {
var dir;
dir = {
restrict: "E",
template: "<div class='chevrons'>\n<ul class='chevrons'>\n<li ng-class='step.status' ng-repeat='step in _steps'><span><a ng-click=\"operationClicked(step)\" href=\"#\" ng-bind=\"step.title\"/></span></li>\n </ul></div>",
replace: true,
scope: {
_steps: "=steps",
_state: "=state"
},
link: function (scope, element) {
var bar;
bar = angular.element(element.children());
scope.operationClicked = function (step) {
return scope.$emit('progress:step:clicked', step);
};
}
};
return dir;
}).factory('ProgressSteps', function () {
var ProgressSteps;
return ProgressSteps = (function () {
function ProgressSteps($scope) {
this.add('query', 'Query');
this.add('transform', 'Transform');
this.add('visualize', 'Visualize');
$scope.$on('easel:progress:query:started');
}
ProgressSteps.prototype.all = [];
ProgressSteps.prototype.add = function (operation, title) {
return this.all.push({
operation: operation,
title: title,
status: null
});
};
ProgressSteps.prototype.inprogress = function (operation) {
return this.updateStatus(operation, 'inprogress');
};
ProgressSteps.prototype.failure = function (operation) {
return this.updateStatus(operation, 'failure');
};
ProgressSteps.prototype.success = function (operation) {
return this.updateStatus(operation, 'success');
};
ProgressSteps.prototype.reset = function (operation) {
return this.updateStatus(operation, null);
};
ProgressSteps.prototype.updateStatus = function (operation, status) {
var step, _i, _len, _ref, _results;
_ref = this.all;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
step = _ref[_i];
if (step.operation === operation) {
_results.push(step.status = status);
} else {
_results.push(void 0);
}
}
return _results;
};
return ProgressSteps;
})();
});
I tried modifying :before and :after but nothing actually worked as chevron left and right are created using border property already. I am have a little experience working on CSS and using this chevron in one of the requirement which also asks me to create a border around it.
Thanks
Mitul J

You need to color the triangles attached to the li to your desired border color and add two new triangles to the inner element (span) to create the "illusion" of a triangle with border. This questions has already been answered in detail two times on stackoverflow :)
Links that will help you:
Adding border to CSS triangle
CSS triangle custom border color
Another interesting method this text-stroke:
Create a triangle with CSS?

Related

Is this possible to make "double sort" icon only in css? [duplicate]

This question already has answers here:
How do CSS triangles work?
(23 answers)
Closed 3 years ago.
Is there a way to make this sort of icon only in css?
I know that I can take this icon from font-awesome but I need a way to make it only in CSS.
It is possible. I created a main div wrapper as flex box. This contains two child divs. There are css commands to create a triangle.
.wrapper
{
display:flex;
flex-direction:column;
padding:5px;
}
.top
{
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 20px solid black;
margin-bottom:5px;
}
.bottom
{
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-top: 20px solid #f00;
}
<div class="wrapper">
<div class="top">
</div>
<div class="bottom">
</div>
</div>
Here's a small webcomponent that does it:
class DoubleIcon extends HTMLElement {
get css() {
return `
:host {
display: inline-block;
}
.root {
display:flex;
flex-direction:column;
padding: 5px;
--size: ${this.size}px;
}
.root::before {
content: '';
width: 0;
height: 0;
border-left: calc(3 * var(--size)) solid transparent;
border-right: calc(3 * var(--size)) solid transparent;
border-bottom: calc(4 * var(--size)) solid #ccc;
margin-bottom: var(--size);
}
.root::after {
content: '';
width: 0;
height: 0;
border-left: calc(3 * var(--size)) solid transparent;
border-right: calc(3 * var(--size)) solid transparent;
border-top: calc(4 * var(--size)) solid #ccc;
}`
}
constructor() {
super();
this.attachShadow({mode: 'open'})
this.connected = false;
this.size = 10;
}
connectedCallback() {
if (this.connected) return;
this.appendStyle();
const i = document.createElement('i');
i.className = 'root';
this.shadowRoot.appendChild(i);
this.connected = true;
}
static get observedAttributes() {
return ['size'];
}
appendStyle() {
if (this.styleEl) this.styleEl.remove();
this.styleEl = document.createElement('style');
this.styleEl.innerHTML = this.css;
this.shadowRoot.appendChild(this.styleEl);
}
attributeChangedCallback(attr, oldVal, newVal) {
if (newVal === null) {
this.size = 5;
return;
} else {
this.size = Number(newVal) || 5;
}
this.appendStyle();
}
}
customElements.define('double-icon', DoubleIcon);
<double-icon size="2"></double-icon>
<double-icon size="6"></double-icon>

Huge Google Maps Controls (Possible Bug?)

I first noticed that my Google Maps Controls were disproportionally large on my own web app (seen below).
Initially I thought some of my CSS was playing with Google's CSS on the controls; however, visiting Google's own webpage told me this incident was not isolated to me...
Below is a map on their documentation: https://developers.google.com/maps/documentation/javascript/examples/control-positioning
The large controls appear on every page of their documentation for me as well. I tried different machines and different browsers (Chrome and Firefox).
I also tried other sites that used the Google Maps API and saw a similar phenomenon in some cases.
Is anyone else experiencing the same issues?
Looks like google have now acknowledged this and have provided a (currently un-documented) feature to change the UI scaling by passing in a "controlSize" when creating the map.
See comment from Google here.
JSFiddle here (from comment above).
Sample code:
var map;
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8,
controlSize: 32,
});
}
Note: 40 is the default currently (and corresponds to the large controls that this question is about). I've found 25 to be about the same as the previous controls.
Update:
As of v3.36 this is a documented feature, see here
Turns out this isn't a bug. See more here:
Aug 13, 2018 03:56PM Reported Issue Google Maps JavaScript API weekly
channel (3.34) will be using the larger control UI.
As we are seeing increases of touch operations on various devices, we
adjusted the control UI to fit for both finger touches and mouse
clicks.
It's possible to opt out of this by loading the API with v=quarterly,
v=3, v=3.33 or v=3.32. Note: requests to retired version will receive
the default channel, see 1.
If you have any requests or other issues concerning the new control UI
please let us know.
1 https://issuetracker.google.com/112519576
Use v=quarterly, v=3, v=3.33 or v=3.32 when loading the API to use smaller controls.
EDIT:
Refer to answer from #Jonny van Beek on how to scale Google map's controls to the size of your choosing.
Refer to answers from #garethdn and #Peter (below) to find out how to replace Google's large controls with your own custom controls.
Refer to #Dutchmanjonny's post (below) for latest and correct solution to this problem.
For those that are reluctant to opt out by specifying older versions of the API, creating custom controls is relatively straight forward. The following will create two button elements to zoom in and out.
defaultMapOptions: google.maps.MapOptions = {
// Hide Google's default zoom controls
zoomControl: false
};
initializeMap(el: HTMLElement, options?: google.maps.MapOptions): google.maps.Map {
let opts = Object.assign({}, this.defaultMapOptions, options);
let map = new google.maps.Map(el, opts);
let zoomControlsDiv = document.createElement('div');
// Add a class to the container to allow you to refine the position of the zoom controls
zoomControlsDiv.classList.add('google-map-custom-zoom-controls');
this.createCustomZoomControls(zoomControlsDiv, map);
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(zoomControlsDiv);
return map;
}
createCustomZoomControls(controlDiv: HTMLDivElement, map: google.maps.Map) {
let zoomInControlUI: HTMLButtonElement = document.createElement('button');
let zoomOutControlUI: HTMLButtonElement = document.createElement('button');
let zoomControls: HTMLButtonElement[] = [zoomInControlUI, zoomOutControlUI];
// List of classes to be applied to each zoom control
let buttonClasses: string[] = ['btn', 'btn-primary', 'btn-sm'];
zoomInControlUI.innerHTML = `&plus;`;
zoomOutControlUI.innerHTML = `−`;
zoomControls.forEach(zc => {
zc.classList.add(...buttonClasses);
controlDiv.appendChild(zc);
});
google.maps.event.addDomListener(zoomInControlUI, 'click', () => map.setZoom(map.getZoom() + 1));
google.maps.event.addDomListener(zoomOutControlUI, 'click', () => map.setZoom(map.getZoom() - 1));
}
let map = this.initializeMap(myGoogleMapContainerElement);
After the backlash, Google has now published an example for how to replace the default (big) controls: https://developers.google.com/maps/documentation/javascript/examples/control-replacement
Here is the code as published by Google:
<!DOCTYPE html>
<html>
<head>
<title>Replacing Default Controls</title>
<meta name="viewport" content="initial-scale=1.0">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
.gm-style .controls {
font-size: 28px; /* this adjusts the size of all the controls */
background-color: white;
box-shadow: rgba(0, 0, 0, 0.3) 0px 1px 4px -1px;
box-sizing: border-box;
border-radius: 2px;
cursor: pointer;
font-weight: 300;
height: 1em;
margin: 6px;
text-align: center;
user-select: none;
padding: 2px;
width: 1em;
}
.gm-style .controls button {
border: 0;
background-color: white;
color: rgba(0, 0, 0, 0.6);
}
.gm-style .controls button:hover {
color: rgba(0, 0, 0, 0.9);
}
.gm-style .controls.zoom-control {
display: flex;
flex-direction: column;
height: auto;
}
.gm-style .controls.zoom-control button {
font: 0.85em Arial;
margin: 1px;
padding: 0;
}
.gm-style .controls.maptype-control {
display: flex;
flex-direction: row;
width: auto;
}
.gm-style .controls.maptype-control button {
display: inline-block;
font-size: 0.5em;
margin: 0 1px;
padding: 0 6px;
}
.gm-style .controls.maptype-control.maptype-control-is-map .maptype-control-map {
font-weight: 700;
}
.gm-style .controls.maptype-control.maptype-control-is-satellite .maptype-control-satellite {
font-weight: 700;
}
.gm-style .controls.fullscreen-control button {
display: block;
font-size: 1em;
height: 100%;
width: 100%
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon {
border-style: solid;
height: 0.25em;
position:absolute;
width: 0.25em;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen- control-top-left {
border-width: 2px 0 0 2px;
left: 0.1em;
top: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-top-left {
border-width: 0 2px 2px 0;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-top-right {
border-width: 2px 2px 0 0;
right: 0.1em;
top: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-top-right {
border-width: 0 0 2px 2px;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-bottom-left {
border-width: 0 0 2px 2px;
left: 0.1em;
bottom: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-bottom-left {
border-width: 2px 2px 0 0;
}
.gm-style .controls.fullscreen-control .fullscreen-control-icon.fullscreen-control-bottom-right {
border-width: 0 2px 2px 0;
right: 0.1em;
bottom: 0.1em;
}
.gm-style .controls.fullscreen-control.is-fullscreen .fullscreen-control-icon.fullscreen-control-bottom-right {
border-width: 2px 0 0 2px;
}
</style>
</head>
<body>
<div id="map"></div>
<!-- Hide controls until they are moved into the map. -->
<div style="display:none">
<div class="controls zoom-control">
<button class="zoom-control-in" title="Zoom In">+</button>
<button class="zoom-control-out" title="Zoom Out">−</button>
</div>
<div class="controls maptype-control maptype-control-is-map">
<button class="maptype-control-map"
title="Show road map">Map</button>
<button class="maptype-control-satellite"
title="Show satellite imagery">Satellite</button>
</div>
<div class="controls fullscreen-control">
<button title="Toggle Fullscreen">
<div class="fullscreen-control-icon fullscreen-control-top-left"></div>
<div class="fullscreen-control-icon fullscreen-control-top-right"></div>
<div class="fullscreen-control-icon fullscreen-control-bottom-left"></div>
<div class="fullscreen-control-icon fullscreen-control-bottom-right"></div>
</button>
</div>
</div>
<script>
var map;
function initMap() {
map = new google.maps.Map(document.querySelector('#map'), {
center: {lat: -34.397, lng: 150.644},
zoom: 8,
disableDefaultUI: true,
});
initZoomControl(map);
initMapTypeControl(map);
initFullscreenControl(map);
}
function initZoomControl(map) {
document.querySelector('.zoom-control-in').onclick = function() {
map.setZoom(map.getZoom() + 1);
};
document.querySelector('.zoom-control-out').onclick = function() {
map.setZoom(map.getZoom() - 1);
};
map.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(
document.querySelector('.zoom-control'));
}
function initMapTypeControl(map) {
var mapTypeControlDiv = document.querySelector('.maptype-control');
document.querySelector('.maptype-control-map').onclick = function() {
mapTypeControlDiv.classList.add('maptype-control-is-map');
mapTypeControlDiv.classList.remove('maptype-control-is-satellite');
map.setMapTypeId('roadmap');
};
document.querySelector('.maptype-control-satellite').onclick =
function() {
mapTypeControlDiv.classList.remove('maptype-control-is-map');
mapTypeControlDiv.classList.add('maptype-control-is-satellite');
map.setMapTypeId('hybrid');
};
map.controls[google.maps.ControlPosition.LEFT_TOP].push(
mapTypeControlDiv);
}
function initFullscreenControl(map) {
var elementToSendFullscreen = map.getDiv().firstChild;
var fullscreenControl = document.querySelector('.fullscreen-control');
map.controls[google.maps.ControlPosition.RIGHT_TOP].push(
fullscreenControl);
fullscreenControl.onclick = function() {
if (isFullscreen(elementToSendFullscreen)) {
exitFullscreen();
} else {
requestFullscreen(elementToSendFullscreen);
}
};
document.onwebkitfullscreenchange =
document.onmsfullscreenchange =
document.onmozfullscreenchange =
document.onfullscreenchange = function() {
if (isFullscreen(elementToSendFullscreen)) {
fullscreenControl.classList.add('is-fullscreen');
} else {
fullscreenControl.classList.remove('is-fullscreen');
}
};
}
function isFullscreen(element) {
return (document.fullscreenElement ||
document.webkitFullscreenElement ||
document.mozFullScreenElement ||
document.msFullscreenElement) == element;
}
function requestFullscreen(element) {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.webkitRequestFullScreen) {
element.webkitRequestFullScreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullScreen) {
element.msRequestFullScreen();
}
}
function exitFullscreen() {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.msCancelFullScreen) {
document.msCancelFullScreen();
}
}
</script>
<script src="https://maps.googleapis.com/maps/api/js? key=YOUR_API_KEY&callback=initMap"
async defer></script>
</body>
</html>
Here is what did it for me:
.gm-bundled-control
,.gm-style-mtc
,.gm-fullscreen-control{
transform: scale(.7);
}
Makes the controls 30% smaller.
I added some css and that's it.
/* Fix +/- zoom buttons design */
#map .gm-bundled-control-on-bottom {
right: 30px !important;
bottom: 116px !important;
}
#map .gm-bundled-control-on-bottom > div:first-child {
top: 44px !important;
}
#map .gmnoprint > .gmnoprint > div {
height: 60px !important;
width: 30px !important;
}
#map .gmnoprint > .gmnoprint > div > div { /* seperator */
width: 22.5px !important;
margin: 0px 3.75px !important;
}
#map .gmnoprint > .gmnoprint button {
width: 30px !important;
height: 30px !important;
}
#map .gmnoprint > .gmnoprint button img {
height: 13.5px !important;
width: 13.5px !important;
margin: 6.75px 8.25px 9.75px !important;
}
and this is for the yellow man button:
/* yellow person button design*/
#map .gm-svpc {
width: 30px !important;
height: 30px !important;
}
#map .gm-svpc img:nth-child(1), #map .gm-svpc img:nth-child(2){
width: 13.5px !important;
height: 22.5px !important;
left: -7px !important;
top: -12px !important;
}
#map .gm-svpc img:nth-child(3) {
width: 24px !important;
height: 30px !important;
}
and for last the MAP|Satellite buttons design
/* MAP|Satellite buttons design*/
#map .gm-style-mtc > div:nth-child(1) {
padding: 0px 9px !important;
height: 30px !important;
font-size: 15px !important;
}
#map .gm-style-mtc > div:nth-child(2) {
top: 30px !important;
}
#map .gm-style-mtc > div:nth-child(2) > div {
padding: 2px 4px 2px 2px !important;
font-size: 14px !important;
}

Progress bar when upload file in contact form 7 in wordpress error

I found this fantastic piece of code for enabling progress bar during uploading files in Contact Form 7 plugin for Wordpress. Original source: HERE
<script type="text/javascript">
jQuery(document).ready(function(){
var dropbox;
dropbox = document.getElementById("dropbox");
dropbox.addEventListener("dragenter", dragenter, false);
dropbox.addEventListener("dragleave", dragleave, false);
dropbox.addEventListener("dragover", dragover, false);
dropbox.addEventListener("drop", drop, false);
function defaults(e){
e.stopPropagation();
e.preventDefault();
}
function dragenter(e) {
jQuery(this).addClass("active");
defaults(e);
}
function dragover(e) {
defaults(e);
}
function dragleave(e) {
jQuery(this).removeClass("active");
defaults(e);
}
function drop(e) {
jQuery(this).removeClass("active");
defaults(e);
var dt = e.dataTransfer;
var files = dt.files;
handleFiles(files,e);
}
jQuery(document).on('change', '#fileElem', function(){
handleFiles(this.files)});
handleFiles = function (files,e){
var imageType = /image.*/;
var file = files[0];
var info = '<div class="preview active-win"><div class="preview-image"><img ></div><div class="progress-holder"><span id="progress"></span></div><span class="percents"></span><div style="float:left;">Uploaded <span class="up-done"></span> KB of '+parseInt(file.size / 1024)+' KB</div>';
jQuery(".upload-progress").show("fast",function(){
jQuery(".upload-progress").html(info);
uploadFile(file);
});
}
uploadFile = function(file){
// check if browser supports file reader object
if (typeof FileReader !== "undefined"){
//alert("uploading "+file.name);
reader = new FileReader();
reader.onload = function(e){
//alert(e.target.result);
jQuery('.preview img').attr('src',e.target.result).css("width","70px").css("height","70px");
}
reader.readAsDataURL(file);
xhr = new XMLHttpRequest();
xhr.open("post", "ajax_fileupload.php", true);
xhr.upload.addEventListener("progress", function (event) {
console.log(event);
if (event.lengthComputable) {
jQuery("#progress").css("width",(event.loaded / event.total) * 100 + "%");
jQuery(".percents").html(" "+((event.loaded / event.total) * 100).toFixed() + "%");
jQuery(".up-done").html((parseInt(event.loaded / 1024)).toFixed(0));
}
else {
alert("Failed to compute file upload length");
}
}, false);
xhr.onreadystatechange = function (oEvent) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
jQuery("#progress").css("width","100%");
jQuery(".percents").html("100%");
jQuery(".up-done").html((parseInt(file.size / 1024)).toFixed(0));
jQuery(".upload-progress").hide();
} else {
alert("Error"+ xhr.statusText);
}
}
};
// Set headers
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", file.fileName);
xhr.setRequestHeader("X-File-Size", file.fileSize);
xhr.setRequestHeader("X-File-Type", file.type);
xhr.send(file);
}else{
alert("Your browser doesnt support FileReader object");
}
}
});
</script>
<style>
.active{ background : #B4F9AC; font-size: 15px; box-shadow : 0px 0px 5px 6px #ccc; }
.progress-holder{ width: 300px; padding: 2px; background: #CCCCCC; border-radius: 3px; float: left; margin-top: 4px; margin-right: 5px; }
#progress{ height: 6px; display:block; width: 0%; border-radius: 2px; background: -moz-linear-gradient(center top , #13DD13 20%, #209340 80%) repeat scroll 0 0 transparent; /* IE hack */ background: -ms-linear-gradient(bottom, #13DD13, #209340); /* chrome hack */ background-image: -webkit-gradient(linear, 20% 20%, 20% 100%, from(#13DD13), to(#209340)); /* safari hack */ background-image: -webkit-linear-gradient(top, #13DD13, #209340); /* opera hack */ background-image: -o-linear-gradient(#13DD13,#209340); box-shadow:3px 3px 3px #888888; }
.preview{ border: 1px solid #CDCDCD; width: 450px; padding: 10px; height:auto; overflow: auto; color: #4D4D4D; float: left; box-shadow:3px 3px 3px #888888; border-radius: 2px; }
.percents{ float: right; }
.preview-image{ box-shadow: 3px 3px 3px #888888; width: 70px; height: 70px; float: left; margin-right: 10px; }
.file-info{ height: 50px; float: left; width: auto; margin-bottom: 10px; border: 1px solid blue; }
.file-info span{ margin: 3px 2px; font-size: 12px; float:left; display: block; min-width: 100px; overflow: auto; border: 1px solid red; overflow: none; }
.upload-progress{ display: none; }</style>
<div id="dropbox">[file* fileElem id:fileElem limit:5000000]</div><div class="upload-progress"></div>
It is working for me however, i have contact form with 5 files to upload and when I'm uploading one progress bar and thumbnail are shown for all of them. See screnshot HERE.
I'm not really programer nor developer so I don't have enough knowledge to "fix it" myself. I was trying to give uniqe ID for every file in CF7 form, but no luck.
Original topic is closed so I can't contact developer with my issue. Can anybody take a look into code and give some clues?
Thank you in advance

Is there a CSS way to automatically set the width of an element based on the size of text strings?

I’m creating a styled select menu in which I’m styling an unordered list that is replacing my select element.
<div class="select">
<select name="distance" id="distance" class="select-hidden">
<option value="5.0 5"><font><font>5 mi</font></font></option>
<option value="6.0 4">6 km</option>
<option value="10.0 4" selected="selected"><font><font>10 km</font></font></option></select><div class="select-styled">10 km</div><ul class="select-options" style="display: none;"><li rel="5.0 5"><font><font>5 mi</font></font></li><li rel="6.0 4"><font><font>6 km</font></font></li><li rel="10.0 4"><font><font>10 km</font></font></li></ul>
</div>
I then have this style
.select {
cursor: pointer;
display: inline-block;
position: relative;
font-size: 16px;
color: #000000;
width: 220px;
height: 42px;
}
Right now I’m hard-coding the width (220px) and my question is can I build this in a less rigid way such that the width will automatically be the width of the longest element name? Here is the Fiddle that illustrates my dilemma — https://jsfiddle.net/n73ao02h/13/ .
How about that: https://jsfiddle.net/n73ao02h/14/
A select-box without any width will always style according to its options. So we use that...
First step is to remove the fixed width.
We get the width in JS before we add display:none to it.
We then generate a temporary element styled-select with zero width to automatically get the padding defined in CSS without hardcoding it.
We then have all we need to calculate the new width of your styled select-box:
/* ... */
var $paddingCalculator = $('<div />', {
'class' : "select-styled test"
}).css({
width : 0,
visibility : "hidden"
}).appendTo("body");
var paddingWidth = $paddingCalculator.outerWidth();
$paddingCalculator.remove();
var selectWidth = $this.width() + paddingWidth;
$this.addClass('select-hidden');
if ( !$this.parent().hasClass('select') ) {
var $wrapper = $("<div />", {
'class' : "select"
}).css({
width : selectWidth
});
$this.wrap( $wrapper );
} // if
/* ... */
 
little addendum:
Keep in mind that both - the original select box and your styled div - need to have the same font-size (and anything text-styling related, such as font-family, font-weight, letter-spacing, ...) so that the calculated dimensions will be correct.
Don't set the width and don't set display:none on the select, plus set white-space:nowrap on your div.select-styled :
$(function() {
$('select').each(function(){
styleSelectMenu($(this));
});
});
// This method applies the styles to our select menu
function styleSelectMenu(selectMenu)
{
var $this = $(selectMenu), numberOfOptions = $(selectMenu).children('option').length;
$this.addClass('select-hidden');
if ( !$this.parent().hasClass('select') ) {
$this.wrap('<div class="select"></div>');
} // if
if ( !$this.next().hasClass('select-styled') ) {
$this.after('<div class="select-styled"></div>');
} // if
var $styledSelect = $this.next('div.select-styled');
$styledSelect.text($this.children('option').eq(0).text());
if ( $styledSelect.parent().find('ul').length > 0 ) {
$styledSelect.parent().find('ul').remove();
} // if
var $list = $('<ul />', {
'class': 'select-options'
}).insertAfter($styledSelect);
for (var i = 0; i < numberOfOptions; i++) {
$('<li />', {
text: $this.children('option').eq(i).text(),
rel: $this.children('option').eq(i).val()
}).appendTo($list);
}
var $listItems = $list.children('li');
// This is the event when someone opens the list
$styledSelect.unbind('click')
$styledSelect.click(function(e) {
e.stopPropagation();
$('div.select-styled.active').each(function(){
$(this).removeClass('active').next('ul.select-options').hide();
});
$(this).toggleClass('active').next('ul.select-options').toggle();
});
// This is the event when someone actually selects something from the list
$listItems.unbind('click.selectStyledItem')
$listItems.bind('click.selectStyledItem', function(event) {
clickListItem($styledSelect, $this, $(this), $list);
});
$(document).click(function() {
$styledSelect.removeClass('active');
$list.hide();
});
var selectedIndex = $this[0].selectedIndex;
if (selectedIndex > 0) {
var name = $this.attr("name")
var selectedText = $( "select[name='" + name + "'] option:selected" ).text();
selectItemFromStyledList($styledSelect, $this, selectedText, $list);
} // if
}
// This is the method that will select an item from the styled list
function selectItemFromStyledList(styledSelect, selectMenu, selectedText, listToHide)
{
$(styledSelect).text(selectedText).removeClass('active');
$(selectMenu).val($(selectMenu).attr('rel'));
$(listToHide).hide();
// Select option in the underlying list so that the form gets submitted
// with the right values
selectedOption = $(selectMenu).find("option").filter(function () { return $(this).html() == selectedText; });
$(selectMenu).find("option[selected='selected']").removeAttr("selected");
$(selectedOption).attr("selected","selected");
} // selectItemFromStyledList
// Called when someone clicks an item from the styled list
// The event data should contain the following parameters:
// styledSelect - the <div> element that contains the styled menu
// selectMenu - the actual form element that contains the items
// listItemClicked - the item that was clicked.
// list - THe <UL> element containig the <li> options
function clickListItem(styledSelect, selectMenu, listItemClicked, list)
{
var $styledSelect = $(styledSelect);
var $selectMenu = $(selectMenu);
var $listItem = $(listItemClicked);
var $list = $(list);
event.stopPropagation();
var selectedText = $listItem.text();
selectItemFromStyledList($styledSelect, $selectMenu, selectedText, $list)
} // clickListItem
#statSearchFields {
vertical-align: top;
font-size: 90%;
}
.selectMenu {
font-family: 'Oxygen', sans-serif;
font-size: 20px;
height: 50px;
-webkit-appearance: menulist-button;
}
.select-hidden {
visibility: hidden;
padding-right: 10px;
}
.select {
cursor: pointer;
display: inline-block;
position: relative;
font-size: 16px;
color: black;
height: 42px;
}
.select-styled {
white-space: nowrap;
}
.select-styled {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background-color: gray;
padding: 11px 12px;
#include transition(all 0.2s ease-in);
&:after {
content:"";
width: 0;
height: 0;
border: 7px solid transparent;
border-color: black transparent transparent transparent;
position: absolute;
top: 16px;
right: 10px;
}
&:hover {
background-color: darken(gray, 2);
}
&:active, &.active {
background-color: darken(gray, 5);
&:after {
top: 9px;
border-color: transparent transparent $select-color transparent;
}
}
}
.select-options {
display: none;
position: absolute;
top: 100%;
right: 0;
left: 0;
z-index: 999;
margin: 0;
padding: 0;
list-style: none;
background-color: darken(gray, 5);
overflow: scroll;
li {
margin: 0;
padding: 12px 0;
text-indent: 15px;
border-top: 1px solid darken(gray, 10);
#include transition(all 0.15s ease-in);
&:hover {
color: gray;
background: black;
}
&[rel="hide"] {
display: none;
}
}
}
#statSearchContainer {
padding: 10px;
font-family: "Calibre", "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
background-color: tan;
display: table;
}
#statSearchContainer h1 {
margin: 5px 0;
font-size: 1.0em;
}
#stat-search-form {
display: block;
padding: 0px;
}
#stat-search-form form input {
vertical-align: middle;
}
#statSearchFields {
vertical-align: top;
font-size: 90%;
}
.searchField {
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="statSearchContainer">
<div class="searchField">
Distance<br/>
<select name="distance" id="distance"><option value="5.0 5">5 mi</option>
<option value="6.0 4">6 km</option>
<option selected="selected" value="10.0 4">10 km</option></select>
</div>
<input alt="Search" type="image" src="/assets/magnifying-glass-0220f37269f90a370c3bb60229240f2ef2a4e15b335cd42e64563ba65e4f22e4.png" class="search_button">
</div>
</div>

Using the CSS :after pseudo-selector to display directional carets in Bootstrap 3 input-groups

I've been trying to apply carets to input-group elements in Bootstrap 3. Failing so far. Tried using table-cell display for the inserted pseudo element, tried absolute positioning, tried using the content property to display a web font caret instead of my preferred CSS triangle caret. Just can't wrap my head around this one.
Here's a JSFiddle (the red borders being where I'd expect the caret to show).
.input-group .input-group-addon:last-child:before,
.input-group .input-group-btn:last-child:before,
.input-group .input-group-addon:not(:last-child):before,
.input-group .input-group-btn:not(:last-child):before {
position: absolute;
content: '';
width: 0;
height: 0;
border: 10px solid transparent;
margin: auto;
top: 0;
bottom: 0;
z-index: 1000;
}
.input-group .input-group-addon:last-child:before,
.input-group .input-group-btn:last-child:before {
border-right-color: red;
right: 0;
}
.input-group .input-group-addon:not(:last-child):before,
.input-group .input-group-btn:not(:last-child):before {
border-left-color: red;
left: 0;
}
EDIT : Based on an answer, I modified the styles which now work fine in all but IE10 and below. IE offsets left-aligned input-group carets by 4px as can be seen here http://jsfiddle.net/W8mFS/3/. Any ideas how to fix this up?
The updated CSS:
.input-group.input-group-caret span:after,
.input-group.input-group-caret > input + span:before {
position: absolute;
content: '';
width: 0;
height: 0;
top: 0;
bottom: 0;
margin: auto;
border: 10px solid transparent;
}
.input-group.input-group-caret > input + span:before {
border-right-color: #cccccc;
margin-left: -20px;
}
.input-group.input-group-caret > input + span:empty:before {
margin-left: -44px;
}
.input-group.input-group-caret > input + span:after {
border-left-color: transparent;
}
.input-group.input-group-caret span:after {
border-left-color: #cccccc;
}
.input-group.input-group-caret .input-group-addon {
padding: 0;
}
.input-group.input-group-caret .input-group-addon i {
font-style: normal;
margin-left: 12px;
padding-right: 12px;
}
.input-group.input-group-caret .input-group-addon:empty {
padding-left: 24px;
}
UPDATE : With added input-group sizing JSFiddle here: http://jsfiddle.net/W8mFS/4/.
The LESS code shows the use of Bootstrap variables to control caret size, margins and padding:
#import "path_to_bootstrap/less/mixins";
#import "path_to_bootstrap/less/variables";
// input-group caret size
#caret-size-base: ceil(#font-size-base * 0.70); // ~10px;
#caret-size-large: ceil(#caret-size-base * 1.20); // ~12px;
#caret-size-small: ceil(#caret-size-base * 0.80); // ~8px;
// input-group caret
.input-group.input-group-caret {
span:after,
> input + span:before {
position: absolute;
content: '';
width: 0;
height: 0;
// v-align to middle
top: 0;
bottom: 0;
margin: auto;
border: #caret-size-base solid transparent;
}
> input + span:before { border-right-color: #input-border; margin-left: -( 2 * #caret-size-base ); } // right aligned
> input + span:empty:before { margin-left: -(( 2 * #padding-base-horizontal ) + ( 2 * #caret-size-base )); } // right aligned
> input + span:after { border-left-color: transparent; } // right aligned
span:after { border-left-color: #input-border; } // left aligned
// sizing
&.input-group-sm {
span:after,
> input + span:before {
border: #caret-size-small solid transparent;
}
> input + span:before { border-right-color: #input-border; margin-left: -( 2 * #caret-size-small ); } // right aligned
> input + span:empty:before { margin-left: -(( 2 * #padding-base-horizontal ) + ( 2 * #caret-size-small )); } // right aligned
> input + span:after { border-left-color: transparent; } // right aligned
span:after { border-left-color: #input-border; } // left aligned
}
&.input-group-lg {
span:after,
> input + span:before {
border: #caret-size-large solid transparent;
}
> input + span:before { border-right-color: #input-border; margin-left: -( 2 * #caret-size-large ); } // right aligned
> input + span:empty:before { margin-left: -(( 2 * #padding-base-horizontal ) + ( 2 * #caret-size-large )); } // right aligned
> input + span:after { border-left-color: transparent; } // right aligned
span:after { border-left-color: #input-border; } // left aligned
}
// input-group caret alignment fixes
.input-group-addon {
padding: 0;
i {
font-style: normal;
margin-left: #padding-base-horizontal;
padding-right: #padding-base-horizontal;
}
// fix-up alignment of empty addon
&:empty {
padding-left: 2 * #padding-base-horizontal;
}
}
}
It seems .input-group > input + span:before will be a good selector for Right Aligned. But there will also be the problem that box-sizing : border-box (Why did Bootstrap 3 switch to box-sizing: border-box?) breaks the carets / forms. (width include :after and :before too?)
see: http://bootply.com/83702
.input-group > input + span:before {
display: inline-block;
width: 0;
height: 0;
border-right: 10px solid red;
border-top: 10px solid transparent;
border-left: 0 dotted;
border-bottom: 10px solid transparent;
vertical-align: middle;
margin-left: 2px;
content:'';
}

Resources