.btn-negative

bootstrap-compatible button type negative - as from the parent

by Jean-Marc Zimmer

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<script src="//code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<!--
---- Author: Jean-Marc ZIMMER
---- Source code: https://github.com/JeanMarcZimmer/btn-negative
--->

<div class="main-container">
  <div class="alert alert-info">
    <div class="row">
      <div class="col col-6">
        <div class="row">
          <code><h1>.btn-negative</h1></code><small>v2.0</small>
        </div>
      </div>
      <div class="col col-6">
        <code>
          <a class="btn btn-lg btn-outline-negative" href="https://github.com/JeanMarcZimmer/btn-negative" target="_blank">Source code <small>v1.0</small></a>
        </code>
      </div>
    </div>
    <hr />
    <h4>CSS property correspondence table</h4>
    <small>Note that only <code>color</code>, <code>background-color</code>, <code>border(-color)</code>, and <code>box-shadow(-color)</code> are affected by this plugin.</small>
    <div class="table-responsive">
      <table class="table table-bordered">
        <thead>
          <tr>
            <th>Parent property</th>
            <th>.btn-negative, .btn-outline-negative:hover property</th>
            <th>.btn-outline-negative property</th>
            <th>.btn[-outline]-negative:focus property</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td><code>background-color</code></td>
            <td><code>color</code></td>
            <td><code>background-color</code></td>
            <td>none</td>
          </tr>
          <tr>
            <td><code>color</code></td>
            <td><code>background-color</code></td>
           ...

CSS

/*
** Author: Jean-Marc ZIMMER
** Source code: https://github.com/JeanMarcZimmer/btn-negative
*/

.main-container {
  margin: 10px;
}

h3 {
  margin: 5px;
}

table * {
  white-space: nowrap;
}

.btn-container {
  padding: 5px;
}

.btn {
  width: 100%;
}

hr {
  background-color: var(--neg-color);
}

.color1 {
  background-color: #532455;
  /* --bg-color */
  color: #f8f9ca;
  /* --neg-color */
}

.color2 {
  background-color: #ff0000;
  color: #0f0;
}

.bw {
  background-color: #fff;
  color: #000
}

.color3 {
  background-color: #fdf9e9;
  color: #3429a5;
}

.debug1 {
  border: solid 1px #f00;
}

.debug2 {
  border: solid 1px #0f0;
}

.debug3 {
  border: solid 1px #00f;
}

/*                                           *\
** Start of the really important part of css **
\*                                           */

.btn-negative,
.btn-outline-negative.active,
.btn-outline-negative:hover:not(.disabled):not([disabled]),
.btn-outline-negative:active:not(.disabled):not([disabled]) {
  background-color: var(--btn-negative-color1);
  color: var(--btn-negative-color0);
}

.btn-negative.active,
.btn-negative:hover:not(.disabled):not([disabled]),
.btn-negative:active:not(.disabled):not([disabled]) {
  background-color: var(--btn-negative-color2);
  color: var(--btn-negative-color0);
  /* Needs to be added to github repo */
}

.btn-negative.active:hover,
.btn-negative:hover:active:not(.disabled):not([disabled]) {
  background-color: var(--btn-negative-color3);
  color: var(--btn-negative-color0);
  /* Needs to be added to github repo */
}

.btn-negative:focus,
.btn-outline-negative:focus {
  box-shadow: 0 0 0 .2rem var(--btn-negative-shadow-color);
}

.btn-outline-negative {
  background-color: var(--btn-negative-color0);
  border: solid 1px var(--btn-negative-color1);
  color: var(--btn-negative-color1);
}

JavaScript

/*
** Author: Jean-Marc ZIMMER
** Source code: https://github.com/JeanMarcZimmer/btn-negative
*/

$(function() {

	const hexDigits = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"];

	function hex(x) {
		return isNaN(x) ? "00" : hexDigits[(x - x % 16) / 16] + hexDigits[x % 16];
	}

	function hexify(rgb) {
		rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
		return "#" + hex(rgb[1]) + hex(rgb[2]) + hex(rgb[3]);
	}

	function darken(rgb) {
		rgb = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
		return "rgb(" + parseInt(0.925 * rgb[1]) + ',' + parseInt(0.925 * rgb[2]) + ',' + parseInt(0.925 * rgb[3]) + ')';
	}

	function getParentBackground($elem) {
		var color = $elem.css("background-color");
		if (color && color !== 'rgba(0, 0, 0, 0)')
			return color;
		return ($elem.is('body') ? false : getParentBackground($elem.parent()));
	}

	function getParentColor($elem) {
		var color = $elem.css("color");
		if (color && color !== 'rgba(0, 0, 0, 0)')
			return color;
		return ($elem.is('body') ? false : getParentColor($elem.parent()));
	}

	$('.btn-negative, .btn-outline-negative').each(function() {
		var bgColor = hexify(getParentBackground($(this).parent()));
		var color = hexify(getParentColor($(this).parent()));
		var rgb = getParentColor($(this).parent());
		this.style.setProperty('--btn-negative-color0', bgColor);
		this.style.setProperty('--btn-negative-color1', color);
		this.style.setProperty('--btn-negative-shadow-color', color + "88");
		this.style.setProperty('--btn-negative-color2', hexify(darken(rgb)));
		this.style.setProperty('--btn-negative-color3', hexify(darken(darken(rgb))));
	});

});