1
0
mirror of https://github.com/JKorf/CryptoExchange.Net.git synced 2026-08-11 16:32:57 +00:00

Websocket refactoring (#190)

Websocket refactoring
This commit is contained in:
Jan Korf
2024-02-24 19:21:47 +01:00
committed by GitHub
parent d91755dff5
commit d533557324
585 changed files with 114831 additions and 2198 deletions
-171
View File
@@ -1,171 +0,0 @@
---
title: General usage
nav_order: 2
---
## How to use the library
Each implementation generally provides two different clients, which will be the access point for the API's. First of is the rest client, which is typically available via [ExchangeName]RestClient, and a socket client, which is generally named [ExchangeName]SocketClient. For example `BinanceRestClient` and `BinanceSocketClient`.
## Rest client
The rest client gives access to the Rest endpoint of the API. Rest endpoints are accessed by sending an HTTP request and receiving a response. The client is split in different sub-clients, which are named API Clients. These API clients are then again split in different topics. Typically a Rest client will look like this:
- [ExchangeName]RestClient
- SpotApi
- Account
- ExchangeData
- Trading
- FuturesApi
- Account
- ExchangeData
- Trading
This rest client has 2 different API clients, the `SpotApi` and the `FuturesApi`, each offering their own set of endpoints.
*Requesting ticker info on the spot API*
```csharp
var client = new KucoinClient();
var tickersResult = kucoinClient.SpotApi.ExchangeData.GetTickersAsync();
```
Structuring the client like this should make it easier to find endpoints and allows for separate options and functionality for different API clients. For example, some API's have totally separate API's for futures, with different base addresses and different API credentials, while other API's have implemented this in the same API. Either way, this structure can facilitate a similar interface.
### Rest API client
The Api clients are parts of the total API with a common identifier. In the previous example, it separates the Spot and the Futures API. This again is then separated into topics. Most Rest clients implement the following structure:
**Account**
Endpoints related to the user account. This can for example be endpoints for accessing account settings, or getting account balances. The endpoints in this topic will require API credentials to be provided in the client options.
**ExchangeData**
Endpoints related to exchange data. Exchange data can be tied to the exchange, for example retrieving the symbols supported by the exchange and what the trading rules are, or can be more general market endpoints, such as getting the most recent trades for a symbol.
These endpoints generally don't require API credentials as they are publicly available.
**Trading**
Endpoints related to trading. These are endpoints for placing and retrieving orders and retrieving trades made by the user. The endpoints in this topic will require API credentials to be provided in the client options.
### Processing request responses
Each request will return a WebCallResult<T> with the following properties:
`RequestHeaders`: The headers send to the server in the request message
`RequestMethod`: The Http method of the request
`RequestUrl`: The url the request was send to
`ResponseLength`: The length in bytes of the response message
`ResponseTime`: The duration between sending the request and receiving the response
`ResponseHeaders`: The headers returned from the server
`ResponseStatusCode`: The status code as returned by the server
`Success`: Whether or not the call was successful. If successful the `Data` property will contain the resulting data, if not successful the `Error` property will contain more details about what the issue was
`Error`: Details on what went wrong with a call. Only filled when `Success` == `false`
`OriginalData`: Will contain the originally received unparsed data if this has been enabled in the client options
`Data`: Data returned by the server, only available if `Success` == `true`
When processing the result of a call it should always be checked for success. Not doing so will result in `NullReference` exceptions when the call fails for whatever reason.
*Check call result*
```csharp
var callResult = await kucoinClient.SpotApi.ExchangeData.GetTickersAsync();
if(!callResult.Success)
{
Console.WriteLine("Request failed: " + callResult.Error);
return;
}
Console.WriteLine("Result: " + callResult.Data);
```
## Socket client
The socket client gives access to the websocket API of an exchange. Websocket API's offer streams to which updates are pushed to which a client can listen, and sometimes also allow request/response communication.
Just like the Rest client is divided in Rest Api clients, the Socket client is divided into Socket Api clients, each with their own range of API functionality. Socket Api clients are generally not divided into topics since the number of methods isn't as big as with the Rest client. To use the Kucoin client as example again, it looks like this:
```csharp
- KucoinSocketClient
- SpotStreams
- FuturesStreams
```
*Subscribing to updates for all tickers on the Spot Api*
```csharp
var subscribeResult = kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
```
Subscribe methods always require a data handler parameter, which is the method which will be called when an update is received from the server. This can be the name of a method or a lambda expression.
*Method reference*
```csharp
await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
private static void DataHandler(DataEvent<KucoinStreamTick> updateData)
{
// Process updateData
}
```
*Lambda*
```csharp
await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(updateData =>
{
// Process updateData
});
```
All updates are wrapped in a `DataEvent<>` object, which contain the following properties:
`Timestamp`: The timestamp when the data was received (not send!)
`OriginalData`: Will contain the originally received unparsed data if this has been enabled in the client options
`Topic`: Will contain the topic of the update, which is typically the symbol or asset the update is for
`Data`: Contains the received update data.
*[WARNING] Do not use `using` statements in combination with constructing a `SocketClient` without blocking the thread. Doing so will dispose the `SocketClient` instance when the subscription is done, which will result in the connection getting closed. Instead assign the socket client to a variable outside of the method scope.*
### Processing subscribe responses
Subscribing to a stream will return a `CallResult<UpdateSubscription>` object. This should be checked for success the same way as a [rest request](#processing-request-responses). The `UpdateSubscription` object can be used to listen for connection events of the socket connection.
```csharp
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
if(!subscriptionResult.Success)
{
Console.WriteLine("Failed to connect: " + subscriptionResult.Error);
return;
}
subscriptionResult.Data.ConnectionLost += () =>
{
Console.WriteLine("Connection lost");
};
subscriptionResult.Data.ConnectionRestored += (time) =>
{
Console.WriteLine("Connection restored");
};
```
### Unsubscribing
When no longer interested in specific updates there are a few ways to unsubscribe.
**Close subscription**
Subscribing to an update stream will respond with an `UpdateSubscription` object. You can call the `CloseAsync()` method on this to no longer receive updates from that subscription:
```csharp
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToAllTickerUpdatesAsync(DataHandler);
await subscriptionResult.Data.CloseAsync();
```
**Cancellation token**
Passing in a `CancellationToken` as parameter in the subscribe method will allow you to cancel subscriptions by canceling the token. This can be useful when you need to cancel some streams but not others. In this example, both `BTC-USDT` and `ETH-USDT` streams get canceled, while the `KCS-USDT` stream remains active.
```csharp
var cts = new CancellationTokenSource();
var subscriptionResult1 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("BTC-USDT", DataHandler, cts.Token);
var subscriptionResult2 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("ETH-USDT", DataHandler, cts.Token);
var subscriptionResult3 = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("KCS-USDT", DataHandler);
Console.ReadLine();
cts.Cancel();
```
**Client unsubscribe**
Subscriptions can also be closed by calling the `UnsubscribeAsync` method on the client, while providing either the `UpdateSubscription` object or the subscription id:
```csharp
var subscriptionResult = await kucoinSocketClient.SpotStreams.SubscribeToTickerUpdatesAsync("BTC-USDT", DataHandler);
await kucoinSocketClient.UnsubscribeAsync(subscriptionResult.Data);
// OR
await kucoinSocketClient.UnsubscribeAsync(subscriptionResult.Data.Id);
```
When you need to unsubscribe all current subscriptions on a client you can call `UnsubscribeAllAsync` on the client to unsubscribe all streams and close all connections.
-60
View File
@@ -1,60 +0,0 @@
---
title: FAQ
nav_order: 12
---
## Frequently asked questions
### I occasionally get a NullReferenceException, what's wrong?
You probably don't check the result status of a call and just assume the data is always there. `NullReferenceExecption`s will happen when you have code like this `var symbol = client.GetTickersAync().Result.Data.Symbol` because the `Data` property is null when the call fails. Instead check if the call is successful like this:
```csharp
var tickerResult = await client.GetTickersAync();
if(!tickerResult.Success)
{
// Handle error
}
else
{
// Handle result, it is now safe to access the Data property
var symbol = tickerResult.Data.Symbol;
}
```
### The socket client stops sending updates after a little while
You probably didn't keep a reference to the socket client and it got disposed.
Instead of subscribing like this:
```csharp
private void SomeMethod()
{
var socketClient = new BinanceSocketClient();
socketClient.Spot.SubscribeToOrderBookUpdates("BTCUSDT", data => {
// Handle data
});
}
```
Subscribe like this:
```csharp
private BinanceSocketClient _socketClient = new BinanceSocketClient();
// .. rest of the class
private void SomeMethod()
{
_socketClient.Spot.SubscribeToOrderBookUpdates("BTCUSDT", data => {
// Handle data
});
}
```
### Can I use the TestNet/US/other API with this library
Yes, generally these are all supported and can be configured by setting the Environment in the client options. Some known environments should be available in the [Exchange]Environment class. For example:
```csharp
var client = new BinanceRestClient(options =>
{
options.Environment = BinanceEnvironment.Testnet;
});
```
### How are timezones handled / Timestamps are off by xx
Exchange API's treat all timestamps as UTC, both incoming and outgoing. The client libraries do no conversion so be sure to use UTC as well.
-28
View File
@@ -1,28 +0,0 @@
---
title: Glossary
nav_order: 11
---
## Terms and definitions
|Definition|Synonyms|Meaning|
|----------|--------|-------|
|Symbol|Market|An asset pair, for example `BTC-ETH`|
|Asset|Currency, Coin|A coin for which you can hold balance and which makes up Symbols. For example both `BTC`, `ETH` or `USD`|
|Trade|Execution, fill|The (partial) execution of an order. Orders can have multiple trades|
|Quantity|Amount, Size|The amount of asset|
|Fee|Commission|The fee paid for an order or trade|
|Kline|Candlestick, OHLC|K-line data, used for candlestick charts. Contains Open/High/Low/Close/Volume|
|KlineInterval|The time period of a single kline|
|Open order|Active order, Unexecuted order|An order which has not yet been fully filled|
|Closed order|Completed order, executed order|An order which is no longer active. Can be canceled or fully filled|
|Network|Chain|The network of an asset. For example `ETH` allows multiple networks like `ERC20` and `BEP2`|
|Order book|Market depth|A list of (the top rows of) the current best bids and asks|
|Ticker|Stats|Statistics over the last 24 hours|
|Client implementation|Library|An implementation of the `CrytpoExchange.Net` library. For example `Binance.Net` or `Bybit.Net`|
### Other naming conventions
#### PlaceOrderAsync
Methods for creating an order are always named `PlaceOrderAsync`, with and optional additional name for the type of order, for example `PlaceMarginOrderAsync`.
#### GetOrdersAsync/GetOpenOrdersAsync/GetClosedOrdersAsync
`GetOpenOrdersAsync` only retrieves orders which are still active, `GetClosedOrdersAsync` only retrieves orders which are canceled/closed. `GetOrdersAsync` retrieves both open and closed orders.
-6
View File
@@ -1,6 +0,0 @@
---
title: Creating an implementation
nav_order: 8
---
TODO
-145
View File
@@ -1,145 +0,0 @@
---
title: Common interfaces
nav_order: 7
---
## Shared interfaces
Clients have a common interface implementation to allow a shared code base to use the same functionality for different exchanges. The interface is implemented at the `API` level, for example:
```csharp
var binanceClient = new BinanceClient();
ISpotClient spotClient = binanceClient.SpotApi.CommonSpotClient;
IFuturesClient futuresClient = binanceClient.UsdFuturesApi.CommonFuturesClient;
```
For examples on this see the Examples folder.
## ISpotClient
The `ISpotClient` interface is implemented on Spot API clients. The interface exposes basic functionality like retrieving market data and managing orders. The `ISpotClient` interface will be available via the `CommonSpotClient` property on the Api client.
The spot client has the following members:
*Properties*
```csharp
// The name of the exchange this client interacts with
string ExchangeName { get; }
```
*Events*
```csharp
// Event when placing an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `PlaceOrderAsync` method is called.
event Action<OrderId> OnOrderPlaced;
// Event when canceling an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `CancelOrderAsync` method is called.
event Action<OrderId> OnOrderCanceled;
```
*Methods*
```csharp
// Retrieve the name of a symbol based on 2 assets. This will format them in the way the exchange expects them. For example BTC, USDT will return BTCUSDT on Binance and BTC-USDT on Kucoin
string GetSymbolName(string baseAsset, string quoteAsset);
// Get a list of symbols (trading pairs) on the exchange
Task<WebCallResult<IEnumerable<Symbol>>> GetSymbolsAsync();
// Get the ticker (24 hour stats) for a symbol
Task<WebCallResult<Ticker>> GetTickerAsync(string symbol);
// Get a list of tickers for all symbols
Task<WebCallResult<IEnumerable<Ticker>>> GetTickersAsync();
// Get a list klines (candlesticks) for a symbol
Task<WebCallResult<IEnumerable<Kline>>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null);
// Get the order book for a symbol
Task<WebCallResult<OrderBook>> GetOrderBookAsync(string symbol);
// Get a list of most recent trades
Task<WebCallResult<IEnumerable<Trade>>> GetRecentTradesAsync(string symbol);
// Get balances
Task<WebCallResult<IEnumerable<Balance>>> GetBalancesAsync(string? accountId = null);
// Place an order
Task<WebCallResult<OrderId>> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, string? accountId = null);
// Get order by order id
Task<WebCallResult<Order>> GetOrderAsync(string orderId, string? symbol = null);
// Get the trades for an order
Task<WebCallResult<IEnumerable<UserTrade>>> GetOrderTradesAsync(string orderId, string? symbol = null);
// Get a list of open orders. Some exchanges require a symbol
Task<WebCallResult<IEnumerable<Order>>> GetOpenOrdersAsync(string? symbol = null);
// Get a list of closed orders. Some exchanges require a symbol
Task<WebCallResult<IEnumerable<Order>>> GetClosedOrdersAsync(string? symbol = null);
// Cancel an active order
Task<WebCallResult<OrderId>> CancelOrderAsync(string orderId, string? symbol = null);
```
## IFuturesClient
The `IFuturesClient` interface is implemented on Futures API clients. The interface exposes basic functionality like retrieving market data and managing orders. The `IFuturesClient` interface will be available via the `CommonFuturesClient` property on the Api client.
The spot client has the following members:
*Properties*
```csharp
// The name of the exchange this client interacts with
string ExchangeName { get; }
```
*Events*
```csharp
// Event when placing an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `PlaceOrderAsync` method is called.
event Action<OrderId> OnOrderPlaced;
// Event when canceling an order with this ISpotClient. Note that this is not an event handler listening on the exchange, just an event handler for when the `CancelOrderAsync` method is called.
event Action<OrderId> OnOrderCanceled;
```
*Methods*
```csharp
// Retrieve the name of a symbol based on 2 assets. This will format them in the way the exchange expects them. For example BTC, USDT will return BTCUSDT on Binance and BTC-USDT on Kucoin
string GetSymbolName(string baseAsset, string quoteAsset);
// Get a list of symbols (trading pairs) on the exchange
Task<WebCallResult<IEnumerable<Symbol>>> GetSymbolsAsync();
// Get the ticker (24 hour stats) for a symbol
Task<WebCallResult<Ticker>> GetTickerAsync(string symbol);
// Get a list of tickers for all symbols
Task<WebCallResult<IEnumerable<Ticker>>> GetTickersAsync();
// Get a list klines (candlesticks) for a symbol
Task<WebCallResult<IEnumerable<Kline>>> GetKlinesAsync(string symbol, TimeSpan timespan, DateTime? startTime = null, DateTime? endTime = null, int? limit = null);
// Get the order book for a symbol
Task<WebCallResult<OrderBook>> GetOrderBookAsync(string symbol);
// Get a list of most recent trades
Task<WebCallResult<IEnumerable<Trade>>> GetRecentTradesAsync(string symbol);
// Get balances
Task<WebCallResult<IEnumerable<Balance>>> GetBalancesAsync(string? accountId = null);
// Get current open positions
Task<WebCallResult<IEnumerable<Position>>> GetPositionsAsync();
// Place an order
Task<WebCallResult<OrderId>> PlaceOrderAsync(string symbol, CommonOrderSide side, CommonOrderType type, decimal quantity, decimal? price = null, int? leverage = null, string? accountId = null);
// Get order by order id
Task<WebCallResult<Order>> GetOrderAsync(string orderId, string? symbol = null);
// Get the trades for an order
Task<WebCallResult<IEnumerable<UserTrade>>> GetOrderTradesAsync(string orderId, string? symbol = null);
// Get a list of open orders. Some exchanges require a symbol
Task<WebCallResult<IEnumerable<Order>>> GetOpenOrdersAsync(string? symbol = null);
// Get a list of closed orders. Some exchanges require a symbol
Task<WebCallResult<IEnumerable<Order>>> GetClosedOrdersAsync(string? symbol = null);
// Cancel an active order
Task<WebCallResult<OrderId>> CancelOrderAsync(string orderId, string? symbol = null);
```
-150
View File
@@ -1,150 +0,0 @@
---
title: Logging
nav_order: 5
---
## Configuring logging
The library offers extensive logging, which depends on the dotnet `Microsoft.Extensions.Logging.ILogger` interface. This should provide ease of use when connecting the library logging to your existing logging implementation.
*Configure logging to write to the console*
```csharp
IServiceCollection services = new ServiceCollection();
services
.AddBinance()
.AddLogging(options =>
{
options.SetMinimumLevel(LogLevel.Trace);
options.AddConsole();
});
```
The library provides a TraceLogger ILogger implementation which writes log messages using `Trace.WriteLine`, but any other logging library can be used.
*Configure logging to use trace logging*
```csharp
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddBinance()
.AddLogging(options =>
{
options.SetMinimumLevel(LogLevel.Trace);
options.AddProvider(new TraceLoggerProvider());
});
```
### Using an external logging library and dotnet DI
With for example an ASP.Net Core or Blazor project the logging can be configured by the dependency container, which can then automatically be used be the clients.
The next example shows how to use Serilog. This assumes the `Serilog.AspNetCore` package (https://github.com/serilog/serilog-aspnetcore) is installed.
*Using serilog:*
```csharp
using Binance.Net;
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBinance();
builder.Host.UseSerilog();
var app = builder.Build();
// startup
app.Run();
```
### Logging without dotnet DI
If you don't have a dependency injection service available because you are for example working on a simple console application you have 2 options for logging.
#### Create a ServiceCollection manually and get the client from the service provider
```csharp
IServiceCollection serviceCollection = new ServiceCollection();
serviceCollection.AddBinance();
serviceCollection.AddLogging(options =>
{
options.SetMinimumLevel(LogLevel.Trace);
options.AddConsole();
}).BuildServiceProvider();
var client = serviceCollection.GetRequiredService<IBinanceRestClient>();
```
#### Create a LoggerFactory manually
```csharp
var logFactory = new LoggerFactory();
logFactory.AddProvider(new ConsoleLoggerProvider());
var binanceClient = new BinanceRestClient(new HttpClient(), logFactory, options => { });
```
## Providing logging for issues
A big debugging tool when opening an issue on Github is providing logging of what data caused the issue. This can be provided two ways, via the `OriginalData` property of the call result or data event, or collecting the Trace logging.
### OriginalData
This is only useful when there is an issue in deserialization. So either a call result is giving a Deserialization error, or the result has a value that is unexpected. If that is the issue, please provide the original data that is received so the deserialization issue can be resolved based on the received data.
By default the `OriginalData` property in the `WebCallResult`/`DataEvent` object is not filled as saving the original data has a (very small) performance penalty. To save the original data in the `OriginalData` property the `OutputOriginalData` option should be set to `true` in the client options.
*Enabled output data*
```csharp
var client = new BinanceClient(options =>
{
options.OutputOriginalData = true
});
```
*Accessing original data*
```csharp
// Rest request
var tickerResult = await client.SpotApi.ExchangeData.GetTickersAsync();
var originallyReceivedData = tickerResult.OriginalData;
// Socket update
await client.SpotStreams.SubscribeToAllTickerUpdatesAsync(update => {
var originallyRecievedData = update.OriginalData;
});
```
### Trace logging
Trace logging, which is the most verbose log level, will show everything the library does and includes the data that was send and received.
Output data will look something like this:
```
2021-12-17 10:40:42:296 | Debug | Binance | Client configuration: LogLevel: Trace, Writers: 1, OutputOriginalData: False, Proxy: -, AutoReconnect: True, ReconnectInterval: 00:00:05, MaxReconnectTries: , MaxResubscribeTries: 5, MaxConcurrentResubscriptionsPerSocket: 5, SocketResponseTimeout: 00:00:10, SocketNoDataTimeout: 00:00:00, SocketSubscriptionsCombineTarget: , CryptoExchange.Net: v5.0.0.0, Binance.Net: v8.0.0.0
2021-12-17 10:40:42:410 | Debug | Binance | [15] Creating request for https://api.binance.com/api/v3/ticker/24hr
2021-12-17 10:40:42:439 | Debug | Binance | [15] Sending GET request to https://api.binance.com/api/v3/ticker/24hr?symbol=BTCUSDT with headers Accept=[application/json], X-MBX-APIKEY=[XXX]
2021-12-17 10:40:43:024 | Debug | Binance | [15] Response received in 571ms: {"symbol":"BTCUSDT","priceChange":"-1726.47000000","priceChangePercent":"-3.531","weightedAvgPrice":"48061.51544204","prevClosePrice":"48901.44000000","lastPrice":"47174.97000000","lastQty":"0.00352000","bidPrice":"47174.96000000","bidQty":"0.65849000","askPrice":"47174.97000000","askQty":"0.13802000","openPrice":"48901.44000000","highPrice":"49436.43000000","lowPrice":"46749.55000000","volume":"33136.69765000","quoteVolume":"1592599905.80360790","openTime":1639647642763,"closeTime":1639734042763,"firstId":1191596486,"lastId":1192649611,"count":1053126}
```
When opening an issue, please provide this logging when available.
### Example of serilog config and minimal API's
```csharp
using Binance.Net;
using Binance.Net.Interfaces.Clients;
using Serilog;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console()
.CreateLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddBinance();
builder.Host.UseSerilog();
var app = builder.Build();
// startup
app.Urls.Add("http://localhost:3000");
app.MapGet("/price/{symbol}", async (string symbol) =>
{
var client = app.Services.GetRequiredService<IBinanceRestClient>();
var result = await client.SpotApi.ExchangeData.GetPriceAsync(symbol);
return result.Data.Price;
});
app.Run();
```
-73
View File
@@ -1,73 +0,0 @@
---
title: Migrate v5 to v6
nav_order: 10
---
## Migrating from version 5 to version 6
When updating your code from version 5 implementations to version 6 implementations you will encounter some breaking changes. Here is the general outline of changes made in the CryptoExchange.Net library. For more specific changes for each library visit the library migration guide.
*NOTE when updating it is not possible to have some client implementations use a V5 version and some clients a V6. When updating all libraries should be migrated*
## Rest client name
To be more clear about different clients for different API's the rest client implementations have been renamed from [Exchange]Client to [Exchange]RestClient. This makes it more clear that it only implements the Rest API and the [Exchange]SocketClient the Socket API.
## Options
Option parameters have been changed to a callback instead of an options object. This makes processing of the options easier and is in line with how dotnet handles option configurations.
**BaseAddress**
The BaseAddress option has been replaced by the Environment option. The Environment options allows for selection/switching between different trade environments more easily. For example the environment can be switched between a testnet and live by changing only a single line instead of having to change all BaseAddresses.
**LogLevel/LogWriters**
The logging options have been removed and are now inherited by the DI configuration. See [Logging](https://jkorf.github.io/CryptoExchange.Net/Logging.html) for more info.
**HttpClient**
The HttpClient will now be received by the DI container instead of having to pass it manually. When not using DI it is still possible to provide a HttpClient, but it is now located in the client constructor.
*V5*
```csharp
var client = new BinanceClient(new BinanceClientOptions(){
OutputOriginalData = true,
SpotApiOptions = new RestApiOptions {
BaseAddress = BinanceApiAddresses.TestNet.RestClientAddress
}
// Other options
});
```
*V6*
```csharp
var client = new BinanceClient(options => {
options.OutputOriginalData = true;
options.Environment = BinanceEnvironment.Testnet;
// Other options
});
```
## Socket api name
As socket API's are often more than just streams to subscribe to the name of the socket API clients have been changed from [Topic]Streams to [Topic]Api which matches the rest API client names. For example `SpotStreams` has become `SpotApi`, so `binanceSocketClient.UsdFuturesStreams.SubscribeXXX` has become `binanceSocketClient.UsdFuturesApi.SubscribeXXX`.
## Add[Exchange] extension method
With the change in options providing the DI extension methods for the IServiceCollection have also been changed slightly. Also the socket clients will now be registered as Singleton by default instead of Scoped.
*V5*
```csharp
builder.Services.AddKucoin((restOpts, socketOpts) =>
{
restOpts.LogLevel = LogLevel.Debug;
restOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
socketOpts.LogLevel = LogLevel.Debug;
socketOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
}, ServiceLifetime.Singleton);
```
*V6*
```csharp
builder.Services.AddKucoin((restOpts) =>
{
restOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
},
(socketOpts) =>
{
socketOpts.ApiCredentials = new KucoinApiCredentials("KEY", "SECRET", "PASS");
});
```
-133
View File
@@ -1,133 +0,0 @@
---
title: Client options
nav_order: 4
---
## Setting client options
Each implementation can be configured using client options. There are 2 ways to provide these, either via `[client].SetDefaultOptions([options]);`, or in the constructor of the client. The examples here use the `BinanceClient`, but usage is the same for each client.
*Set the default options to use for new clients*
```csharp
BinanceClient.SetDefaultOptions(options =>
{
options.OutputOriginalData = true;
options.ApiCredentials = new ApiCredentials("KEY", "SECRET");
// Override the api credentials for the Spot API
options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET");
});
```
*Set the options to use for a single new client*
```csharp
var client = new BinanceClient(options =>
{
options.OutputOriginalData = true;
options.ApiCredentials = new ApiCredentials("KEY", "SECRET");
// Override the api credentials for the Spot API
options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET");
});
```
When calling `SetDefaultOptions` each client created after that will use the options that were set, unless the specific option is overriden in the options that were provided to the client. Consider the following example:
```csharp
BinanceClient.SetDefaultOptions(options =>
{
options.OutputOriginalData = true;
});
var client = new BinanceClient(options =>
{
options.OutputOriginalData = false;
});
```
The client instance will have the following options:
`OutputOriginalData = false`
## Api options
The options are divided in two categories. The basic options, which will apply to everything the client does, and the Api options, which is limited to the specific API client (see [Clients](https://jkorf.github.io/CryptoExchange.Net/Clients.html)).
```csharp
var client = new BinanceRestClient(options =>
{
options.ApiCredentials = new ApiCredentials("GENERAL-KEY", "GENERAL-SECRET"),
options.SpotOptions.ApiCredentials = new ApiCredentials("SPOT-KEY", "SPOT-SECRET");
});
```
The options provided in the SpotApiOptions are only applied to the SpotApi (`client.SpotApi.XXX` endpoints), while the base options are applied to everything. This means that the spot endpoints will use the "SPOT-KEY" credentials, while all other endpoints (`client.UsdFuturesApi.XXX` / `client.CoinFuturesApi.XXX`) will use the "GENERAL-KEY" credentials.
## CryptoExchange.Net options definitions
All clients have access to the following options, specific implementations might have additional options.
**Base client options**
|Option|Description|Default|
|------|-----------|-------|
|`OutputOriginalData`|If set to `true` the originally received Json data will be output as well as the deserialized object. For `RestClient` calls the data will be in the `WebCallResult<T>.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent<T>.OriginalData` property when receiving an update. | `false`
|`ApiCredentials`| The API credentials to use for accessing protected endpoints. Can either be an API key/secret using Hmac encryption or an API key/private key using RSA encryption for exchanges that support that. See [Credentials](#credentials). Note that this is a `default` value for all API clients, and can be overridden per API client. See the `Base Api client options`| `null`
|`Proxy`|The proxy to use for connecting to the API.| `null`
|`RequestTimeout`|The timeout for client requests to the server| `TimeSpan.FromSeconds(20)`
**Rest client options (extension of base client options)**
|Option|Description|Default|
|------|-----------|-------|
|`AutoTimestamp`|Whether or not the library should attempt to sync the time between the client and server. If the time between server and client is not in sync authentication errors might occur. This option should be disabled when the client time sure is to be in sync.|`true`|
|`TimestampRecalculationInterval`|The interval of how often the time synchronization between client and server should be executed| `TimeSpan.FromHours(1)`
|`Environment`|The environment the library should talk to. Some exchanges have testnet/sandbox environments which can be used instead of the real exchange. The environment option can be used to switch between different trade environments|`Live environment`
**Socket client options (extension of base client options)**
|Option|Description|Default|
|------|-----------|-------|
|`AutoReconnect`|Whether or not the socket should attempt to automatically reconnect when disconnected.|`true`
|`ReconnectInterval`|The time to wait between connection tries when reconnecting.|`TimeSpan.FromSeconds(5)`
|`SocketResponseTimeout`|The time in which a response is expected on a request before giving a timeout.|`TimeSpan.FromSeconds(10)`
|`SocketNoDataTimeout`|If no data is received after this timespan then assume the connection is dropped. This is mainly used for API's which have some sort of ping/keepalive system. For example; the Bitfinex API will sent a heartbeat message every 15 seconds, so the `SocketNoDataTimeout` could be set to 20 seconds. On API's without such a mechanism this might not work because there just might not be any update while still being fully connected. | `default(TimeSpan)` (no timeout)
|`SocketSubscriptionsCombineTarget`|The amount of subscriptions that should be made on a single socket connection. Not all exchanges support multiple subscriptions on a single socket. Setting this to a higher number increases subscription speed because not every subscription needs to connect to the server, but having more subscriptions on a single connection will also increase the amount of traffic on that single connection, potentially leading to issues.| Depends on implementation
|`MaxConcurrentResubscriptionsPerSocket`|The maximum number of concurrent resubscriptions per socket when resubscribing after reconnecting|5
|`MaxSocketConnections`|The maximum amount of distinct socket connections|`null`
|`DelayAfterConnect`|The time to wait before sending messages after connecting to the server.|`TimeSpan.Zero`
|`Environment`|The environment the library should talk to. Some exchanges have testnet/sandbox environments which can be used instead of the real exchange. The environment option can be used to switch between different trade environments|`Live environment`
**Base Api client options**
|Option|Description|Default|
|------|-----------|-------|
|`ApiCredentials`|The API credentials to use for accessing protected endpoints. Can either be an API key/secret using Hmac encryption or an API key/private key using RSA encryption for exchanges that support that. See [Credentials](#credentials). Setting ApiCredentials on the Api Options will override any default ApiCredentials on the `Base client options`| `null`
|`OutputOriginalData`|If set to `true` the originally received Json data will be output as well as the deserialized object. For `RestClient` calls the data will be in the `WebCallResult<T>.OriginalData` property, for `SocketClient` subscriptions the data will be available in the `DataEvent<T>.OriginalData` property when receiving an update.|False
**Options for Rest Api Client (extension of base api client options)**
|Option|Description|Default|
|------|-----------|-------|
|`RateLimiters`|A list of `IRateLimiter`s to use.|`new List<IRateLimiter>()`|
|`RateLimitingBehaviour`|What should happen when a rate limit is reached.|`RateLimitingBehaviour.Wait`|
|`AutoTimestamp`|Whether or not the library should attempt to sync the time between the client and server. If the time between server and client is not in sync authentication errors might occur. This option should be disabled when the client time is sure to be in sync. Overrides the Rest client options `AutoTimestamp` option if set|`null`|
|`TimestampRecalculationInterval`|The interval of how often the time synchronization between client and server should be executed. Overrides the Rest client options `TimestampRecalculationInterval` option if set| `TimeSpan.FromHours(1)`
**Options for Socket Api Client (extension of base api client options)**
|Option|Description|Default|
|------|-----------|-------|
|`SocketNoDataTimeout`|If no data is received after this timespan then assume the connection is dropped. This is mainly used for API's which have some sort of ping/keepalive system. For example; the Bitfinex API will sent a heartbeat message every 15 seconds, so the `SocketNoDataTimeout` could be set to 20 seconds. On API's without such a mechanism this might not work because there just might not be any update while still being fully connected. Overrides the Socket client options `SocketNoDataTimeout` option if set | `default(TimeSpan)` (no timeout)
|`MaxSocketConnections`|The maximum amount of distinct socket connections. Overrides the Socket client options `MaxSocketConnections` option if set |`null`
## Credentials
Credentials are supported in 3 formats in the base library:
|Type|Description|Example|
|----|-----------|-------|
|`Hmac`|An API key + secret combination. The API key is send with the request and the secret is used to sign requests. This is the default authentication method on all exchanges. |`options.ApiCredentials = new ApiCredentials("51231f76e-9c503548-8fabs3f-rfgf12mkl3", "556be32-d563ba53-faa2dfd-b3n5c", CredentialType.Hmac);`|
|`RsaPem`|An API key + a public and private key pair generated by the user. The public key is shared with the exchange, while the private key is used to sign requests. This CredentialType expects the private key to be in .pem format and is only supported in .netstandard2.1 due to limitations of the framework|`options.ApiCredentials = new ApiCredentials("432vpV8daAaXAF4Qg", ""-----BEGIN PRIVATE KEY-----[PRIVATEKEY]-----END PRIVATE KEY-----", CredentialType.RsaPem);`|
|`RsaXml`|An API key + a public and private key pair generated by the user. The public key is shared with the exchange, while the private key is used to sign requests. This CredentialType expects the private key to be in xml format and is supported in .netstandard2.0 and .netstandard2.1, but it might mean the private key needs to be converted from the original format to xml|`options.ApiCredentials = new ApiCredentials("432vpV8daAaXAF4Qg", "<RSAKeyValue>[PRIVATEKEY]</RSAKeyValue>", CredentialType.RsaXml);`|
-68
View File
@@ -1,68 +0,0 @@
---
title: Order books
nav_order: 6
---
## Locally synced order book
Each exchange implementation provides an order book implementation. These implementations will provide a client side order book and will take care of synchronization with the server, and will handle reconnecting and resynchronizing in case of a dropped connection.
Order book implementations are named as `[ExchangeName][Type]SymbolOrderBook`, for example `BinanceSpotSymbolOrderBook`.
## Usage
Start the book synchronization by calling the `StartAsync` method. This returns whether the book is successfully synchronized and started. You can listen to the `OnStatusChange` event to be notified of when the status of a book changes. Note that the order book is only synchronized with the server when the state is `Synced`. When the order book has been started and the state changes from `Synced` to `Reconnecting` the book will automatically reconnect and resync itself.
*Start an order book and print the top 3 rows*
```csharp
var book = new BinanceSpotSymbolOrderBook("BTCUSDT");
book.OnStatusChange += (oldState, newState) => Console.WriteLine($"State changed from {oldState} to {newState}");
var startResult = await book.StartAsync();
if (!startResult.Success)
{
Console.WriteLine("Failed to start order book: " + startResult.Error);
return;
}
while(true)
{
Console.Clear();
Console.WriteLine(book.ToString(3);
await Task.Delay(500);
}
```
### Accessing bids/asks
You can access the current Bid/Ask lists using the responding properties:
`var currentBidList = book.Bids;`
`var currentAskList = book.Asks;`
Note that these will return copies of the internally synced lists when accessing the properties, and when accessing them in sequence like above does mean that the lists may not be in sync with eachother since they're accessed at different points in time.
When you need both lists in sync you should access the `Book` property.
`var (currentBidList, currentAskList) = book.Book;`
Because copies of the lists are made when accessing the bids/asks properties the performance impact should be considered. When only the current best ask/bid info is needed you can access the `BestOffers` property.
`var (bestBid, bestAsk) = book.BestOffers;`
### Events
The following events are available on the symbol order book:
`book.OnStatusChange`: The book has changed state. This happens during connecting, the connection was lost or the order book was detected to be out of sync. The asks/bids are only the actual with the server when state is `Synced`.
`book.OnOrderBookUpdate`: The book has changed, the arguments contain the changed entries.
`book.OnBestOffersChanged`: The best offer (best bid, best ask) has changed.
```csharp
book.OnStatusChange += (oldStatus, newStatus) => { Console.WriteLine($"State changed from {oldStatus} to {newStatus}"); };
book.OnOrderBookUpdate += (bidsAsks) => { Console.WriteLine($"Order book changed: {bidsAsks.Asks.Count()} asks, {bidsAsks.Bids.Count()} bids"); };
book.OnBestOffersChanged += (bestOffer) => { Console.WriteLine($"Best offer changed, best bid: {bestOffer.BestBid.Price}, best ask: {bestOffer.BestAsk.Price}"); };
```
### Order book factory
Each exchange implementation also provides an order book factory for creating ISymbolOrderBook instances. The naming convention for the factory is `[Exchange]OrderBookFactory`, for example `BinanceOrderBookFactory`. This type will be automatically added when using DI and can be used to facilitate easier testing.
*Creating an order book using the order book factory*
```csharp
var factory = services.GetRequiredService<IKucoinOrderBookFactory>();
var book = factory.CreateSpot("ETH-USDT");
var startResult = await book.StartAsync();
```
-74
View File
@@ -1,74 +0,0 @@
---
title: Rate limiting
nav_order: 9
---
## Rate limiting
The library has build in rate limiting. These rate limits can be configured per client. Some client implementations where the exchange has clear rate limits will also have a default rate limiter already set up.
Rate limiting is configured in the client options, and can be set on a specific client or for all clients by either providing it in the constructor for a client, or by using the `SetDefaultOptions` on a client.
What to do when a limit is reached can be configured with the `RateLimitingBehaviour` client options, which has 2 possible options. Setting it to `Fail` will cause a request to fail without sending it. Setting it to `Wait` will cause the request to wait until the request can be send in accordance to the rate limiter.
A rate limiter can be configured in the options like so:
```csharp
new ClientOptions
{
RateLimitingBehaviour = RateLimitingBehaviour.Wait,
RateLimiters = new List<IRateLimiter>
{
new RateLimiter()
.AddTotalRateLimit(50, TimeSpan.FromSeconds(10))
}
}
```
This will add a rate limiter for 50 requests per 10 seconds.
A rate limiter can have multiple limits:
```csharp
new RateLimiter()
.AddTotalRateLimit(50, TimeSpan.FromSeconds(10))
.AddEndpointLimit("/api/order", 10, TimeSpan.FromSeconds(2))
```
This adds another limit of 10 requests per 2 seconds in addition to the 50 requests per 10 seconds limit.
These are the available rate limit configurations:
### AddTotalRateLimit
|Parameter|Description|
|---------|-----------|
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|perTimePeriod|The time period over which the limit is enforced|
A rate limit for the total amount of requests for all requests send from the client.
### AddEndpointLimit
|Parameter|Description|
|---------|-----------|
|endpoint|The endpoint this limit is for|
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|perTimePeriod|The time period over which the limit is enforced|
|method|The HTTP method this limit is for. Defaults to all methods|
|excludeFromOtherRateLimits|When set to true requests to this endpoint won't be counted for other configured rate limits|
A rate limit for all requests send to a specific endpoint. Requests that do not fully match the endpoint will not be counted to this limit.
### AddPartialEndpointLimit
|Parameter|Description|
|---------|-----------|
|endpoint|The partial endpoint this limit is for. Partial means that a request will match this limiter when a part of the request URI path matches this endpoint|
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|perTimePeriod|The time period over which the limit is enforced|
|method|The HTTP method this limit is for. Defaults to all methods|
|countPerEndpoint|Whether all requests matching the endpoint pattern should be combined for this limit or each endpoint has its own limit|
|ignoreOtherRateLimits|When set to true requests to this endpoint won't be counted for other configured rate limits|
A rate limit for a partial endpoint. Requests will be counted towards this limit if the request path contains the endpoint. For example request `/api/v2/test` will match when the partial endpoint limit is set for `/api/v2`.
### AddApiKeyLimit
|Parameter|Description|
|---------|-----------|
|limit|The request weight limit per time period. Note that requests can have a weight specified. Default requests will have a weight of 1|
|perTimePeriod|The time period over which the limit is enforced|
|onlyForSignedRequests|Whether this rate limit should only be counter for signed/authenticated requests|
|excludeFromTotalRateLimit|Whether requests counted for this rate limited should not be counted towards the total rate limit|
A rate limit for an API key. Requests with the same API key will be grouped and limited.
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Blue
==============================*/
::selection {
background: #007bff;
}
a, a:focus {
color: #007bff;
}
a:hover, a:active {
color: #006adb;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #007bff;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #007bff;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #007bff;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #007bff;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #007bff !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #007bff;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #007bff;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #007bff;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #007bff;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #007bff;
}
.nav-pills .nav-link:not(.active):hover {
color: #007bff;
}
#footer .nav .nav-item .nav-link:focus {
color: #007bff;
}
#footer .nav .nav-link:hover {
color: #007bff;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #007bff;
}
/* Back to Top */
#back-to-top:hover {
background-color: #007bff;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #007bff !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #007bff !important;
}
.btn-link:hover {
color: #006adb !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #006adb !important;
}
.border-primary {
border-color: #007bff !important;
}
.btn-primary {
background-color: #007bff;
border-color: #007bff;
}
.btn-primary:hover {
background-color: #006adb;
border-color: #006adb;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #006adb;
border-color: #006adb;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #006adb;
border-color: #006adb;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #007bff;
border-color: #007bff;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #007bff;
border-color: #007bff;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #007bff;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #007bff;
border-color: #007bff;
}
.list-group-item.active {
background-color: #007bff;
border-color: #007bff;
}
.page-link {
color: #007bff;
}
.page-link:hover {
color: #006adb;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Brown
==============================*/
::selection {
background: #795548;
}
a, a:focus {
color: #795548;
}
a:hover, a:active {
color: #63453b;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #795548;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #795548;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #795548;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #795548;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #795548 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #795548;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #795548;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #795548;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #795548;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #795548;
}
.nav-pills .nav-link:not(.active):hover {
color: #795548;
}
#footer .nav .nav-item .nav-link:focus {
color: #795548;
}
#footer .nav .nav-link:hover {
color: #795548;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #795548;
}
/* Back to Top */
#back-to-top:hover {
background-color: #795548;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #795548 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #795548 !important;
}
.btn-link:hover {
color: #63453b !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #63453b !important;
}
.border-primary {
border-color: #795548 !important;
}
.btn-primary {
background-color: #795548;
border-color: #795548;
}
.btn-primary:hover {
background-color: #63453b;
border-color: #63453b;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #63453b;
border-color: #63453b;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #63453b;
border-color: #63453b;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #795548;
border-color: #795548;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #795548;
border-color: #795548;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #795548;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #795548;
border-color: #795548;
}
.list-group-item.active {
background-color: #795548;
border-color: #795548;
}
.page-link {
color: #795548;
}
.page-link:hover {
color: #63453b;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Cyan
==============================*/
::selection {
background: #17a2b8;
}
a, a:focus {
color: #17a2b8;
}
a:hover, a:active {
color: #138698;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #17a2b8;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #17a2b8;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #17a2b8;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #17a2b8;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #17a2b8 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #17a2b8;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #17a2b8;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #17a2b8;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #17a2b8;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #17a2b8;
}
.nav-pills .nav-link:not(.active):hover {
color: #17a2b8;
}
#footer .nav .nav-item .nav-link:focus {
color: #17a2b8;
}
#footer .nav .nav-link:hover {
color: #17a2b8;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #17a2b8;
}
/* Back to Top */
#back-to-top:hover {
background-color: #17a2b8;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #17a2b8 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #17a2b8 !important;
}
.btn-link:hover {
color: #138698 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #138698 !important;
}
.border-primary {
border-color: #17a2b8 !important;
}
.btn-primary {
background-color: #17a2b8;
border-color: #17a2b8;
}
.btn-primary:hover {
background-color: #138698;
border-color: #138698;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #138698;
border-color: #138698;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #138698;
border-color: #138698;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #17a2b8;
border-color: #17a2b8;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #17a2b8;
border-color: #17a2b8;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #17a2b8;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #17a2b8;
border-color: #17a2b8;
}
.list-group-item.active {
background-color: #17a2b8;
border-color: #17a2b8;
}
.page-link {
color: #17a2b8;
}
.page-link:hover {
color: #138698;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Green
==============================*/
::selection {
background: #28a745;
}
a, a:focus {
color: #28a745;
}
a:hover, a:active {
color: #218a39;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #28a745;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #28a745;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #28a745;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #28a745;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #28a745 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #28a745;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #28a745;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #28a745;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #28a745;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #28a745;
}
.nav-pills .nav-link:not(.active):hover {
color: #28a745;
}
#footer .nav .nav-item .nav-link:focus {
color: #28a745;
}
#footer .nav .nav-link:hover {
color: #28a745;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #28a745;
}
/* Back to Top */
#back-to-top:hover {
background-color: #28a745;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #28a745 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #28a745 !important;
}
.btn-link:hover {
color: #218a39 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #218a39 !important;
}
.border-primary {
border-color: #28a745 !important;
}
.btn-primary {
background-color: #28a745;
border-color: #28a745;
}
.btn-primary:hover {
background-color: #218a39;
border-color: #218a39;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #218a39;
border-color: #218a39;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #218a39;
border-color: #218a39;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #28a745;
border-color: #28a745;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #28a745;
border-color: #28a745;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #28a745;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #28a745;
border-color: #28a745;
}
.list-group-item.active {
background-color: #28a745;
border-color: #28a745;
}
.page-link {
color: #28a745;
}
.page-link:hover {
color: #218a39;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Indigo
==============================*/
::selection {
background: #6610f2;
}
a, a:focus {
color: #6610f2;
}
a:hover, a:active {
color: #570bd3;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #6610f2;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #6610f2;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #6610f2;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #6610f2;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #6610f2 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #6610f2;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #6610f2;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #6610f2;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #6610f2;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #6610f2;
}
.nav-pills .nav-link:not(.active):hover {
color: #6610f2;
}
#footer .nav .nav-item .nav-link:focus {
color: #6610f2;
}
#footer .nav .nav-link:hover {
color: #6610f2;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #6610f2;
}
/* Back to Top */
#back-to-top:hover {
background-color: #6610f2;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #6610f2 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #6610f2 !important;
}
.btn-link:hover {
color: #570bd3 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #570bd3 !important;
}
.border-primary {
border-color: #6610f2 !important;
}
.btn-primary {
background-color: #6610f2;
border-color: #6610f2;
}
.btn-primary:hover {
background-color: #570bd3;
border-color: #570bd3;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #570bd3;
border-color: #570bd3;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #570bd3;
border-color: #570bd3;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #6610f2;
border-color: #6610f2;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #6610f2;
border-color: #6610f2;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #6610f2;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #6610f2;
border-color: #6610f2;
}
.list-group-item.active {
background-color: #6610f2;
border-color: #6610f2;
}
.page-link {
color: #6610f2;
}
.page-link:hover {
color: #570bd3;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Orange
==============================*/
::selection {
background: #fd7e14;
}
a, a:focus {
color: #fd7e14;
}
a:hover, a:active {
color: #eb6c02;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #fd7e14;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #fd7e14;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #fd7e14;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #fd7e14;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #fd7e14 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #fd7e14;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #fd7e14;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #fd7e14;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #fd7e14;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #fd7e14;
}
.nav-pills .nav-link:not(.active):hover {
color: #fd7e14;
}
#footer .nav .nav-item .nav-link:focus {
color: #fd7e14;
}
#footer .nav .nav-link:hover {
color: #fd7e14;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #fd7e14;
}
/* Back to Top */
#back-to-top:hover {
background-color: #fd7e14;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #fd7e14 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #fd7e14 !important;
}
.btn-link:hover {
color: #eb6c02 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #eb6c02 !important;
}
.border-primary {
border-color: #fd7e14 !important;
}
.btn-primary {
background-color: #fd7e14;
border-color: #fd7e14;
}
.btn-primary:hover {
background-color: #eb6c02;
border-color: #eb6c02;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #eb6c02;
border-color: #eb6c02;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #eb6c02;
border-color: #eb6c02;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #fd7e14;
border-color: #fd7e14;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #fd7e14;
border-color: #fd7e14;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #fd7e14;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #fd7e14;
border-color: #fd7e14;
}
.list-group-item.active {
background-color: #fd7e14;
border-color: #fd7e14;
}
.page-link {
color: #fd7e14;
}
.page-link:hover {
color: #eb6c02;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Purple
==============================*/
::selection {
background: #6f42c1;
}
a, a:focus {
color: #6f42c1;
}
a:hover, a:active {
color: #5f37a8;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #6f42c1;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #6f42c1;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #6f42c1;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #6f42c1;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #6f42c1 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #6f42c1;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #6f42c1;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #6f42c1;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #6f42c1;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #6f42c1;
}
.nav-pills .nav-link:not(.active):hover {
color: #6f42c1;
}
#footer .nav .nav-item .nav-link:focus {
color: #6f42c1;
}
#footer .nav .nav-link:hover {
color: #6f42c1;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #6f42c1;
}
/* Back to Top */
#back-to-top:hover {
background-color: #6f42c1;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #6f42c1 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #6f42c1 !important;
}
.btn-link:hover {
color: #5f37a8 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #5f37a8 !important;
}
.border-primary {
border-color: #6f42c1 !important;
}
.btn-primary {
background-color: #6f42c1;
border-color: #6f42c1;
}
.btn-primary:hover {
background-color: #5f37a8;
border-color: #5f37a8;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #5f37a8;
border-color: #5f37a8;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #5f37a8;
border-color: #5f37a8;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #6f42c1;
border-color: #6f42c1;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #6f42c1;
border-color: #6f42c1;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #6f42c1;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #6f42c1;
border-color: #6f42c1;
}
.list-group-item.active {
background-color: #6f42c1;
border-color: #6f42c1;
}
.page-link {
color: #6f42c1;
}
.page-link:hover {
color: #5f37a8;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Red
==============================*/
::selection {
background: #dc3545;
}
a, a:focus {
color: #dc3545;
}
a:hover, a:active {
color: #ca2333;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #dc3545;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #dc3545;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #dc3545;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #dc3545;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #dc3545 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #dc3545;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #dc3545;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #dc3545;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #dc3545;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #dc3545;
}
.nav-pills .nav-link:not(.active):hover {
color: #dc3545;
}
#footer .nav .nav-item .nav-link:focus {
color: #dc3545;
}
#footer .nav .nav-link:hover {
color: #dc3545;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #dc3545;
}
/* Back to Top */
#back-to-top:hover {
background-color: #dc3545;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #dc3545 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #dc3545 !important;
}
.btn-link:hover {
color: #ca2333 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #ca2333 !important;
}
.border-primary {
border-color: #dc3545 !important;
}
.btn-primary {
background-color: #dc3545;
border-color: #dc3545;
}
.btn-primary:hover {
background-color: #ca2333;
border-color: #ca2333;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #ca2333;
border-color: #ca2333;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #ca2333;
border-color: #ca2333;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #dc3545;
border-color: #dc3545;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #dc3545;
border-color: #dc3545;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #dc3545;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #dc3545;
border-color: #dc3545;
}
.list-group-item.active {
background-color: #dc3545;
border-color: #dc3545;
}
.page-link {
color: #dc3545;
}
.page-link:hover {
color: #ca2333;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Teal
==============================*/
::selection {
background: #20c997;
}
a, a:focus {
color: #20c997;
}
a:hover, a:active {
color: #1baa80;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #20c997;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #20c997;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #20c997;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #20c997;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #20c997 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #20c997;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #20c997;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #20c997;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #20c997;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #20c997;
}
.nav-pills .nav-link:not(.active):hover {
color: #20c997;
}
#footer .nav .nav-item .nav-link:focus {
color: #20c997;
}
#footer .nav .nav-link:hover {
color: #20c997;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #20c997;
}
/* Back to Top */
#back-to-top:hover {
background-color: #20c997;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #20c997 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #20c997 !important;
}
.btn-link:hover {
color: #1baa80 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #1baa80 !important;
}
.border-primary {
border-color: #20c997 !important;
}
.btn-primary {
background-color: #20c997;
border-color: #20c997;
}
.btn-primary:hover {
background-color: #1baa80;
border-color: #1baa80;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #1baa80;
border-color: #1baa80;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #1baa80;
border-color: #1baa80;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #20c997;
border-color: #20c997;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #20c997;
border-color: #20c997;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #20c997;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #20c997;
border-color: #20c997;
}
.list-group-item.active {
background-color: #20c997;
border-color: #20c997;
}
.page-link {
color: #20c997;
}
.page-link:hover {
color: #1baa80;
}
+159
View File
@@ -0,0 +1,159 @@
/*============================
COLOR Yellow
==============================*/
::selection {
background: #ffc107;
}
a, a:focus {
color: #ffc107;
}
a:hover, a:active {
color: #f7b900;
}
.primary-menu ul.navbar-nav > li:hover > a:not(.btn), .primary-menu ul.navbar-nav > li > a.active:not(.btn) {
color: #ffc107;
}
.primary-menu ul.navbar-nav > li.dropdown .dropdown-menu li:hover > a:not(.btn) {
color: #ffc107;
}
.primary-menu.navbar-line-under-text ul.navbar-nav > li > a:not(.btn):after {
border-color: #ffc107;
}
/*=== Side Navigation ===*/
.idocs-navigation .nav .nav .nav-item .nav-link.active:after, .idocs-navigation.docs-navigation-dark .nav .nav .nav-item .nav-link.active:after {
border-color: #ffc107;
}
/* Accordion & Toggle */
.accordion .card-header a:hover.collapsed {
color: #ffc107 !important;
}
.accordion:not(.accordion-alternate) .card-header a {
background-color: #ffc107;
color: #fff;
}
/* Nav */
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover {
color: #ffc107;
}
.nav-tabs .nav-item .nav-link.active {
color: #0c2f55;
}
.nav-tabs .nav-item .nav-link.active:after {
background-color: #ffc107;
}
.nav-tabs .nav-item .nav-link:not(.active):hover {
color: #ffc107;
}
.nav-tabs.flex-column .nav-item .nav-link.active {
color: #ffc107;
}
.nav-pills .nav-link:not(.active):hover {
color: #ffc107;
}
#footer .nav .nav-item .nav-link:focus {
color: #ffc107;
}
#footer .nav .nav-link:hover {
color: #ffc107;
}
#footer .footer-copyright .nav .nav-link:hover {
color: #ffc107;
}
/* Back to Top */
#back-to-top:hover {
background-color: #ffc107;
}
/* Extras */
.bg-primary, .badge-primary {
background-color: #ffc107 !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: #ffc107 !important;
}
.btn-link:hover {
color: #f7b900 !important;
}
.text-muted {
color: #8e9a9d !important;
}
.text-light {
color: #dee3e4 !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover {
background-color: #f7b900 !important;
}
.border-primary {
border-color: #ffc107 !important;
}
.btn-primary {
background-color: #ffc107;
border-color: #ffc107;
}
.btn-primary:hover {
background-color: #f7b900;
border-color: #f7b900;
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active {
background-color: #f7b900;
border-color: #f7b900;
}
.btn-primary.focus, .btn-primary:focus {
background-color: #f7b900;
border-color: #f7b900;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active {
color: #ffc107;
border-color: #ffc107;
}
.btn-outline-primary:hover, .btn-outline-primary:not(:disabled):not(.disabled).active:hover, .btn-outline-primary:not(:disabled):not(.disabled):active:hover {
background-color: #ffc107;
border-color: #ffc107;
color: #fff;
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active {
background-color: #ffc107;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before {
background-color: #ffc107;
border-color: #ffc107;
}
.list-group-item.active {
background-color: #ffc107;
border-color: #ffc107;
}
.page-link {
color: #ffc107;
}
.page-link:hover {
color: #f7b900;
}
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

+162
View File
@@ -0,0 +1,162 @@
/*
================================================================
* Template: iDocs - One Page Documentation HTML Template
* Written by: Harnish Design - (http://www.harnishdesign.net)
* Description: Main Custom Script File
================================================================
*/
(function ($) {
"use strict";
// Preloader
$(window).on('load', function () {
$('.lds-ellipsis').fadeOut(); // will first fade out the loading animation
$('.preloader').delay(333).fadeOut('slow'); // will fade out the white DIV that covers the website.
$('body').delay(333);
});
/*-------------------------------
Primary Menu
--------------------------------- */
// Dropdown show on hover
$('.primary-menu ul.navbar-nav li.dropdown, .login-signup ul.navbar-nav li.dropdown').on("mouseover", function() {
if ($(window).width() > 991) {
$(this).find('> .dropdown-menu').stop().slideDown('fast');
$(this).bind('mouseleave', function() {
$(this).find('> .dropdown-menu').stop().css('display', 'none');
});
}
});
// When dropdown going off to the out of the screen.
$('.primary-menu ul.navbar-nav .dropdown-menu').each(function() {
var menu = $('#header .container-fluid').offset();
var dropdown = $(this).parent().offset();
var i = (dropdown.left + $(this).outerWidth()) - (menu.left + $('#header .container-fluid').outerWidth());
if (i > 0) {
$(this).css('margin-left', '-' + (i + 5) + 'px');
}
});
$(function () {
$(".dropdown li").on('mouseenter mouseleave', function (e) {
if ($(window).width() > 991) {
var elm = $('.dropdown-menu', this);
var off = elm.offset();
var l = off.left;
var w = elm.width();
var docW = $(window).width();
var isEntirelyVisible = (l + w + 30 <= docW);
if (!isEntirelyVisible) {
$(elm).addClass('dropdown-menu-right');
} else {
$(elm).removeClass('dropdown-menu-right');
}
}
});
});
// DropDown Arrow
$('.primary-menu ul.navbar-nav').find('a.dropdown-toggle').append($('<i />').addClass('arrow'));
// Mobile Collapse Nav
$('.primary-menu .navbar-nav .dropdown-toggle[href="#"], .primary-menu .dropdown-toggle[href!="#"] .arrow').on('click', function(e) {
if ($(window).width() < 991) {
e.preventDefault();
var $parentli = $(this).closest('li');
$parentli.siblings('li').find('.dropdown-menu:visible').slideUp();
$parentli.find('> .dropdown-menu').stop().slideToggle();
$parentli.siblings('li').find('a .arrow.show').toggleClass('show');
$parentli.find('> a .arrow').toggleClass('show');
}
});
// Mobile Menu
$('.navbar-toggler').on('click', function() {
$(this).toggleClass('show');
});
/*------------------------
Side Navigation
-------------------------- */
$('#sidebarCollapse').on('click', function () {
$('#sidebarCollapse span:nth-child(3)').toggleClass('w-50');
$('.idocs-navigation').toggleClass('active');
});
/*------------------------
Sections Scroll
-------------------------- */
$('.smooth-scroll,.idocs-navigation a').on('click', function() {
event.preventDefault();
var sectionTo = $(this).attr('href');
$('html, body').stop().animate({
scrollTop: $(sectionTo).offset().top - 120}, 1000, 'easeInOutExpo');
});
/*-----------------------------
Magnific Popup
------------------------------- */
// Image on Modal
$('.popup-img').each(function() {
$(this).magnificPopup({
type: "image",
tLoading: '<div class="preloader"><div class="lds-ellipsis"><div></div><div></div><div></div><div></div></div></div>',
closeOnContentClick: !0,
mainClass: "mfp-fade",
});
});
// YouTube/Viemo Video & Gmaps
$('.popup-youtube, .popup-vimeo, .popup-gmaps').each(function() {
$(this).magnificPopup({
type: 'iframe',
mainClass: 'mfp-fade',
});
});
/*------------------------
Highlight Js
-------------------------- */
hljs.initHighlightingOnLoad();
/*------------------------
tooltips
-------------------------- */
$('[data-toggle=\'tooltip\']').tooltip({container: 'body'});
/*------------------------
Scroll to top
-------------------------- */
$(function () {
$(window).on('scroll', function(){
if ($(this).scrollTop() > 400) {
$('#back-to-top').fadeIn();
} else {
$('#back-to-top').fadeOut();
}
});
});
$('#back-to-top').on("click", function() {
$('html, body').animate({scrollTop:0}, 'slow');
return false;
});
})(jQuery)
+537
View File
@@ -0,0 +1,537 @@
/* =================================== */
/* 5. Elements
/* =================================== */
/*=== 5.1 List Style ===*/
.list-style-1 > li {
position: relative;
list-style-type: none;
line-height: 24px;
&:after {
content: " ";
position: absolute;
top: 12px;
left: -15px;
border-color: #000;
border-top: 1px solid;
border-right: 1px solid;
width: 6px;
height: 6px;
-webkit-transform: translate(-50%, -50%) rotate(45deg);
transform: translate(-50%, -50%) rotate(45deg);
}
}
.list-style-2{padding:0;}
.list-style-2 > li {
list-style-type: none;
border-bottom: 1px solid #eaeaea;
padding-top: 12px;
padding-bottom: 12px;
}
.list-style-2.list-style-light > li {
border-bottom: 1px solid rgba(250,250,250,0.12);
}
/*=== 5.2 Changelog ===*/
.changelog {
list-style: none;
padding: 0;
.badge {
width: 90px;
margin-right: 10px;
border-radius: .20rem;
text-transform: uppercase;
}
li {
line-height: 1.8;
}
}
/*=== 5.3 Accordion & Toggle ===*/
.accordion {
.card {
border: none;
margin-bottom: 16px;
margin-bottom: 1rem;
background-color: transparent;
}
.card-header {
padding: 0;
border: none;
background: none;
a {
font-size: 16px;
font-weight:normal;
padding: 1rem 1.25rem 1rem 2.25rem;
display: block;
border-radius: 4px;
position: relative;
&:hover{
text-decoration:none;
}
&:hover.collapsed {
color: $primary-color!important;
}
}
}
&:not(.accordion-alternate) .card-header a {
background-color: $primary-color;
color: #fff;
&.collapsed {
background-color: #f1f2f4;
color: #4c4d4d;
}
}
.card-header a {
&:before {
position: absolute;
content: " ";
left: 20px;
top: calc(50% + 2px);
width: 9px;
height: 9px;
border-color: #CCC;
border-top: 2px solid;
border-right: 2px solid;
-webkit-transform: translate(-50%, -50%) rotate(-45deg);
transform: translate(-50%, -50%) rotate(-45deg);
@include transition(all 0.2s ease);
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
&.collapsed:before {
top: calc(50% - 2px);
-webkit-transform: translate(-50%, -50%) rotate(135deg);
transform: translate(-50%, -50%) rotate(135deg);
}
}
.card-body {
line-height: 26px;
}
&.arrow-right .card-header a{
padding-left:1.25rem;
&:before {
right: 15px;
left: auto;
}
}
&.accordion-alternate {
.card {
margin: 0;
}
.card-header a {
padding-left: 1.40rem;
border-top: 1px solid #e4e9ec;
border-radius: 0px;
}
.card:first-of-type .card-header a {
border-top: 0px;
}
.card-header a {
&:before {
left: 6px;
}
&.collapsed {
color: #4c4d4d;
}
}
.card-body {
padding: 0rem 0 1rem 1.25rem;
}
&.arrow-right .card-header a{
padding-left:0;
&:before {
right: 0px;
left: auto;
}
}
}
&.toggle .card-header a {
&:before {
content: "-";
border: none;
font-size: 20px;
height: auto;
top: calc(50% + 2px);
width: auto;
-webkit-transform: translate(-50%, -50%) rotate(180deg);
transform: translate(-50%, -50%) rotate(180deg);
}
&.collapsed:before {
content: "+";
top: calc(50% - 1px);
-webkit-transform: translate(-50%, -50%) rotate(0deg);
transform: translate(-50%, -50%) rotate(0deg);
}
}
&.accordion-alternate.style-2 {
.card-header a {
&:before {
right: 2px;
left: auto;
-webkit-transform: translate(-50%, -50%) rotate(135deg);
transform: translate(-50%, -50%) rotate(135deg);
top: 50%;
}
&.collapsed:before {
-webkit-transform: translate(-50%, -50%) rotate(45deg);
transform: translate(-50%, -50%) rotate(45deg);
}
padding-left: 0px;
}
.card-body {
padding-left: 0px;
}
}
&.accordion-alternate.popularRoutes {
.card-header {
.nav {
margin-top: 3px;
a {
font-size: 14px;
}
}
a {
padding: 0px 8px 0px 0px;
border: none;
font-size: inherit;
&:before {
content: none;
}
}
h5 {
cursor: pointer;
&:before {
position: absolute;
content: " ";
right: 0px;
top: 24px;
width: 10px;
height: 10px;
opacity: 0.6;
border-top: 2px solid;
border-right: 2px solid;
-webkit-transform: translate(-50%, -50%) rotate(-45deg);
transform: translate(-50%, -50%) rotate(-45deg);
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
&.collapsed:before {
top: 24px;
-webkit-transform: translate(-50%, -50%) rotate(135deg);
transform: translate(-50%, -50%) rotate(135deg);
}
}
}
.card-body {
padding: 0;
}
.card {
border-bottom: 2px solid #e4e9ec;
padding: 15px 0px;
}
.routes-list {
margin: 1rem 0px 0px 0px;
padding: 0px;
list-style: none;
a {
color: inherit;
display: -ms-flexbox !important;
display: flex !important;
-ms-flex-align: center !important;
align-items: center !important;
&:hover {
color: #0071cc;
text-decoration: underline;
}
}
}
}
}
/* 5.4 Nav */
.nav .nav-item .nav-link{color: #222222;}
.nav.nav-light .nav-item .nav-link{color: #ddd;}
.nav:not(.nav-pills) .nav-item .nav-link.active, .nav:not(.nav-pills) .nav-item .nav-link:hover{color: $primary-color;}
.nav-pills .nav-link:not(.active):hover{color: $primary-color;}
.nav-pills .nav-link.active,.nav-pills.nav-light .nav-link.active, .nav-pills .show > .nav-link{color:#fff;}
.nav.nav-separator .nav-item .nav-link{position:relative;}
.nav.nav-separator .nav-item + .nav-item .nav-link:after{
height: 14px;
width: 1px;
content: ' ';
background-color: rgba(0,0,0,0.2);
display: block;
position: absolute;
top: 50%;
left: 0;
@include translateY(-7px);
}
.nav.nav-separator.nav-separator-light .nav-item + .nav-item .nav-link:after{
background-color: rgba(250,250,250,0.2);
}
.nav.nav-sm .nav-item .nav-link{font-size:14px;}
/*=== 5.5 Tabs ===*/
.nav-tabs {
border-bottom: 1px solid #d7dee3;
.nav-item .nav-link {
border:0;
background: transparent;
position: relative;
border-radius: 0;
padding:0.6rem 1rem;
color: #7b8084;
white-space: nowrap !important;
&.active {
&:after {
height: 2px;
width: 100%;
content: ' ';
background-color: $primary-color;
display: block;
position: absolute;
bottom: -3px;
left: 0;
@include translateY(-3px);
}
color: #0c2f55;
}
&:not(.active):hover {
color: $primary-color;
}
}
&.flex-column {
border-right: 1px solid #d7dee3;
border-bottom: 0px;
padding: 1.5rem 0;
.nav-item {
.nav-link {
border: 1px solid #d7dee3;
border-right: 0px;
background-color: #f6f7f8;
font-size: 14px;
padding: 0.75rem 1rem;
color: #535b61;
}
&:first-of-type .nav-link {
border-top-left-radius: 4px;
}
&:last-of-type .nav-link {
border-bottom-left-radius: 4px;
}
.nav-link.active {
&:after {
height: 100%;
width: 2px;
background: #fff;
right: -1px;
left: auto;
}
background-color: transparent;
color: $primary-color;
}
}
}
}
.nav-tabs:not(.flex-column) {
.nav-item {
margin-bottom: 0px;
}
flex-wrap: nowrap;
overflow: hidden;
overflow-x: auto;
-ms-overflow-style: -ms-autohiding-scrollbar;
-webkit-overflow-scrolling: touch;
}
@include media-breakpoint-down(xs) {
.nav-tabs .nav-item .nav-link {
padding-left: 0px;
padding-right: 0px;
margin-right: 10px;
font-size: 0.875rem;
}
}
/*=== 5.6 Popup Img ===*/
.popup-img img{@include transition(all 0.2s ease-in-out);}
.popup-img:hover img{
opacity:0.8;
cursor: -webkit-zoom-in;
cursor: -moz-zoom-in;
cursor: zoom-in;
}
/*=== 5.7 Featured Box ===*/
.featured-box {
box-sizing: border-box;
position: relative;
h3, h4 {
font-size: 1.25rem;
font-size: 20px;
margin-bottom: 10px;
font-weight: 500;
}
&:not(.style-5) .featured-box-icon {
display: inline-block;
font-size: 48px;
min-width: 55px;
min-height: 55px;
padding: 0;
margin-top: 0;
margin-bottom: 0.8rem;
color: #4c4d4d;
border-radius: 0;
}
&.style-1, &.style-2, &.style-3 {
padding-left: 50px;
padding-top: 8px;
}
&.style-1 .featured-box-icon, &.style-2 .featured-box-icon, &.style-3 .featured-box-icon {
position: absolute;
top: 0;
left: 0;
margin-bottom: 0;
font-size: 30px;
-ms-flex-pack: center !important;
justify-content: center !important;
text-align: center;
}
&.style-2 p {
margin-left: -50px;
}
&.style-3 {
padding-left: 90px;
padding-top: 0px;
.featured-box-icon {
width: 70px;
height: 70px;
-ms-flex-negative: 0;
flex-shrink: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
}
&.style-4 {
text-align: center;
.featured-box-icon {
margin: 0 auto 24px;
margin: 0 auto 1.5rem;
width: 120px;
height: 120px;
text-align: center;
-ms-flex-negative: 0;
flex-shrink: 0;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-ms-flex-pack: center;
justify-content: center;
@include box-shadow(0px 0px 50px rgba(0, 0, 0, 0.03));
}
}
&.style-5 {
text-align: center;
background: #fff;
border: 1px solid #f0f2f3;
@include box-shadow(0px 2px 5px rgba(0, 0, 0, 0.05));
@include transition(all 0.3s ease-in-out);
&:hover {
border: 1px solid #ebeded;
@include box-shadow(0px 5px 1.5rem rgba(0, 0, 0, 0.15));
}
h3 {
background: #f1f5f6;
font-size: 16px;
padding: 8px 0;
margin-bottom: 0px;
}
.featured-box-icon {
font-size: 50px;
margin: 44px 0px;
}
}
}
@mixin featured-box-reverse {
text-align:right;
&.style-1, &.style-2{
padding-right:50px;
padding-left:0px;
.featured-box-icon{
left:auto;
right:0px;
}
}
&.style-2 p{
margin-right: -50px;
margin-left:0;
}
&.style-3{
padding-left:0;
padding-right:90px;
.featured-box-icon{
left:auto;
right:0px;
}
}
}
.featured-box.featured-box-reverse{
@include featured-box-reverse;
}
@include media-breakpoint-up(xs) {
.featured-box.featured-box-reverse-sm{
@include featured-box-reverse;
}
}
@include media-breakpoint-up(sm) {
.featured-box.featured-box-reverse-md{
@include featured-box-reverse;
}
}
@include media-breakpoint-up(md) {
.featured-box.featured-box-reverse-lg{
@include featured-box-reverse;
}
}
@include media-breakpoint-up(lg) {
.featured-box.featured-box-reverse-xl{
@include featured-box-reverse;
}
}
+448
View File
@@ -0,0 +1,448 @@
/* =================================== */
/* Extras
/* =================================== */
/* Bootstrap Specific */
.form-control, .custom-select {
border-color: #dae1e3;
font-size: 16px;
color: #656565;
}
.form-control:not(.form-control-sm) {
padding: .810rem .96rem;
height:inherit;
}
.form-control-sm{font-size:14px;}
.icon-inside {
position: absolute;
right: 15px;
top: calc(50% - 11px);
pointer-events: none;
font-size: 18px;
font-size: 1.125rem;
color: #c4c3c3;
z-index:3;
}
.form-control-sm + .icon-inside {
font-size: 0.875rem !important;
font-size: 14px;
top: calc(50% - 13px);
}
select.form-control:not([size]):not([multiple]):not(.form-control-sm) {
height: auto;
padding-top: .700rem;
padding-bottom: .700rem;
}
.custom-select:not(.custom-select-sm){
height:calc(3.05rem + 2px);
padding-top: .700rem;
padding-bottom: .700rem;}
.col-form-label-sm{font-size:13px;}
.custom-select-sm{padding-left:5px!important; font-size:14px;}
.custom-select:not(.custom-select-sm).border-0{height:3.00rem;}
.form-control:focus, .custom-select:focus{
@include box-shadow(0 0 5px rgba(128, 189, 255, 0.5));
}
.form-control:focus[readonly]{box-shadow:none;}
.input-group-text {
border-color: #dae1e3;
background-color:#f1f5f6;
color: #656565;
}
.form-control {
&::-webkit-input-placeholder {
color: #b1b4b6;
}
&:-moz-placeholder {
/* FF 4-18 */
color: #b1b4b6;
}
&::-moz-placeholder {
/* FF 19+ */
color: #b1b4b6;
}
&:-ms-input-placeholder, &::-ms-input-placeholder {
/* IE 10+ */
color: #b1b4b6;
}
}
/* Form Dark */
.form-dark {
.form-control, .custom-select {
border-color: #232a31;
background:#232a31;
color: #fff;
}
.form-control:focus{border-color: #80bdff!important;}
.form-control {
&::-webkit-input-placeholder {
color: #777b7f;
}
&:-moz-placeholder {
/* FF 4-18 */
color: #777b7f;
}
&::-moz-placeholder {
/* FF 19+ */
color: #777b7f;
}
&:-ms-input-placeholder, &::-ms-input-placeholder {
/* IE 10+ */
color: #777b7f;
}
}
.custom-select {
color: #777b7f;
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='rgba(250,250,250,0.3)' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
background-size: 13px 15px;
border-color: #232a31;
background-color:#232a31;
}
.icon-inside {
color: #777b7f;
}
}
/* Input with only bottom border */
.form-border {
.form-control {
background-color: transparent;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 0px;
padding-left: 0px!important;
color: rgba(0, 0, 0, 1);
&::-webkit-input-placeholder {
color: rgba(0, 0, 0, 0.4);
}
&:-moz-placeholder {
/* FF 4-18 */
color: rgba(0, 0, 0, 0.4);
}
&::-moz-placeholder {
/* FF 19+ */
color: rgba(0, 0, 0, 0.4);
}
&:-ms-input-placeholder, &::-ms-input-placeholder {
/* IE 10+ */
color: rgba(0, 0, 0, 0.4);
}
}
.custom-select {
background-color: transparent;
border: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.12);
border-radius: 0px;
padding-left: 0px;
color: rgba(0, 0, 0, 0.4);
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='rgba(0,0,0,0.3)' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
background-size: 13px 15px;
}
.form-control:focus, .custom-select:focus {
box-shadow: none;
-webkit-box-shadow: none;
border-bottom: 2px solid rgba(0, 0, 0, 0.7);
}
.form-control:not(output):-moz-ui-invalid, .custom-select:not(output):-moz-ui-invalid {
&:not(:focus), &:-moz-focusring:not(:focus) {
border-bottom: 2px solid #b00708;
box-shadow: none;
-webkit-box-shadow: none;
}
}
.icon-inside {
color: rgba(0, 0, 0, 0.25);
}
select option {
color: #666;
}
}
.form-border-light {
.form-control {
border-bottom: 2px solid rgba(250, 250, 250, 0.3);
color: rgba(250, 250, 250, 1);
&::-webkit-input-placeholder {
color: rgba(250, 250, 250, 0.7);
}
&:-moz-placeholder {
/* FF 4-18 */
color: rgba(250, 250, 250, 0.7);
}
&::-moz-placeholder {
/* FF 19+ */
color: rgba(250, 250, 250, 0.7);
}
&:-ms-input-placeholder, &::-ms-input-placeholder {
/* IE 10+ */
color: rgba(250, 250, 250, 0.7);
}
}
.custom-select {
border-bottom: 2px solid rgba(250, 250, 250, 0.3);
color: rgba(250, 250, 250, 1);
background: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='rgba(250,250,250,0.6)' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
background-size: 13px 15px;
}
.form-control:focus, .custom-select:focus {
border-bottom: 2px solid rgba(250, 250, 250, 0.8);
}
.icon-inside {
color: #999;
}
select option {
color: #333;
}
}
.input-group-append .btn, .input-group-prepend .btn {
@include box-shadow(none);
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.input-group-append .btn:hover, .input-group-prepend .btn:hover {
@include box-shadow(none);
}
@include media-breakpoint-down(xs) {
.input-group > {
.input-group-append > .btn, .input-group-prepend > .btn {
padding: 0 0.75rem;
}
}
}
.bg-primary, .badge-primary {
background-color: $primary-color !important;
}
.bg-secondary {
background-color: $secondary-color !important;
}
.text-primary, .btn-light, .btn-outline-light:hover, .btn-link, .btn-outline-light:not(:disabled):not(.disabled).active, .btn-outline-light:not(:disabled):not(.disabled):active {
color: $primary-color !important;
}
.btn-link:hover {
color: $primary-color-hover !important;
}
.text-secondary{
color: $secondary-color !important;
}
.text-light{
color:#dee3e4!important;
}
.text-body{
color: $text-color !important;
}
a.bg-primary:focus, a.bg-primary:hover, button.bg-primary:focus, button.bg-primary:hover{background-color: $primary-color-hover!important;}
.border-primary {
border-color: $primary-color !important;
}
.border-secondary {
border-color: $secondary-color !important;
}
.btn-primary{
background-color: $primary-color;
border-color: $primary-color;
&:hover {
background-color: $primary-color-hover;
border-color: $primary-color-hover;
}
}
.btn-primary:not(:disabled):not(.disabled).active, .btn-primary:not(:disabled):not(.disabled):active{
background-color: $primary-color-hover;
border-color: $primary-color-hover;
}
.btn-primary.focus, .btn-primary:focus{
background-color: $primary-color-hover;
border-color: $primary-color-hover;
}
.btn-primary:not(:disabled):not(.disabled).active:focus, .btn-primary:not(:disabled):not(.disabled):active:focus, .show > .btn-primary.dropdown-toggle:focus{
@include box-shadow(none);
}
.btn-secondary {
background-color: $secondary-color;
border-color: $secondary-color;
}
.btn-outline-primary, .btn-outline-primary:not(:disabled):not(.disabled).active, .btn-outline-primary:not(:disabled):not(.disabled):active{
color: $primary-color;
border-color: $primary-color;
&:hover {
background-color: $primary-color;
border-color: $primary-color;
color: #fff;
}
}
.btn-outline-secondary{
color: $secondary-color;
border-color: $secondary-color;
&:hover {
background-color: $secondary-color;
border-color: $secondary-color;
color: #fff;
}
}
.progress-bar,
.nav-pills .nav-link.active, .nav-pills .show > .nav-link, .dropdown-item.active, .dropdown-item:active{
background-color: $primary-color;
}
.page-item.active .page-link,
.custom-radio .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label::before,
.custom-checkbox .custom-control-input:checked ~ .custom-control-label:before,
.custom-control-input:checked ~ .custom-control-label:before{
background-color: $primary-color;
border-color: $primary-color;
}
.list-group-item.active{
background-color: $primary-color;
border-color: $primary-color;
}
.page-link {
color: $primary-color;
&:hover {
color: $primary-color-hover;
}
}
/* Pagination */
.page-link {
border: none;
border-radius: 0.25rem;
margin: 0 0.22rem;
font-size: 16px;
font-size: 1rem;
&:hover {
background-color: #e9eff0;
}
}
/* Vertical Multilple input group */
.vertical-input-group .input-group {
&:first-child {
padding-bottom: 0;
* {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
}
&:last-child {
padding-top: 0;
* {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
}
&:not(:last-child):not(:first-child) {
padding-top: 0;
padding-bottom: 0;
* {
border-radius: 0;
}
}
&:not(:first-child) * {
border-top: 0;
}
}
/* styles-switcher */
#styles-switcher {
background: #fff;
width: 202px;
position: fixed;
top: 35%;
z-index: 99;
padding: 20px;
left: -202px;
ul {
padding: 0;
li {
list-style-type: none;
width: 25px;
height: 25px;
margin: 4px 2px;
border-radius: 50%;
display: inline-block;
cursor: pointer;
transition: all .2s ease-in-out;
&.blue {
background: #007bff;
}
&.brown {
background: #795548;
}
&.purple {
background: #6f42c1;
}
&.indigo {
background: #6610f2;
}
&.red {
background: #dc3545;
}
&.orange {
background: #fd7e14;
}
&.yellow {
background: #ffc107;
}
&.green {
background: #28a745;
}
&.teal {
background: #20c997;
}
&.cyan {
background: #17a2b8;
}
&.active {
transform: scale(0.7);
cursor:default;
}
}
}
.switcher-toggle {
position: absolute;
background: #333;
color: #fff;
font-size: 1.25rem;
border-radius: 0px 4px 4px 0;
right: -40px;
top: 0;
width: 40px;
height: 40px;
padding: 0;
}
#reset-color{background: #e83e8c;}
}
input:-internal-autofill-selected {
background-color: transparent;
}
#styles-switcher.right{left:auto; right: -202px;}
#styles-switcher.right .switcher-toggle{right: auto; left: -40px; border-radius: 4px 0px 0px 4px;}
+188
View File
@@ -0,0 +1,188 @@
/* =================================== */
/* 6. Footer
/* =================================== */
#footer {
background: #fff;
color: #252b33;
margin-left:260px;
padding: 66px 0px;
padding: 4.125rem 0;
.nav {
.nav-item {
display: inline-block;
line-height: 12px;
margin: 0;
.nav-link {
color: #252b33;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
&:focus {
color: $primary-color;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
}
&:first-child .nav-link {
padding-left: 0px;
}
&:last-child .nav-link{
padding-right: 0px;
}
}
.nav-link:hover {
color: $primary-color;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
}
.footer-copyright {
border-top: 1px solid #e2e8ea;
padding: 0px 0px;
color: #67727c;
.nav {
.nav-item .nav-link {
color: #67727c;
}
.nav-link:hover {
color: $primary-color;
-webkit-transition: all 0.2s ease;
transition: all 0.2s ease;
}
}
}
.nav.flex-column .nav-item {
padding: 0px;
.nav-link {
margin: 0.7rem 0px;
}
}
&.footer-text-light {
color: rgba(250, 250, 250, 0.8);
.nav .nav-item .nav-link {
color: rgba(250, 250, 250, 0.8);
&:hover {
color: rgba(250, 250, 250, 1);
}
}
.footer-copyright {
border-color: rgba(250, 250, 250, 0.15);
color: rgba(250, 250, 250, 0.5);
}
&:not(.bg-primary) .social-icons-light.social-icons li a {
color: rgba(250, 250, 250, 0.8);
&:hover {
color: rgba(250, 250, 250, 1);
}
}
&.bg-primary {
color: #fff;
.nav .nav-item .nav-link {
color: #fff;
&:hover {
color: rgba(250, 250, 250, 0.7);
}
}
.footer-copyright {
border-color: rgba(250, 250, 250, 0.15);
color: rgba(250, 250, 250, 0.9);
}
:not(.social-icons) a {
color: #fff;
&:hover {
color: rgba(250, 250, 250, 0.7);
}
}
}
}
}
@include media-breakpoint-down(sm) {
#footer {
margin-left:0px;
}
}
/*=== 6.1 Social Icons ===*/
.social-icons {
margin: 0;
padding: 0;
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
list-style: none;
li {
margin: 0px 6px;
padding: 0;
overflow: visible;
a {
display: block;
height: 26px;
line-height: 26px;
width: 26px;
font-size: 18px;
text-align: center;
color: #4d555a;
text-decoration: none;
@include transition(all 0.2s ease);
}
i {
line-height: inherit;
}
}
&.social-icons-sm li{
margin: 0px 4px;
}
&.social-icons-sm li a {
font-size: 15px;
width:22px;
}
&.social-icons-lg li a {
width: 34px;
height: 34px;
line-height:34px;
font-size: 22px;
}
&.social-icons-light li a {
color: #eee;
}
&.social-icons-muted li a {
color: #aab1b8;
}
li:hover {
a {
color: #999;
}
}
}
/*=== 6.2 Back to Top ===*/
#back-to-top {
display: none;
position: fixed;
z-index: 1030;
bottom: 8px;
right: 10px;
background-color: rgba(0, 0, 0, 0.22);
text-align: center;
color: #fff;
font-size: 14px;
width: 36px;
height: 36px;
line-height: 34px;
border-radius:3px;
@include transition(all 0.3s ease-in-out);
@include box-shadow(0px 5px 15px rgba(0, 0, 0, 0.15));
&:hover {
background-color: $primary-color;
@include box-shadow(0px 5px 15px rgba(0, 0, 0, 0.25));
@include transition(all 0.3s ease-in-out);
}
}
@include media-breakpoint-down(xs) {
#back-to-top {z-index: 1029;}
}
+554
View File
@@ -0,0 +1,554 @@
/* =================================== */
/* 4. Header
/* =================================== */
#header {
@include transition(all .5s ease);
.navbar {
padding: 0px;
min-height:70px;
}
.logo {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-ms-flex-item-align: stretch;
align-self: stretch;
}
}
/*=== 4.1 Main Navigation ===*/
.navbar-light .navbar-nav {
.active > .nav-link {
color: #0c2f55;
}
.nav-link {
&.active, &.show {
color: #0c2f55;
}
}
.show > .nav-link {
color: #0c2f55;
}
}
.primary-menu {
display: -webkit-box !important;
display: -ms-flexbox !important;
display: flex !important;
height: auto !important;
-webkit-box-ordinal-group: 0;
-ms-flex-item-align: stretch;
align-self: stretch;
background: #fff;
border-bottom:1px solid #efefef;
&.bg-transparent {
position: absolute;
z-index: 999;
top: 0;
left: 0;
width: 100%;
box-shadow: none;
border-bottom: 1px solid rgba(250, 250, 250, 0.3);
}
&.sticky-on{
position: fixed;
top: 0;
width: 100%;
z-index: 1020;
left: 0;
@include box-shadow(0px 0px 10px rgba(0, 0, 0, 0.05));
-webkit-animation: slide-down 0.7s;
-moz-animation: slide-down 0.7s;
animation: slide-down 0.7s;
@-webkit-keyframes slide-down { 0% { opacity:0; transform:translateY(-100%);}100% { opacity:1; transform:translateY(0);}}
@-moz-keyframes slide-down { 0% { opacity:0; transform:translateY(-100%);}100% { opacity:1; transform:translateY(0);}}
@keyframes slide-down { 0% { opacity:0; transform:translateY(-100%);}100% { opacity:1; transform:translateY(0);}}
.none-on-sticky{
display:none!important;
}
}
ul.navbar-nav > li {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
height: 100%;
+ li {
margin-left: 2px;
}
a {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
> a:not(.btn) {
height: 70px;
padding:0px 0.85em;
color: #252b33;
@include transition(all .2s ease);
position: relative;
position:relative;
}
&:hover > a:not(.btn), & > a.active:not(.btn) {
color: $primary-color;
text-decoration:none;
@include transition(all .2s ease);
}
a.btn{padding: 0.4rem 1.4rem;}
&.dropdown {
.dropdown-menu li {
> a:not(.btn) {
padding: 8px 0px;
background-color: transparent;
text-transform: none;
color: #777;
@include transition(all .2s ease);
}
&:hover > a:not(.btn) {
color: $primary-color;
@include transition(all .2s ease);
}
}
&:hover > a:after {
clear: both;
content: ' ';
display: block;
width: 0;
height: 0;
border-style: solid;
border-color: transparent transparent #fff transparent;
position: absolute;
border-width: 0px 7px 6px 7px;
bottom: 0px;
left: 50%;
margin: 0 0 0 -5px;
z-index: 1022;
}
.dropdown-menu {
@include box-shadow(0px 0px 12px rgba(0, 0, 0, 0.176));
border: 0px none;
padding: 10px 15px;
min-width: 220px;
margin: 0;
font-size: 14px;
font-size: 0.875rem;
z-index:1021;
}
> .dropdown-toggle .arrow {
display: none;
}
}
}
.dropdown-menu-right {
left: auto !important;
right: 100% !important;
}
ul.navbar-nav > li {
&.dropdown-mega {
position: static;
> .dropdown-menu {
width: 100%;
padding: 20px 20px;
margin-left: 0px !important;
}
.dropdown-mega-content > .row > div {
padding: 5px 5px 5px 20px;
border-right: 1px solid #eee;
&:last-child {
border-right: 0;
}
}
.sub-title {
display: block;
font-size: 16px;
margin-top: 1rem;
padding-bottom: 5px;
}
.dropdown-mega-submenu {
list-style-type: none;
padding-left: 0px;
}
}
a.btn{font-size:14px; padding: 0.65rem 2rem; text-transform:uppercase;}
&.dropdown {
.dropdown-menu {
.dropdown-menu {
left: 100%;
margin-top: -40px;
}
.dropdown-toggle:after {
border-top: .4em solid transparent;
border-right: 0;
border-bottom: 0.4em solid transparent;
border-left: 0.4em solid;
}
}
.dropdown-toggle .arrow {
position: absolute;
min-width: 30px;
height: 100%;
right: 0px;
top: 0;
@include transition(all .2s ease);
&:after {
content: " ";
position: absolute;
top: 50%;
left: 50%;
border-color: #000;
border-top: 1px solid;
border-right: 1px solid;
width: 6px;
height: 6px;
-webkit-transform: translate(-50%, -50%) rotate(45deg);
transform: translate(-50%, -50%) rotate(45deg);
}
}
}
}
.dropdown-toggle:after {
content: none;
}
&.navbar-line-under-text ul.navbar-nav > li {
> a:not(.btn):after {
position: absolute;
content: "";
height: 2px;
width: 0;
left: 50%;
right: 0;
bottom: 14px;
background-color: transparent;
color:#fff;
border-bottom: 2px solid $primary-color;
@include transition(all .3s ease-in-out);
transform: translate(-50%,0) translateZ(0);
-webkit-transform: translate(-50%,0) translateZ(0);
}
& > a:hover:not(.logo):after, & > a.active:after{
width:calc(100% - 0.99em);
}
}
}
/*== Color Options ==*/
.primary-menu.navbar-text-light .navbar-toggler span {background:#fff;}
.primary-menu.navbar-text-light .navbar-nav > li{
> a:not(.btn) {
color: #fff;
}
&:hover > a:not(.btn), & > a.active:not(.btn) {
color: rgba(250, 250, 250, 0.75);
}
}
.primary-menu.navbar-text-light.navbar-line-under-text .navbar-nav > li{
& > a:not(.logo):after, & > a.active:after{
border-color:rgba(250, 250, 250, 0.60);
}
}
.primary-menu {
&.navbar-dropdown-dark ul.navbar-nav > li {
&.dropdown {
.dropdown-menu {
background-color: #252A2C;
color: #fff;
.dropdown-menu {
background-color: #272c2e;
}
}
&:hover > a:after {
border-color: transparent transparent #252A2C transparent;
}
.dropdown-menu li {
> a:not(.btn) {
color: rgba(250, 250, 250, 0.8);
}
&:hover > a:not(.btn) {
color: rgba(250, 250, 250, 1);
font-weight:600;
}
}
}
&.dropdown-mega .dropdown-mega-content > .row > div {
border-color: #3a3a3a;
}
}
&.navbar-dropdown-primary ul.navbar-nav > li {
&.dropdown {
.dropdown-menu {
background-color: $primary-color;
color: #fff;
.dropdown-menu {
background-color: $primary-color;
}
}
&:hover > a:after {
border-color: transparent transparent $primary-color transparent;
}
.dropdown-menu li {
> a:not(.btn) {
color: rgba(250, 250, 250, 0.95);
}
&:hover > a:not(.btn) {
color: rgba(250, 250, 250, 1);
font-weight:600;
}
}
}
&.dropdown-mega .dropdown-mega-content > .row > div {
border-color: rgba(250, 250, 250, 0.2);
}
}
}
/* Hamburger Menu Button */
.navbar-toggler {
width: 25px;
height: 30px;
padding: 10px;
margin: 18px 15px;
position: relative;
border:none;
@include rotate(0deg);
@include transition(.5s ease-in-out);
cursor: pointer;
display: block;
span {
display: block;
position: absolute;
height: 2px;
width: 100%;
background: #3c3636;
border-radius: 2px;
opacity: 1;
left: 0;
@include rotate(0deg);
@include transition(.25s ease-in-out);
&:nth-child(1) {
top: 7px;
-webkit-transform-origin: left center;
-moz-transform-origin: left center;
-o-transform-origin: left center;
transform-origin: left center;
}
&:nth-child(2) {
top: 14px;
-webkit-transform-origin: left center;
-moz-transform-origin: left center;
-o-transform-origin: left center;
transform-origin: left center;
}
&:nth-child(3) {
top: 21px;
-webkit-transform-origin: left center;
-moz-transform-origin: left center;
-o-transform-origin: left center;
transform-origin: left center;
}
}
&.show span {
&:nth-child(1) {
top: 4px;
left: 3px;
@include rotate(45deg);
}
&:nth-child(2) {
width: 0%;
opacity: 0;
}
&:nth-child(3) {
top: 22px;
left: 3px;
@include rotate(-45deg);
}
}
}
.navbar-accordion{position:initial;}
// For Responsive Navbar
@mixin navbar-responsive {
.navbar-collapse {
position: absolute;
top: 99%;
right: 0;
left: 0;
background: #fff;
margin-top: 0px;
z-index: 1000;
@include box-shadow(0px 0px 15px rgba(0, 0, 0, 0.1));
.navbar-nav {
overflow: hidden;
overflow-y: auto;
max-height: 65vh;
padding: 15px;
}
}
ul.navbar-nav {
li {
display: block;
border-bottom: 1px solid #eee;
margin: 0;
padding: 0;
&:last-child {
border: none;
}
+ li {
margin-left: 0px;
}
&.dropdown > .dropdown-toggle > .arrow.show:after {
-webkit-transform: translate(-50%, -50%) rotate(-45deg);
transform: translate(-50%, -50%) rotate(-45deg);
@include transition(all .2s ease);
}
> a:hover:after, > a.active:after {
content: none!important;
width:0px!important;
}
&.dropdown{
> .dropdown-toggle .arrow {
display: block;
}
}
}
> li {
> a:not(.btn) {
height: auto;
padding: 8px 0;
position: relative;
}
&.dropdown {
.dropdown-menu li > a:not(.btn) {
padding: 8px 0;
position: relative;
}
&:hover > a:after {
content: none;
}
.dropdown-toggle .arrow:after {
-webkit-transform: translate(-50%, -50%) rotate(134deg);
transform: translate(-50%, -50%) rotate(134deg);
@include transition(all .2s ease);
}
}
}
> li {
&.dropdown .dropdown-menu {
margin: 0;
@include box-shadow(none);
border: none;
padding: 0px 0px 0px 15px;
.dropdown-menu {
margin: 0;
}
}
&.dropdown-mega {
.dropdown-mega-content > .row > div {
padding: 0px 15px;
}
}
}
}
&.navbar-text-light .navbar-collapse{background:rgba(0,0,0,0.95);}
&.navbar-text-light .navbar-collapse ul.navbar-nav li{
border-color:rgba(250,250,250,0.15);
}
&.navbar-dropdown-dark .navbar-collapse {
background-color: #252A2C;
}
&.navbar-dropdown-primary .navbar-collapse {
background-color: $primary-color;
}
&.navbar-dropdown-primary ul.navbar-nav > li.dropdown .dropdown-menu .dropdown-menu {
background-color: $primary-color;
}
&.navbar-dropdown-dark ul.navbar-nav {
li {
border-color: #444;
}
> li {
> a {
color: #a3a2a2;
}
&:hover > a {
color: #fff;
}
}
}
&.navbar-dropdown-primary ul.navbar-nav {
li {
border-color: rgba(250, 250, 250, 0.2);
}
> li {
> a {
color: rgba(250, 250, 250, 0.8);
}
&:hover > a {
color: #fff;
}
}
}
}
.navbar-expand-none{
@include navbar-responsive;
}
@include media-breakpoint-down(xs) {
.navbar-expand-sm{
@include navbar-responsive;
}
}
@include media-breakpoint-down(sm) {
.navbar-expand-md{
@include navbar-responsive;
}
}
@include media-breakpoint-down(md) {
.navbar-expand-lg{
@include navbar-responsive;
}
}
@include media-breakpoint-down(lg) {
.navbar-expand-xl{
@include navbar-responsive;
}
}
+301
View File
@@ -0,0 +1,301 @@
/* =================================== */
/* 2. Helpers Classes
/* =================================== */
/* Box Shadow */
.shadow-md {
@include box-shadow(0px 0px 50px -35px rgba(0, 0, 0, 0.4)!important);
}
/* Border Radius */
.rounded-lg{
border-radius: 0.6rem !important;
}
.rounded-top-0{
border-top-left-radius:0px!important;
border-top-right-radius:0px!important;
}
.rounded-bottom-0{
border-bottom-left-radius:0px!important;
border-bottom-right-radius:0px!important;
}
.rounded-left-0{
border-top-left-radius:0px!important;
border-bottom-left-radius:0px!important;
}
.rounded-right-0{border-top-right-radius:0px!important;
border-bottom-right-radius:0px!important;
}
/* Border Size */
.border-1{
border-width:1px!important;
}
.border-2{
border-width:2px!important;
}
.border-3{
border-width:3px!important;
}
.border-4{
border-width:4px!important;
}
.border-5{
border-width:5px!important;
}
/* Text Size */
.text-0 {
font-size: 11px !important;
font-size: 0.6875rem !important;
}
.text-1 {
font-size: 12px !important;
font-size: 0.75rem !important;
}
.text-2 {
font-size: 14px !important;
font-size: 0.875rem !important;
}
.text-3 {
font-size: 16px !important;
font-size: 1rem !important;
}
.text-4 {
font-size: 18px !important;
font-size: 1.125rem !important;
}
.text-5 {
font-size: 21px !important;
font-size: 1.3125rem !important;
}
.text-6 {
font-size: 24px !important;
font-size: 1.50rem !important;
}
.text-7 {
font-size: 28px !important;
font-size: 1.75rem !important;
}
.text-8 {
font-size: 32px !important;
font-size: 2rem !important;
}
.text-9 {
font-size: 36px !important;
font-size: 2.25rem !important;
}
.text-10 {
font-size: 40px !important;
font-size: 2.50rem !important;
}
.text-11 {
@include rfs(44, true);
}
.text-12 {
@include rfs(48, true);
}
.text-13 {
@include rfs(52, true);
}
.text-14 {
@include rfs(56, true);
}
.text-15 {
@include rfs(60, true);
}
.text-16 {
@include rfs(64, true);
}
.text-17 {
@include rfs(72, true);
}
.text-18 {
@include rfs(80, true);
}
.text-19 {
@include rfs(84, true);
}
.text-20 {
@include rfs(92, true);
}
.text-21 {
@include rfs(104, true);
}
.text-22 {
@include rfs(112, true);
}
.text-23 {
@include rfs(124, true);
}
.text-24 {
@include rfs(132, true);
}
.text-25 {
@include rfs(144, true);
}
.text-11, .text-12, .text-13, .text-14, .text-15, .text-16, .text-17, .text-18, .text-19, .text-20, .text-21, .text-22, .text-23, .text-24, .text-25{
line-height: 1.3;
}
/* Line height */
.line-height-07 {
line-height: 0.7 !important;
}
.line-height-1 {
line-height: 1 !important;
}
.line-height-2 {
line-height: 1.2 !important;
}
.line-height-3 {
line-height: 1.4 !important;
}
.line-height-4 {
line-height: 1.6 !important;
}
.line-height-5 {
line-height: 1.8 !important;
}
/* Font Weight */
.font-weight-100 {
font-weight: 100 !important;
}
.font-weight-200 {
font-weight: 200 !important;
}
.font-weight-300 {
font-weight: 300 !important;
}
.font-weight-400 {
font-weight: 400 !important;
}
.font-weight-500 {
font-weight: 500 !important;
}
.font-weight-600 {
font-weight: 600 !important;
}
.font-weight-700 {
font-weight: 700 !important;
}
.font-weight-800 {
font-weight: 800 !important;
}
.font-weight-900 {
font-weight: 900 !important;
}
/* Opacity */
.opacity-0 {
opacity: 0;
}
.opacity-1 {
opacity: 0.1;
}
.opacity-2 {
opacity: 0.2;
}
.opacity-3 {
opacity: 0.3;
}
.opacity-4 {
opacity: 0.4;
}
.opacity-5 {
opacity: 0.5;
}
.opacity-6 {
opacity: 0.6;
}
.opacity-7 {
opacity: 0.7;
}
.opacity-8 {
opacity: 0.8;
}
.opacity-9 {
opacity: 0.9;
}
.opacity-10 {
opacity: 1;
}
/* Background light */
.bg-light-1 {
background-color: $gray-200 !important;
}
.bg-light-2 {
background-color: $gray-300 !important;
}
.bg-light-3 {
background-color: $gray-400 !important;
}
.bg-light-4 {
background-color: $gray-500 !important;
}
/* Background Dark */
.bg-dark {
background-color: #111418 !important;
}
.bg-dark-1 {
background-color: $gray-900 !important;
}
.bg-dark-2 {
background-color: $gray-800 !important;
}
.bg-dark-3 {
background-color: $gray-700 !important;
}
.bg-dark-4 {
background-color: $gray-600 !important;
}
/* Progress Bar */
.progress-sm {
height: 0.5rem !important;
}
.progress-lg {
height: 1.5rem !important;
}
hr{
border-top:1px solid rgba(16,85,96,.1);
}
+171
View File
@@ -0,0 +1,171 @@
/* =================================== */
/* 3. Layouts
/* =================================== */
#main-wrapper {
background:#fff;
}
.box {
#main-wrapper {
max-width: 1200px;
margin: 0 auto;
@include box-shadow(0px 0px 10px rgba(0, 0, 0, 0.1));
}
.idocs-navigation {
left: auto;
}
}
@include media-breakpoint-up(xl) {
.container {
max-width: 1170px !important;
}
}
/*=== 3.1 Side Navigation ===*/
.idocs-navigation {
position: fixed;
top: 70px;
left: 0;
overflow: hidden;
overflow-y: auto;
width: 260px;
height: calc(100% - 70px);
z-index: 1;
border-right: 1px solid rgba(0, 0, 0, 0.05);
transition: all 0.3s;
> .nav {
padding: 30px 0;
}
.nav {
.nav-item {
position: relative;
}
.nav {
margin: 0 0 5px;
}
.nav-link {
position: relative;
padding: 6px 30px;
line-height: 25px;
font-weight: 600;
}
.nav-item {
&:hover > .nav-link, .nav-link.active {
font-weight: 700;
}
}
.nav {
.nav-item .nav-link {
&:after {
content: "";
position: absolute;
left: 30px;
height: 100%;
border-left: 1px solid rgba(0, 0, 0, 0.12);
width: 1px;
top: 0;
}
&.active:after {
border-color: $primary-color;
border-width: 2px;
}
}
display: none;
border-left: 1px solid regba(0, 0, 0, 0.3);
}
.nav-item .nav-link.active + .nav {
display: block;
}
.nav {
.nav-link {
color: #6a6a6a;
padding: 4px 30px 4px 45px;
font-size: 15px;
text-transform: none;
}
.nav {
.nav-link {
padding: 4px 30px 4px 60px;
font-size: 15px;
}
.nav-item .nav-link:after {
left: 45px;
}
}
}
}
> .nav > .nav-item > .nav-link.active:after {
position: absolute;
content: " ";
top: 50%;
right: 18px;
border-color: #000;
border-top: 2px solid;
border-right: 2px solid;
width: 7px;
height: 7px;
-webkit-transform: translate(-50%, -50%) rotate(45deg);
transform: translate(-50%, -50%) rotate(45deg);
@include transition(all .2s ease);
}
&.docs-navigation-dark .nav {
.nav-link {
color: rgba(250, 250, 250, 0.85);
}
.nav {
.nav-link {
color: rgba(250, 250, 250, 0.7);
}
.nav-item .nav-link {
&:after {
border-color: rgba(250, 250, 250, 0.2);
}
&.active:after {
border-color: $primary-color;
}
}
}
}
}
/*=== 3.2 Docs Content ===*/
.idocs-content {
position: relative;
margin-left: 260px;
padding: 0px 50px 50px;
min-height: 750px;
transition: all 0.3s;
section:first-child {
padding-top: 3rem;
}
ol li, ul li {
margin-top: 10px;
}
}
@include media-breakpoint-down(sm) {
.idocs-navigation {
margin-left: -260px;
&.active {
margin-left: 0;
}
}
.idocs-content {
margin-left:0px;
padding:0px;
}
}
/*=== 3.3 Section Divider ===*/
.divider{margin: 4rem 0;}
+31
View File
@@ -0,0 +1,31 @@
//---------- @mixins ----------//
@mixin box-shadow($val...) {
-webkit-box-shadow: ($val);
box-shadow: ($val);
}
@mixin transition($val...) {
-webkit-transition: ($val);
transition: ($val);
}
@mixin translateY($val...) {
-webkit-transform: translateY($val);
transform: translateY($val);
}
@mixin translateX($val...) {
-webkit-transform: translateX($val);
transform: translateX($val);
}
@mixin rotate($val){
-webkit-transform: rotate($val);
transform: rotate($val);
}
@mixin scale($val){
-webkit-transform: scale($val);
transform: scale($val);
}
+164
View File
@@ -0,0 +1,164 @@
/* =================================== */
/* 1. Basic Style
/* =================================== */
body, html {
height:100%;
}
body {
background: $body-bg;
color: $text-color;
}
/*-------- Preloader --------*/
.preloader {
position: fixed;
width: 100%;
height: 100%;
z-index: 999999999 !important;
background-color: #fff;
top: 0;
left: 0;
right: 0;
bottom: 0;
.lds-ellipsis {
display: inline-block;
position: absolute;
width: 80px;
height: 80px;
margin-top: -40px;
margin-left: -40px;
top: 50%;
left: 50%;
div {
position: absolute;
top: 33px;
width: 13px;
height: 13px;
border-radius: 50%;
background: #000;
animation-timing-function: cubic-bezier(0, 1, 1, 0);
&:nth-child(1) {
left: 8px;
animation: lds-ellipsis1 0.6s infinite;
}
&:nth-child(2) {
left: 8px;
animation: lds-ellipsis2 0.6s infinite;
}
&:nth-child(3) {
left: 32px;
animation: lds-ellipsis2 0.6s infinite;
}
&:nth-child(4) {
left: 56px;
animation: lds-ellipsis3 0.6s infinite;
}
}
}
}
@keyframes lds-ellipsis1 {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
@keyframes lds-ellipsis3 {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
@keyframes lds-ellipsis2 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(24px, 0);
}
}
/*--- Preloader Magnific Popup ----*/
.mfp-container .preloader{
background: transparent;
.lds-ellipsis div{
background: #fff;
}
}
::selection {
background: $primary-color;
color: #fff;
text-shadow: none;
}
code{padding: 2px 5px; background-color: #f9f2f4; border-radius: 4px;}
form {
padding: 0;
margin: 0;
display: inline;
}
img {
vertical-align: inherit;
}
a, a:focus {
color: $primary-color;
@include transition(all .2s ease);
}
a:hover, a:active {
color: $primary-color-hover;
@include transition(all .2s ease);
}
a:focus, a:active,
.btn.active.focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn:active:focus,
.btn:focus,
button:focus,
button:active{
outline: none;
}
p {
line-height: 1.8;
}
blockquote {
border-left: 5px solid #eee;
padding: 10px 20px;
}
iframe {
border: 0 !important;
}
h1, h2, h3, h4, h5, h6 {
color: $title-color;
line-height: 1.5;
margin: 0 0 1.5rem 0;
font-family:Roboto, sans-serif;
}
h1{font-size:3rem;}
h2{font-size:2.2rem;}
dl, ol, ul, pre, blockquote, .table{margin-bottom:1.8rem;}
/*=== Highlight Js ===*/
.hljs {padding: 1.5rem;}
+44
View File
@@ -0,0 +1,44 @@
/*===========================================================
Template Name: iDocs - One Page Documentation HTML Template
Author: Harnish Design
Template URL: http://demo.harnishdesign.net/html/idocs
Author URL: https://themeforest.net/user/harnishdesign
File Description : Main css file of the template
=================================================
Table of Contents
=================================================
1. Basic
2. Helpers Classes
3. Layouts
3.1 Side Navigation
3.2 Docs Content
3.3 Section Divider
4. Header
4.1 Main Navigation
5 Elements
5.1 List Style
5.2 Changelog
5.3 Accordion & Toggle
5.4 Nav
5.5 Tabs
5.6 Popup Img
5.7 Featured Box
6 Footer
6.1 Social Icons
6.2 Back to Top
7 Extra
=======================================================*/
//-------------------- Base Colors --------------------//
$primary-color: #0366d6;
$primary-color-hover: darken($primary-color, 7%);
$secondary-color: $secondary;
$body-bg: #dddddd;
$text-color: #4c4d4d;
$title-color: #252b33;
+51
View File
@@ -0,0 +1,51 @@
//
// Base styles
//
.alert {
position: relative;
padding: $alert-padding-y $alert-padding-x;
margin-bottom: $alert-margin-bottom;
border: $alert-border-width solid transparent;
@include border-radius($alert-border-radius);
}
// Headings for larger alerts
.alert-heading {
// Specified to prevent conflicts of changing $headings-color
color: inherit;
}
// Provide class for links that match alerts
.alert-link {
font-weight: $alert-link-font-weight;
}
// Dismissible alerts
//
// Expand the right padding and account for the close button's positioning.
.alert-dismissible {
padding-right: $close-font-size + $alert-padding-x * 2;
// Adjust close link position
.close {
position: absolute;
top: 0;
right: 0;
padding: $alert-padding-y $alert-padding-x;
color: inherit;
}
}
// Alternate styles
//
// Generate contextual modifier classes for colorizing the alert.
@each $color, $value in $theme-colors {
.alert-#{$color} {
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
}
}
+54
View File
@@ -0,0 +1,54 @@
// Base class
//
// Requires one of the contextual, color modifier classes for `color` and
// `background-color`.
.badge {
display: inline-block;
padding: $badge-padding-y $badge-padding-x;
@include font-size($badge-font-size);
font-weight: $badge-font-weight;
line-height: 1;
text-align: center;
white-space: nowrap;
vertical-align: baseline;
@include border-radius($badge-border-radius);
@include transition($badge-transition);
@at-root a#{&} {
@include hover-focus() {
text-decoration: none;
}
}
// Empty badges collapse automatically
&:empty {
display: none;
}
}
// Quick fix for badges in buttons
.btn .badge {
position: relative;
top: -1px;
}
// Pill badges
//
// Make them extra rounded with a modifier to replace v3's badges.
.badge-pill {
padding-right: $badge-pill-padding-x;
padding-left: $badge-pill-padding-x;
@include border-radius($badge-pill-border-radius);
}
// Colors
//
// Contextual variations (linked badges get darker on :hover).
@each $color, $value in $theme-colors {
.badge-#{$color} {
@include badge-variant($value);
}
}
@@ -0,0 +1,44 @@
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
margin-bottom: $breadcrumb-margin-bottom;
@include font-size($breadcrumb-font-size);
list-style: none;
background-color: $breadcrumb-bg;
@include border-radius($breadcrumb-border-radius);
}
.breadcrumb-item {
display: flex;
// The separator between breadcrumbs (by default, a forward-slash: "/")
+ .breadcrumb-item {
padding-left: $breadcrumb-item-padding;
&::before {
display: inline-block; // Suppress underlining of the separator in modern browsers
padding-right: $breadcrumb-item-padding;
color: $breadcrumb-divider-color;
content: escape-svg($breadcrumb-divider);
}
}
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
// without `<ul>`s. The `::before` pseudo-element generates an element
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
//
// To trick IE into suppressing the underline, we give the pseudo-element an
// underline and then immediately remove it.
+ .breadcrumb-item:hover::before {
text-decoration: underline;
}
// stylelint-disable-next-line no-duplicate-selectors
+ .breadcrumb-item:hover::before {
text-decoration: none;
}
&.active {
color: $breadcrumb-active-color;
}
}
@@ -0,0 +1,163 @@
// stylelint-disable selector-no-qualifying-type
// Make the div behave like a button
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-flex;
vertical-align: middle; // match .btn alignment given font-size hack above
> .btn {
position: relative;
flex: 1 1 auto;
// Bring the hover, focused, and "active" buttons to the front to overlay
// the borders properly
@include hover() {
z-index: 1;
}
&:focus,
&:active,
&.active {
z-index: 1;
}
}
}
// Optional: Group multiple button groups together for a toolbar
.btn-toolbar {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
.input-group {
width: auto;
}
}
.btn-group {
// Prevent double borders when buttons are next to each other
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-left: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-right-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include border-left-radius(0);
}
}
// Sizing
//
// Remix the default button sizing classes into new ones for easier manipulation.
.btn-group-sm > .btn { @extend .btn-sm; }
.btn-group-lg > .btn { @extend .btn-lg; }
//
// Split button dropdowns
//
.dropdown-toggle-split {
padding-right: $btn-padding-x * .75;
padding-left: $btn-padding-x * .75;
&::after,
.dropup &::after,
.dropright &::after {
margin-left: 0;
}
.dropleft &::before {
margin-right: 0;
}
}
.btn-sm + .dropdown-toggle-split {
padding-right: $btn-padding-x-sm * .75;
padding-left: $btn-padding-x-sm * .75;
}
.btn-lg + .dropdown-toggle-split {
padding-right: $btn-padding-x-lg * .75;
padding-left: $btn-padding-x-lg * .75;
}
// The clickable button for toggling the menu
// Set the same inset shadow as the :active state
.btn-group.show .dropdown-toggle {
@include box-shadow($btn-active-box-shadow);
// Show no shadow for `.btn-link` since it has no other button styles.
&.btn-link {
@include box-shadow(none);
}
}
//
// Vertical button groups
//
.btn-group-vertical {
flex-direction: column;
align-items: flex-start;
justify-content: center;
> .btn,
> .btn-group {
width: 100%;
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) {
margin-top: -$btn-border-width;
}
// Reset rounded corners
> .btn:not(:last-child):not(.dropdown-toggle),
> .btn-group:not(:last-child) > .btn {
@include border-bottom-radius(0);
}
> .btn:not(:first-child),
> .btn-group:not(:first-child) > .btn {
@include border-top-radius(0);
}
}
// Checkbox and radio options
//
// In order to support the browser's form validation feedback, powered by the
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
// `display: none;` or `visibility: hidden;` as that also hides the popover.
// Simply visually hiding the inputs via `opacity` would leave them clickable in
// certain cases which is prevented by using `clip` and `pointer-events`.
// This way, we ensure a DOM element is visible to position the popover from.
//
// See https://github.com/twbs/bootstrap/pull/12794 and
// https://github.com/twbs/bootstrap/pull/14559 for more information.
.btn-group-toggle {
> .btn,
> .btn-group > .btn {
margin-bottom: 0; // Override default `<label>` value
input[type="radio"],
input[type="checkbox"] {
position: absolute;
clip: rect(0, 0, 0, 0);
pointer-events: none;
}
}
}
+142
View File
@@ -0,0 +1,142 @@
// stylelint-disable selector-no-qualifying-type
//
// Base styles
//
.btn {
display: inline-block;
font-family: $btn-font-family;
font-weight: $btn-font-weight;
color: $body-color;
text-align: center;
text-decoration: if($link-decoration == none, null, none);
white-space: $btn-white-space;
vertical-align: middle;
user-select: none;
background-color: transparent;
border: $btn-border-width solid transparent;
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
@include transition($btn-transition);
@include hover() {
color: $body-color;
text-decoration: none;
}
&:focus,
&.focus {
outline: 0;
box-shadow: $btn-focus-box-shadow;
}
// Disabled comes first so active can properly restyle
&.disabled,
&:disabled {
opacity: $btn-disabled-opacity;
@include box-shadow(none);
}
&:not(:disabled):not(.disabled) {
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
&:active,
&.active {
@include box-shadow($btn-active-box-shadow);
&:focus {
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
}
}
}
}
// Future-proof disabling of clicks on `<a>` elements
a.btn.disabled,
fieldset:disabled a.btn {
pointer-events: none;
}
//
// Alternate buttons
//
@each $color, $value in $theme-colors {
.btn-#{$color} {
@include button-variant($value, $value);
}
}
@each $color, $value in $theme-colors {
.btn-outline-#{$color} {
@include button-outline-variant($value);
}
}
//
// Link buttons
//
// Make a button look and behave like a link
.btn-link {
font-weight: $font-weight-normal;
color: $link-color;
text-decoration: $link-decoration;
@include hover() {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
&:focus,
&.focus {
text-decoration: $link-hover-decoration;
}
&:disabled,
&.disabled {
color: $btn-link-disabled-color;
pointer-events: none;
}
// No need for an active state here
}
//
// Button Sizes
//
.btn-lg {
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
}
.btn-sm {
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
}
//
// Block button
//
.btn-block {
display: block;
width: 100%;
// Vertically space out multiple block buttons
+ .btn-block {
margin-top: $btn-block-spacing-y;
}
}
// Specificity overrides
input[type="submit"],
input[type="reset"],
input[type="button"] {
&.btn-block {
width: 100%;
}
}
+286
View File
@@ -0,0 +1,286 @@
//
// Base styles
//
.card {
position: relative;
display: flex;
flex-direction: column;
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
height: $card-height;
word-wrap: break-word;
background-color: $card-bg;
background-clip: border-box;
border: $card-border-width solid $card-border-color;
@include border-radius($card-border-radius);
> hr {
margin-right: 0;
margin-left: 0;
}
> .list-group {
border-top: inherit;
border-bottom: inherit;
&:first-child {
border-top-width: 0;
@include border-top-radius($card-inner-border-radius);
}
&:last-child {
border-bottom-width: 0;
@include border-bottom-radius($card-inner-border-radius);
}
}
// Due to specificity of the above selector (`.card > .list-group`), we must
// use a child selector here to prevent double borders.
> .card-header + .list-group,
> .list-group + .card-footer {
border-top: 0;
}
}
.card-body {
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
// as much space as possible, ensuring footers are aligned to the bottom.
flex: 1 1 auto;
// Workaround for the image size bug in IE
// See: https://github.com/twbs/bootstrap/pull/28855
min-height: 1px;
padding: $card-spacer-x;
color: $card-color;
}
.card-title {
margin-bottom: $card-spacer-y;
}
.card-subtitle {
margin-top: -$card-spacer-y / 2;
margin-bottom: 0;
}
.card-text:last-child {
margin-bottom: 0;
}
.card-link {
@include hover() {
text-decoration: none;
}
+ .card-link {
margin-left: $card-spacer-x;
}
}
//
// Optional textual caps
//
.card-header {
padding: $card-spacer-y $card-spacer-x;
margin-bottom: 0; // Removes the default margin-bottom of <hN>
color: $card-cap-color;
background-color: $card-cap-bg;
border-bottom: $card-border-width solid $card-border-color;
&:first-child {
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
}
}
.card-footer {
padding: $card-spacer-y $card-spacer-x;
color: $card-cap-color;
background-color: $card-cap-bg;
border-top: $card-border-width solid $card-border-color;
&:last-child {
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
}
}
//
// Header navs
//
.card-header-tabs {
margin-right: -$card-spacer-x / 2;
margin-bottom: -$card-spacer-y;
margin-left: -$card-spacer-x / 2;
border-bottom: 0;
}
.card-header-pills {
margin-right: -$card-spacer-x / 2;
margin-left: -$card-spacer-x / 2;
}
// Card image
.card-img-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
padding: $card-img-overlay-padding;
@include border-radius($card-inner-border-radius);
}
.card-img,
.card-img-top,
.card-img-bottom {
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
}
.card-img,
.card-img-top {
@include border-top-radius($card-inner-border-radius);
}
.card-img,
.card-img-bottom {
@include border-bottom-radius($card-inner-border-radius);
}
// Card deck
.card-deck {
.card {
margin-bottom: $card-deck-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
margin-right: -$card-deck-margin;
margin-left: -$card-deck-margin;
.card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-right: $card-deck-margin;
margin-bottom: 0; // Override the default
margin-left: $card-deck-margin;
}
}
}
//
// Card groups
//
.card-group {
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
margin-bottom: $card-group-margin;
}
@include media-breakpoint-up(sm) {
display: flex;
flex-flow: row wrap;
// The child selector allows nested `.card` within `.card-group`
// to display properly.
> .card {
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
flex: 1 0 0%;
margin-bottom: 0;
+ .card {
margin-left: 0;
border-left: 0;
}
// Handle rounded corners
@if $enable-rounded {
&:not(:last-child) {
@include border-right-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-right-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-right-radius: 0;
}
}
&:not(:first-child) {
@include border-left-radius(0);
.card-img-top,
.card-header {
// stylelint-disable-next-line property-blacklist
border-top-left-radius: 0;
}
.card-img-bottom,
.card-footer {
// stylelint-disable-next-line property-blacklist
border-bottom-left-radius: 0;
}
}
}
}
}
}
//
// Columns
//
.card-columns {
.card {
margin-bottom: $card-columns-margin;
}
@include media-breakpoint-up(sm) {
column-count: $card-columns-count;
column-gap: $card-columns-gap;
orphans: 1;
widows: 1;
.card {
display: inline-block; // Don't let them vertically span multiple columns
width: 100%; // Don't let their width change
}
}
}
//
// Accordion
//
.accordion {
overflow-anchor: none;
> .card {
overflow: hidden;
&:not(:last-of-type) {
border-bottom: 0;
@include border-bottom-radius(0);
}
&:not(:first-of-type) {
@include border-top-radius(0);
}
> .card-header {
@include border-radius(0);
margin-bottom: -$card-border-width;
}
}
}
+197
View File
@@ -0,0 +1,197 @@
// Notes on the classes:
//
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
// we're preventing all actions instead
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
// the active slide is heading.
// 3. .active.carousel-item is the current slide.
// 4. .active.carousel-item-left and .active.carousel-item-right is the current
// slide in its in-transition state. Only one of these occurs at a time.
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
// is the upcoming slide in transition.
.carousel {
position: relative;
}
.carousel.pointer-event {
touch-action: pan-y;
}
.carousel-inner {
position: relative;
width: 100%;
overflow: hidden;
@include clearfix();
}
.carousel-item {
position: relative;
display: none;
float: left;
width: 100%;
margin-right: -100%;
backface-visibility: hidden;
@include transition($carousel-transition);
}
.carousel-item.active,
.carousel-item-next,
.carousel-item-prev {
display: block;
}
.carousel-item-next:not(.carousel-item-left),
.active.carousel-item-right {
transform: translateX(100%);
}
.carousel-item-prev:not(.carousel-item-right),
.active.carousel-item-left {
transform: translateX(-100%);
}
//
// Alternate transitions
//
.carousel-fade {
.carousel-item {
opacity: 0;
transition-property: opacity;
transform: none;
}
.carousel-item.active,
.carousel-item-next.carousel-item-left,
.carousel-item-prev.carousel-item-right {
z-index: 1;
opacity: 1;
}
.active.carousel-item-left,
.active.carousel-item-right {
z-index: 0;
opacity: 0;
@include transition(opacity 0s $carousel-transition-duration);
}
}
//
// Left/right controls for nav
//
.carousel-control-prev,
.carousel-control-next {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
// Use flex for alignment (1-3)
display: flex; // 1. allow flex styles
align-items: center; // 2. vertically center contents
justify-content: center; // 3. horizontally center contents
width: $carousel-control-width;
color: $carousel-control-color;
text-align: center;
opacity: $carousel-control-opacity;
@include transition($carousel-control-transition);
// Hover/focus state
@include hover-focus() {
color: $carousel-control-color;
text-decoration: none;
outline: 0;
opacity: $carousel-control-hover-opacity;
}
}
.carousel-control-prev {
left: 0;
@if $enable-gradients {
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
}
}
.carousel-control-next {
right: 0;
@if $enable-gradients {
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));
}
}
// Icons for within
.carousel-control-prev-icon,
.carousel-control-next-icon {
display: inline-block;
width: $carousel-control-icon-width;
height: $carousel-control-icon-width;
background: no-repeat 50% / 100% 100%;
}
.carousel-control-prev-icon {
background-image: escape-svg($carousel-control-prev-icon-bg);
}
.carousel-control-next-icon {
background-image: escape-svg($carousel-control-next-icon-bg);
}
// Optional indicator pips
//
// Add an ordered list with the following class and add a list item for each
// slide your carousel holds.
.carousel-indicators {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 15;
display: flex;
justify-content: center;
padding-left: 0; // override <ol> default
// Use the .carousel-control's width as margin so we don't overlay those
margin-right: $carousel-control-width;
margin-left: $carousel-control-width;
list-style: none;
li {
box-sizing: content-box;
flex: 0 1 auto;
width: $carousel-indicator-width;
height: $carousel-indicator-height;
margin-right: $carousel-indicator-spacer;
margin-left: $carousel-indicator-spacer;
text-indent: -999px;
cursor: pointer;
background-color: $carousel-indicator-active-bg;
background-clip: padding-box;
// Use transparent borders to increase the hit area by 10px on top and bottom.
border-top: $carousel-indicator-hit-area-height solid transparent;
border-bottom: $carousel-indicator-hit-area-height solid transparent;
opacity: .5;
@include transition($carousel-indicator-transition);
}
.active {
opacity: 1;
}
}
// Optional captions
//
//
.carousel-caption {
position: absolute;
right: (100% - $carousel-caption-width) / 2;
bottom: 20px;
left: (100% - $carousel-caption-width) / 2;
z-index: 10;
padding-top: 20px;
padding-bottom: 20px;
color: $carousel-caption-color;
text-align: center;
}
+40
View File
@@ -0,0 +1,40 @@
.close {
float: right;
@include font-size($close-font-size);
font-weight: $close-font-weight;
line-height: 1;
color: $close-color;
text-shadow: $close-text-shadow;
opacity: .5;
// Override <a>'s hover style
@include hover() {
color: $close-color;
text-decoration: none;
}
&:not(:disabled):not(.disabled) {
@include hover-focus() {
opacity: .75;
}
}
}
// Additional properties for button version
// iOS requires the button element instead of an anchor tag.
// If you want the anchor version, it requires `href="#"`.
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
// stylelint-disable-next-line selector-no-qualifying-type
button.close {
padding: 0;
background-color: transparent;
border: 0;
}
// Future-proof disabling of clicks on `<a>` elements
// stylelint-disable-next-line selector-no-qualifying-type
a.close.disabled {
pointer-events: none;
}
+48
View File
@@ -0,0 +1,48 @@
// Inline code
code {
@include font-size($code-font-size);
color: $code-color;
word-wrap: break-word;
// Streamline the style when inside anchors to avoid broken underline and more
a > & {
color: inherit;
}
}
// User input typically entered via keyboard
kbd {
padding: $kbd-padding-y $kbd-padding-x;
@include font-size($kbd-font-size);
color: $kbd-color;
background-color: $kbd-bg;
@include border-radius($border-radius-sm);
@include box-shadow($kbd-box-shadow);
kbd {
padding: 0;
@include font-size(100%);
font-weight: $nested-kbd-font-weight;
@include box-shadow(none);
}
}
// Blocks of code
pre {
display: block;
@include font-size($code-font-size);
color: $pre-color;
// Account for some code outputs that place code tags in pre tags
code {
@include font-size(inherit);
color: inherit;
word-break: normal;
}
}
// Enable scrollable blocks of code
.pre-scrollable {
max-height: $pre-scrollable-max-height;
overflow-y: scroll;
}
@@ -0,0 +1,523 @@
// Embedded icons from Open Iconic.
// Released under MIT and copyright 2014 Waybury.
// https://useiconic.com/open
// Checkboxes and radios
//
// Base class takes care of all the key behavioral aspects.
.custom-control {
position: relative;
z-index: 1;
display: block;
min-height: $font-size-base * $line-height-base;
padding-left: $custom-control-gutter + $custom-control-indicator-size;
}
.custom-control-inline {
display: inline-flex;
margin-right: $custom-control-spacer-x;
}
.custom-control-input {
position: absolute;
left: 0;
z-index: -1; // Put the input behind the label so it doesn't overlay text
width: $custom-control-indicator-size;
height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;
opacity: 0;
&:checked ~ .custom-control-label::before {
color: $custom-control-indicator-checked-color;
border-color: $custom-control-indicator-checked-border-color;
@include gradient-bg($custom-control-indicator-checked-bg);
@include box-shadow($custom-control-indicator-checked-box-shadow);
}
&:focus ~ .custom-control-label::before {
// the mixin is not used here to make sure there is feedback
@if $enable-shadows {
box-shadow: $input-box-shadow, $input-focus-box-shadow;
} @else {
box-shadow: $custom-control-indicator-focus-box-shadow;
}
}
&:focus:not(:checked) ~ .custom-control-label::before {
border-color: $custom-control-indicator-focus-border-color;
}
&:not(:disabled):active ~ .custom-control-label::before {
color: $custom-control-indicator-active-color;
background-color: $custom-control-indicator-active-bg;
border-color: $custom-control-indicator-active-border-color;
@include box-shadow($custom-control-indicator-active-box-shadow);
}
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
&[disabled],
&:disabled {
~ .custom-control-label {
color: $custom-control-label-disabled-color;
&::before {
background-color: $custom-control-indicator-disabled-bg;
}
}
}
}
// Custom control indicators
//
// Build the custom controls out of pseudo-elements.
.custom-control-label {
position: relative;
margin-bottom: 0;
color: $custom-control-label-color;
vertical-align: top;
cursor: $custom-control-cursor;
// Background-color and (when enabled) gradient
&::before {
position: absolute;
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
left: -($custom-control-gutter + $custom-control-indicator-size);
display: block;
width: $custom-control-indicator-size;
height: $custom-control-indicator-size;
pointer-events: none;
content: "";
background-color: $custom-control-indicator-bg;
border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
@include box-shadow($custom-control-indicator-box-shadow);
}
// Foreground (icon)
&::after {
position: absolute;
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
left: -($custom-control-gutter + $custom-control-indicator-size);
display: block;
width: $custom-control-indicator-size;
height: $custom-control-indicator-size;
content: "";
background: no-repeat 50% / #{$custom-control-indicator-bg-size};
}
}
// Checkboxes
//
// Tweak just a few things for checkboxes.
.custom-checkbox {
.custom-control-label::before {
@include border-radius($custom-checkbox-indicator-border-radius);
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-image: escape-svg($custom-checkbox-indicator-icon-checked);
}
}
.custom-control-input:indeterminate ~ .custom-control-label {
&::before {
border-color: $custom-checkbox-indicator-indeterminate-border-color;
@include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
@include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
}
&::after {
background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
&:indeterminate ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
}
}
// Radios
//
// Tweak just a few things for radios.
.custom-radio {
.custom-control-label::before {
// stylelint-disable-next-line property-blacklist
border-radius: $custom-radio-indicator-border-radius;
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-image: escape-svg($custom-radio-indicator-icon-checked);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
}
}
// switches
//
// Tweak a few things for switches
.custom-switch {
padding-left: $custom-switch-width + $custom-control-gutter;
.custom-control-label {
&::before {
left: -($custom-switch-width + $custom-control-gutter);
width: $custom-switch-width;
pointer-events: all;
// stylelint-disable-next-line property-blacklist
border-radius: $custom-switch-indicator-border-radius;
}
&::after {
top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
width: $custom-switch-indicator-size;
height: $custom-switch-indicator-size;
background-color: $custom-control-indicator-border-color;
// stylelint-disable-next-line property-blacklist
border-radius: $custom-switch-indicator-border-radius;
@include transition(transform .15s ease-in-out, $custom-forms-transition);
}
}
.custom-control-input:checked ~ .custom-control-label {
&::after {
background-color: $custom-control-indicator-bg;
transform: translateX($custom-switch-width - $custom-control-indicator-size);
}
}
.custom-control-input:disabled {
&:checked ~ .custom-control-label::before {
@include gradient-bg($custom-control-indicator-checked-disabled-bg);
}
}
}
// Select
//
// Replaces the browser default select with a custom one, mostly pulled from
// https://primer.github.io/.
//
.custom-select {
display: inline-block;
width: 100%;
height: $custom-select-height;
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
font-family: $custom-select-font-family;
@include font-size($custom-select-font-size);
font-weight: $custom-select-font-weight;
line-height: $custom-select-line-height;
color: $custom-select-color;
vertical-align: middle;
background: $custom-select-bg $custom-select-background;
border: $custom-select-border-width solid $custom-select-border-color;
@include border-radius($custom-select-border-radius, 0);
@include box-shadow($custom-select-box-shadow);
appearance: none;
&:focus {
border-color: $custom-select-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($custom-select-box-shadow, $custom-select-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $custom-select-focus-box-shadow;
}
&::-ms-value {
// For visual consistency with other platforms/browsers,
// suppress the default white text on blue background highlight given to
// the selected option text when the (still closed) <select> receives focus
// in IE and (under certain conditions) Edge.
// See https://github.com/twbs/bootstrap/issues/19398.
color: $input-color;
background-color: $input-bg;
}
}
&[multiple],
&[size]:not([size="1"]) {
height: auto;
padding-right: $custom-select-padding-x;
background-image: none;
}
&:disabled {
color: $custom-select-disabled-color;
background-color: $custom-select-disabled-bg;
}
// Hides the default caret in IE11
&::-ms-expand {
display: none;
}
// Remove outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $custom-select-color;
}
}
.custom-select-sm {
height: $custom-select-height-sm;
padding-top: $custom-select-padding-y-sm;
padding-bottom: $custom-select-padding-y-sm;
padding-left: $custom-select-padding-x-sm;
@include font-size($custom-select-font-size-sm);
}
.custom-select-lg {
height: $custom-select-height-lg;
padding-top: $custom-select-padding-y-lg;
padding-bottom: $custom-select-padding-y-lg;
padding-left: $custom-select-padding-x-lg;
@include font-size($custom-select-font-size-lg);
}
// File
//
// Custom file input.
.custom-file {
position: relative;
display: inline-block;
width: 100%;
height: $custom-file-height;
margin-bottom: 0;
}
.custom-file-input {
position: relative;
z-index: 2;
width: 100%;
height: $custom-file-height;
margin: 0;
opacity: 0;
&:focus ~ .custom-file-label {
border-color: $custom-file-focus-border-color;
box-shadow: $custom-file-focus-box-shadow;
}
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
&[disabled] ~ .custom-file-label,
&:disabled ~ .custom-file-label {
background-color: $custom-file-disabled-bg;
}
@each $lang, $value in $custom-file-text {
&:lang(#{$lang}) ~ .custom-file-label::after {
content: $value;
}
}
~ .custom-file-label[data-browse]::after {
content: attr(data-browse);
}
}
.custom-file-label {
position: absolute;
top: 0;
right: 0;
left: 0;
z-index: 1;
height: $custom-file-height;
padding: $custom-file-padding-y $custom-file-padding-x;
font-family: $custom-file-font-family;
font-weight: $custom-file-font-weight;
line-height: $custom-file-line-height;
color: $custom-file-color;
background-color: $custom-file-bg;
border: $custom-file-border-width solid $custom-file-border-color;
@include border-radius($custom-file-border-radius);
@include box-shadow($custom-file-box-shadow);
&::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
z-index: 3;
display: block;
height: $custom-file-height-inner;
padding: $custom-file-padding-y $custom-file-padding-x;
line-height: $custom-file-line-height;
color: $custom-file-button-color;
content: "Browse";
@include gradient-bg($custom-file-button-bg);
border-left: inherit;
@include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
}
}
// Range
//
// Style range inputs the same across browsers. Vendor-specific rules for pseudo
// elements cannot be mixed. As such, there are no shared styles for focus or
// active states on prefixed selectors.
.custom-range {
width: 100%;
height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
padding: 0; // Need to reset padding
background-color: transparent;
appearance: none;
&:focus {
outline: none;
// Pseudo-elements must be split across multiple rulesets to have an effect.
// No box-shadow() mixin for focus accessibility.
&::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
&::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
&::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
}
&::-moz-focus-outer {
border: 0;
}
&::-webkit-slider-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include gradient-bg($custom-range-thumb-active-bg);
}
}
&::-webkit-slider-runnable-track {
width: $custom-range-track-width;
height: $custom-range-track-height;
color: transparent; // Why?
cursor: $custom-range-track-cursor;
background-color: $custom-range-track-bg;
border-color: transparent;
@include border-radius($custom-range-track-border-radius);
@include box-shadow($custom-range-track-box-shadow);
}
&::-moz-range-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include gradient-bg($custom-range-thumb-active-bg);
}
}
&::-moz-range-track {
width: $custom-range-track-width;
height: $custom-range-track-height;
color: transparent;
cursor: $custom-range-track-cursor;
background-color: $custom-range-track-bg;
border-color: transparent; // Firefox specific?
@include border-radius($custom-range-track-border-radius);
@include box-shadow($custom-range-track-box-shadow);
}
&::-ms-thumb {
width: $custom-range-thumb-width;
height: $custom-range-thumb-height;
margin-top: 0; // Edge specific
margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
@include gradient-bg($custom-range-thumb-bg);
border: $custom-range-thumb-border;
@include border-radius($custom-range-thumb-border-radius);
@include box-shadow($custom-range-thumb-box-shadow);
@include transition($custom-forms-transition);
appearance: none;
&:active {
@include gradient-bg($custom-range-thumb-active-bg);
}
}
&::-ms-track {
width: $custom-range-track-width;
height: $custom-range-track-height;
color: transparent;
cursor: $custom-range-track-cursor;
background-color: transparent;
border-color: transparent;
border-width: $custom-range-thumb-height / 2;
@include box-shadow($custom-range-track-box-shadow);
}
&::-ms-fill-lower {
background-color: $custom-range-track-bg;
@include border-radius($custom-range-track-border-radius);
}
&::-ms-fill-upper {
margin-right: 15px; // arbitrary?
background-color: $custom-range-track-bg;
@include border-radius($custom-range-track-border-radius);
}
&:disabled {
&::-webkit-slider-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
&::-webkit-slider-runnable-track {
cursor: default;
}
&::-moz-range-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
&::-moz-range-track {
cursor: default;
}
&::-ms-thumb {
background-color: $custom-range-thumb-disabled-bg;
}
}
}
.custom-control-label::before,
.custom-file-label,
.custom-select {
@include transition($custom-forms-transition);
}
+192
View File
@@ -0,0 +1,192 @@
// The dropdown wrapper (`<div>`)
.dropup,
.dropright,
.dropdown,
.dropleft {
position: relative;
}
.dropdown-toggle {
white-space: nowrap;
// Generate the caret automatically
@include caret();
}
// The dropdown menu
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: $zindex-dropdown;
display: none; // none by default, but block on "open" of the menu
float: left;
min-width: $dropdown-min-width;
padding: $dropdown-padding-y 0;
margin: $dropdown-spacer 0 0; // override default ul
@include font-size($dropdown-font-size);
color: $dropdown-color;
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
list-style: none;
background-color: $dropdown-bg;
background-clip: padding-box;
border: $dropdown-border-width solid $dropdown-border-color;
@include border-radius($dropdown-border-radius);
@include box-shadow($dropdown-box-shadow);
}
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.dropdown-menu#{$infix}-left {
right: auto;
left: 0;
}
.dropdown-menu#{$infix}-right {
right: 0;
left: auto;
}
}
}
// Allow for dropdowns to go bottom up (aka, dropup-menu)
// Just add .dropup after the standard .dropdown class and you're set.
.dropup {
.dropdown-menu {
top: auto;
bottom: 100%;
margin-top: 0;
margin-bottom: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(up);
}
}
.dropright {
.dropdown-menu {
top: 0;
right: auto;
left: 100%;
margin-top: 0;
margin-left: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(right);
&::after {
vertical-align: 0;
}
}
}
.dropleft {
.dropdown-menu {
top: 0;
right: 100%;
left: auto;
margin-top: 0;
margin-right: $dropdown-spacer;
}
.dropdown-toggle {
@include caret(left);
&::before {
vertical-align: 0;
}
}
}
// When enabled Popper.js, reset basic dropdown position
// stylelint-disable-next-line no-duplicate-selectors
.dropdown-menu {
&[x-placement^="top"],
&[x-placement^="right"],
&[x-placement^="bottom"],
&[x-placement^="left"] {
right: auto;
bottom: auto;
}
}
// Dividers (basically an `<hr>`) within the dropdown
.dropdown-divider {
@include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);
}
// Links, buttons, and more within the dropdown menu
//
// `<button>`-specific styles are denoted with `// For <button>s`
.dropdown-item {
display: block;
width: 100%; // For `<button>`s
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
clear: both;
font-weight: $font-weight-normal;
color: $dropdown-link-color;
text-align: inherit; // For `<button>`s
text-decoration: if($link-decoration == none, null, none);
white-space: nowrap; // prevent links from randomly breaking onto new lines
background-color: transparent; // For `<button>`s
border: 0; // For `<button>`s
// Prevent dropdown overflow if there's no padding
// See https://github.com/twbs/bootstrap/pull/27703
@if $dropdown-padding-y == 0 {
&:first-child {
@include border-top-radius($dropdown-inner-border-radius);
}
&:last-child {
@include border-bottom-radius($dropdown-inner-border-radius);
}
}
@include hover-focus() {
color: $dropdown-link-hover-color;
text-decoration: none;
@include gradient-bg($dropdown-link-hover-bg);
}
&.active,
&:active {
color: $dropdown-link-active-color;
text-decoration: none;
@include gradient-bg($dropdown-link-active-bg);
}
&.disabled,
&:disabled {
color: $dropdown-link-disabled-color;
pointer-events: none;
background-color: transparent;
// Remove CSS gradients if they're enabled
@if $enable-gradients {
background-image: none;
}
}
}
.dropdown-menu.show {
display: block;
}
// Dropdown section headers
.dropdown-header {
display: block;
padding: $dropdown-header-padding;
margin-bottom: 0; // for use with heading elements
@include font-size($font-size-sm);
color: $dropdown-header-color;
white-space: nowrap; // as with > li > a
}
// Dropdown text
.dropdown-item-text {
display: block;
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
color: $dropdown-link-color;
}
+347
View File
@@ -0,0 +1,347 @@
// stylelint-disable selector-no-qualifying-type
//
// Textual form controls
//
.form-control {
display: block;
width: 100%;
height: $input-height;
padding: $input-padding-y $input-padding-x;
font-family: $input-font-family;
@include font-size($input-font-size);
font-weight: $input-font-weight;
line-height: $input-line-height;
color: $input-color;
background-color: $input-bg;
background-clip: padding-box;
border: $input-border-width solid $input-border-color;
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
@include border-radius($input-border-radius, 0);
@include box-shadow($input-box-shadow);
@include transition($input-transition);
// Unstyle the caret on `<select>`s in IE10+.
&::-ms-expand {
background-color: transparent;
border: 0;
}
// Remove select outline from select box in FF
&:-moz-focusring {
color: transparent;
text-shadow: 0 0 0 $input-color;
}
// Customize the `:focus` state to imitate native WebKit styles.
@include form-control-focus($ignore-warning: true);
// Placeholder
&::placeholder {
color: $input-placeholder-color;
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
opacity: 1;
}
// Disabled and read-only inputs
//
// HTML5 says that controls under a fieldset > legend:first-child won't be
// disabled if the fieldset is disabled. Due to implementation difficulty, we
// don't honor that edge case; we style them as disabled anyway.
&:disabled,
&[readonly] {
background-color: $input-disabled-bg;
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
opacity: 1;
}
}
input[type="date"],
input[type="time"],
input[type="datetime-local"],
input[type="month"] {
&.form-control {
appearance: none; // Fix appearance for date inputs in Safari
}
}
select.form-control {
&:focus::-ms-value {
// Suppress the nested default white text on blue background highlight given to
// the selected option text when the (still closed) <select> receives focus
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
// match the appearance of the native widget.
// See https://github.com/twbs/bootstrap/issues/19398.
color: $input-color;
background-color: $input-bg;
}
}
// Make file inputs better match text inputs by forcing them to new lines.
.form-control-file,
.form-control-range {
display: block;
width: 100%;
}
//
// Labels
//
// For use with horizontal and inline forms, when you need the label (or legend)
// text to align with the form controls.
.col-form-label {
padding-top: add($input-padding-y, $input-border-width);
padding-bottom: add($input-padding-y, $input-border-width);
margin-bottom: 0; // Override the `<label>/<legend>` default
@include font-size(inherit); // Override the `<legend>` default
line-height: $input-line-height;
}
.col-form-label-lg {
padding-top: add($input-padding-y-lg, $input-border-width);
padding-bottom: add($input-padding-y-lg, $input-border-width);
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
}
.col-form-label-sm {
padding-top: add($input-padding-y-sm, $input-border-width);
padding-bottom: add($input-padding-y-sm, $input-border-width);
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
}
// Readonly controls as plain text
//
// Apply class to a readonly input to make it appear like regular plain
// text (without any border, background color, focus indicator)
.form-control-plaintext {
display: block;
width: 100%;
padding: $input-padding-y 0;
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
@include font-size($input-font-size);
line-height: $input-line-height;
color: $input-plaintext-color;
background-color: transparent;
border: solid transparent;
border-width: $input-border-width 0;
&.form-control-sm,
&.form-control-lg {
padding-right: 0;
padding-left: 0;
}
}
// Form control sizing
//
// Build on `.form-control` with modifier classes to decrease or increase the
// height and font-size of form controls.
//
// Repeated in `_input_group.scss` to avoid Sass extend issues.
.form-control-sm {
height: $input-height-sm;
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
@include border-radius($input-border-radius-sm);
}
.form-control-lg {
height: $input-height-lg;
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
@include border-radius($input-border-radius-lg);
}
// stylelint-disable-next-line no-duplicate-selectors
select.form-control {
&[size],
&[multiple] {
height: auto;
}
}
textarea.form-control {
height: auto;
}
// Form groups
//
// Designed to help with the organization and spacing of vertical forms. For
// horizontal forms, use the predefined grid classes.
.form-group {
margin-bottom: $form-group-margin-bottom;
}
.form-text {
display: block;
margin-top: $form-text-margin-top;
}
// Form grid
//
// Special replacement for our grid system's `.row` for tighter form layouts.
.form-row {
display: flex;
flex-wrap: wrap;
margin-right: -$form-grid-gutter-width / 2;
margin-left: -$form-grid-gutter-width / 2;
> .col,
> [class*="col-"] {
padding-right: $form-grid-gutter-width / 2;
padding-left: $form-grid-gutter-width / 2;
}
}
// Checkboxes and radios
//
// Indent the labels to position radios/checkboxes as hanging controls.
.form-check {
position: relative;
display: block;
padding-left: $form-check-input-gutter;
}
.form-check-input {
position: absolute;
margin-top: $form-check-input-margin-y;
margin-left: -$form-check-input-gutter;
// Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247
&[disabled] ~ .form-check-label,
&:disabled ~ .form-check-label {
color: $text-muted;
}
}
.form-check-label {
margin-bottom: 0; // Override default `<label>` bottom margin
}
.form-check-inline {
display: inline-flex;
align-items: center;
padding-left: 0; // Override base .form-check
margin-right: $form-check-inline-margin-x;
// Undo .form-check-input defaults and add some `margin-right`.
.form-check-input {
position: static;
margin-top: 0;
margin-right: $form-check-inline-input-margin-x;
margin-left: 0;
}
}
// Form validation
//
// Provide feedback to users when form field values are valid or invalid. Works
// primarily for client-side validation via scoped `:invalid` and `:valid`
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
// server side validation.
@each $state, $data in $form-validation-states {
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
}
// Inline forms
//
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
// forms begin stacked on extra small (mobile) devices and then go inline when
// viewports reach <768px.
//
// Requires wrapping inputs and labels with `.form-group` for proper display of
// default HTML form controls and our custom form controls (e.g., input groups).
.form-inline {
display: flex;
flex-flow: row wrap;
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
// Because we use flex, the initial sizing of checkboxes is collapsed and
// doesn't occupy the full-width (which is what we want for xs grid tier),
// so we force that here.
.form-check {
width: 100%;
}
// Kick in the inline
@include media-breakpoint-up(sm) {
label {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 0;
}
// Inline-block all the things for "inline"
.form-group {
display: flex;
flex: 0 0 auto;
flex-flow: row wrap;
align-items: center;
margin-bottom: 0;
}
// Allow folks to *not* use `.form-group`
.form-control {
display: inline-block;
width: auto; // Prevent labels from stacking above inputs in `.form-group`
vertical-align: middle;
}
// Make static controls behave like regular ones
.form-control-plaintext {
display: inline-block;
}
.input-group,
.custom-select {
width: auto;
}
// Remove default margin on radios/checkboxes that were used for stacking, and
// then undo the floating of radios and checkboxes to match.
.form-check {
display: flex;
align-items: center;
justify-content: center;
width: auto;
padding-left: 0;
}
.form-check-input {
position: relative;
flex-shrink: 0;
margin-top: 0;
margin-right: $form-check-input-margin-x;
margin-left: 0;
}
.custom-control {
align-items: center;
justify-content: center;
}
.custom-control-label {
margin-bottom: 0;
}
}
}
+141
View File
@@ -0,0 +1,141 @@
// Bootstrap functions
//
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
// Ascending
// Used to evaluate Sass maps like our grid breakpoints.
@mixin _assert-ascending($map, $map-name) {
$prev-key: null;
$prev-num: null;
@each $key, $num in $map {
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
// Do nothing
} @else if not comparable($prev-num, $num) {
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
} @else if $prev-num >= $num {
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
}
$prev-key: $key;
$prev-num: $num;
}
}
// Starts at zero
// Used to ensure the min-width of the lowest breakpoint starts at 0.
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
@if length($map) > 0 {
$values: map-values($map);
$first-value: nth($values, 1);
@if $first-value != 0 {
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
}
}
}
// Replace `$search` with `$replace` in `$string`
// Used on our SVG icon backgrounds for custom forms.
//
// @author Hugo Giraudel
// @param {String} $string - Initial string
// @param {String} $search - Substring to replace
// @param {String} $replace ('') - New value
// @return {String} - Updated string
@function str-replace($string, $search, $replace: "") {
$index: str-index($string, $search);
@if $index {
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
}
@return $string;
}
// See https://codepen.io/kevinweber/pen/dXWoRw
@function escape-svg($string) {
@if str-index($string, "data:image/svg+xml") {
@each $char, $encoded in $escaped-characters {
// Do not escape the url brackets
@if str-index($string, "url(") == 1 {
$string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");
} @else {
$string: str-replace($string, $char, $encoded);
}
}
}
@return $string;
}
// Color contrast
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
$r: red($color);
$g: green($color);
$b: blue($color);
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
@if ($yiq >= $yiq-contrasted-threshold) {
@return $dark;
} @else {
@return $light;
}
}
// Retrieve color Sass maps
@function color($key: "blue") {
@return map-get($colors, $key);
}
@function theme-color($key: "primary") {
@return map-get($theme-colors, $key);
}
@function gray($key: "100") {
@return map-get($grays, $key);
}
// Request a theme color level
@function theme-color-level($color-name: "primary", $level: 0) {
$color: theme-color($color-name);
$color-base: if($level > 0, $black, $white);
$level: abs($level);
@return mix($color-base, $color, $level * $theme-color-interval);
}
// Return valid calc
@function add($value1, $value2, $return-calc: true) {
@if $value1 == null {
@return $value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 + $value2;
}
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
}
@function subtract($value1, $value2, $return-calc: true) {
@if $value1 == null and $value2 == null {
@return null;
}
@if $value1 == null {
@return -$value2;
}
@if $value2 == null {
@return $value1;
}
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
@return $value1 - $value2;
}
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
}
+73
View File
@@ -0,0 +1,73 @@
// Container widths
//
// Set the container width, and override it for fixed navbars in media queries.
@if $enable-grid-classes {
// Single container class with breakpoint max-widths
.container,
// 100% wide container at all breakpoints
.container-fluid {
@include make-container();
}
// Responsive containers that are 100% wide until a breakpoint
@each $breakpoint, $container-max-width in $container-max-widths {
.container-#{$breakpoint} {
@extend .container-fluid;
}
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
%responsive-container-#{$breakpoint} {
max-width: $container-max-width;
}
// Extend each breakpoint which is smaller or equal to the current breakpoint
$extend-breakpoint: true;
@each $name, $width in $grid-breakpoints {
@if ($extend-breakpoint) {
.container#{breakpoint-infix($name, $grid-breakpoints)} {
@extend %responsive-container-#{$breakpoint};
}
// Once the current breakpoint is reached, stop extending
@if ($breakpoint == $name) {
$extend-breakpoint: false;
}
}
}
}
}
}
// Row
//
// Rows contain your columns.
@if $enable-grid-classes {
.row {
@include make-row();
}
// Remove the negative margin from default .row, then the horizontal padding
// from all immediate children columns (to prevent runaway style inheritance).
.no-gutters {
margin-right: 0;
margin-left: 0;
> .col,
> [class*="col-"] {
padding-right: 0;
padding-left: 0;
}
}
}
// Columns
//
// Common styles for small and large grid columns
@if $enable-grid-classes {
@include make-grid-columns();
}
+42
View File
@@ -0,0 +1,42 @@
// Responsive images (ensure images don't scale beyond their parents)
//
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
// which weren't expecting the images within themselves to be involuntarily resized.
// See also https://github.com/twbs/bootstrap/issues/18178
.img-fluid {
@include img-fluid();
}
// Image thumbnails
.img-thumbnail {
padding: $thumbnail-padding;
background-color: $thumbnail-bg;
border: $thumbnail-border-width solid $thumbnail-border-color;
@include border-radius($thumbnail-border-radius);
@include box-shadow($thumbnail-box-shadow);
// Keep them at most 100% wide
@include img-fluid();
}
//
// Figures
//
.figure {
// Ensures the caption's text aligns with the image.
display: inline-block;
}
.figure-img {
margin-bottom: $spacer / 2;
line-height: 1;
}
.figure-caption {
@include font-size($figure-caption-font-size);
color: $figure-caption-color;
}
@@ -0,0 +1,192 @@
// stylelint-disable selector-no-qualifying-type
//
// Base styles
//
.input-group {
position: relative;
display: flex;
flex-wrap: wrap; // For form validation feedback
align-items: stretch;
width: 100%;
> .form-control,
> .form-control-plaintext,
> .custom-select,
> .custom-file {
position: relative; // For focus state's z-index
flex: 1 1 auto;
width: 1%;
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
margin-bottom: 0;
+ .form-control,
+ .custom-select,
+ .custom-file {
margin-left: -$input-border-width;
}
}
// Bring the "active" form control to the top of surrounding elements
> .form-control:focus,
> .custom-select:focus,
> .custom-file .custom-file-input:focus ~ .custom-file-label {
z-index: 3;
}
// Bring the custom file input above the label
> .custom-file .custom-file-input:focus {
z-index: 4;
}
> .form-control,
> .custom-select {
&:not(:last-child) { @include border-right-radius(0); }
&:not(:first-child) { @include border-left-radius(0); }
}
// Custom file inputs have more complex markup, thus requiring different
// border-radius overrides.
> .custom-file {
display: flex;
align-items: center;
&:not(:last-child) .custom-file-label,
&:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
}
}
// Prepend and append
//
// While it requires one extra layer of HTML for each, dedicated prepend and
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
// 3) support HTML5 form validation.
.input-group-prepend,
.input-group-append {
display: flex;
// Ensure buttons are always above inputs for more visually pleasing borders.
// This isn't needed for `.input-group-text` since it shares the same border-color
// as our inputs.
.btn {
position: relative;
z-index: 2;
&:focus {
z-index: 3;
}
}
.btn + .btn,
.btn + .input-group-text,
.input-group-text + .input-group-text,
.input-group-text + .btn {
margin-left: -$input-border-width;
}
}
.input-group-prepend { margin-right: -$input-border-width; }
.input-group-append { margin-left: -$input-border-width; }
// Textual addons
//
// Serves as a catch-all element for any text or radio/checkbox input you wish
// to prepend or append to an input.
.input-group-text {
display: flex;
align-items: center;
padding: $input-padding-y $input-padding-x;
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
@include font-size($input-font-size); // Match inputs
font-weight: $font-weight-normal;
line-height: $input-line-height;
color: $input-group-addon-color;
text-align: center;
white-space: nowrap;
background-color: $input-group-addon-bg;
border: $input-border-width solid $input-group-addon-border-color;
@include border-radius($input-border-radius);
// Nuke default margins from checkboxes and radios to vertically center within.
input[type="radio"],
input[type="checkbox"] {
margin-top: 0;
}
}
// Sizing
//
// Remix the default form control sizing classes into new ones for easier
// manipulation.
.input-group-lg > .form-control:not(textarea),
.input-group-lg > .custom-select {
height: $input-height-lg;
}
.input-group-lg > .form-control,
.input-group-lg > .custom-select,
.input-group-lg > .input-group-prepend > .input-group-text,
.input-group-lg > .input-group-append > .input-group-text,
.input-group-lg > .input-group-prepend > .btn,
.input-group-lg > .input-group-append > .btn {
padding: $input-padding-y-lg $input-padding-x-lg;
@include font-size($input-font-size-lg);
line-height: $input-line-height-lg;
@include border-radius($input-border-radius-lg);
}
.input-group-sm > .form-control:not(textarea),
.input-group-sm > .custom-select {
height: $input-height-sm;
}
.input-group-sm > .form-control,
.input-group-sm > .custom-select,
.input-group-sm > .input-group-prepend > .input-group-text,
.input-group-sm > .input-group-append > .input-group-text,
.input-group-sm > .input-group-prepend > .btn,
.input-group-sm > .input-group-append > .btn {
padding: $input-padding-y-sm $input-padding-x-sm;
@include font-size($input-font-size-sm);
line-height: $input-line-height-sm;
@include border-radius($input-border-radius-sm);
}
.input-group-lg > .custom-select,
.input-group-sm > .custom-select {
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
}
// Prepend and append rounded corners
//
// These rulesets must come after the sizing ones to properly override sm and lg
// border-radius values when extending. They're more specific than we'd like
// with the `.input-group >` part, but without it, we cannot override the sizing.
.input-group > .input-group-prepend > .btn,
.input-group > .input-group-prepend > .input-group-text,
.input-group > .input-group-append:not(:last-child) > .btn,
.input-group > .input-group-append:not(:last-child) > .input-group-text,
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
@include border-right-radius(0);
}
.input-group > .input-group-append > .btn,
.input-group > .input-group-append > .input-group-text,
.input-group > .input-group-prepend:not(:first-child) > .btn,
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
@include border-left-radius(0);
}
@@ -0,0 +1,17 @@
.jumbotron {
padding: $jumbotron-padding ($jumbotron-padding / 2);
margin-bottom: $jumbotron-padding;
color: $jumbotron-color;
background-color: $jumbotron-bg;
@include border-radius($border-radius-lg);
@include media-breakpoint-up(sm) {
padding: ($jumbotron-padding * 2) $jumbotron-padding;
}
}
.jumbotron-fluid {
padding-right: 0;
padding-left: 0;
@include border-radius(0);
}
+154
View File
@@ -0,0 +1,154 @@
// Base class
//
// Easily usable on <ul>, <ol>, or <div>.
.list-group {
display: flex;
flex-direction: column;
// No need to set list-style: none; since .list-group-item is block level
padding-left: 0; // reset padding because ul and ol
margin-bottom: 0;
@include border-radius($list-group-border-radius);
}
// Interactive list items
//
// Use anchor or button elements instead of `li`s or `div`s to create interactive
// list items. Includes an extra `.active` modifier class for selected items.
.list-group-item-action {
width: 100%; // For `<button>`s (anchors become 100% by default though)
color: $list-group-action-color;
text-align: inherit; // For `<button>`s (anchors inherit)
// Hover state
@include hover-focus() {
z-index: 1; // Place hover/focus items above their siblings for proper border styling
color: $list-group-action-hover-color;
text-decoration: none;
background-color: $list-group-hover-bg;
}
&:active {
color: $list-group-action-active-color;
background-color: $list-group-action-active-bg;
}
}
// Individual list items
//
// Use on `li`s or `div`s within the `.list-group` parent.
.list-group-item {
position: relative;
display: block;
padding: $list-group-item-padding-y $list-group-item-padding-x;
color: $list-group-color;
text-decoration: if($link-decoration == none, null, none);
background-color: $list-group-bg;
border: $list-group-border-width solid $list-group-border-color;
&:first-child {
@include border-top-radius(inherit);
}
&:last-child {
@include border-bottom-radius(inherit);
}
&.disabled,
&:disabled {
color: $list-group-disabled-color;
pointer-events: none;
background-color: $list-group-disabled-bg;
}
// Include both here for `<a>`s and `<button>`s
&.active {
z-index: 2; // Place active items above their siblings for proper border styling
color: $list-group-active-color;
background-color: $list-group-active-bg;
border-color: $list-group-active-border-color;
}
& + & {
border-top-width: 0;
&.active {
margin-top: -$list-group-border-width;
border-top-width: $list-group-border-width;
}
}
}
// Horizontal
//
// Change the layout of list group items from vertical (default) to horizontal.
@each $breakpoint in map-keys($grid-breakpoints) {
@include media-breakpoint-up($breakpoint) {
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
.list-group-horizontal#{$infix} {
flex-direction: row;
> .list-group-item {
&:first-child {
@include border-bottom-left-radius($list-group-border-radius);
@include border-top-right-radius(0);
}
&:last-child {
@include border-top-right-radius($list-group-border-radius);
@include border-bottom-left-radius(0);
}
&.active {
margin-top: 0;
}
& + .list-group-item {
border-top-width: $list-group-border-width;
border-left-width: 0;
&.active {
margin-left: -$list-group-border-width;
border-left-width: $list-group-border-width;
}
}
}
}
}
}
// Flush list items
//
// Remove borders and border-radius to keep list group items edge-to-edge. Most
// useful within other components (e.g., cards).
.list-group-flush {
@include border-radius(0);
> .list-group-item {
border-width: 0 0 $list-group-border-width;
&:last-child {
border-bottom-width: 0;
}
}
}
// Contextual variants
//
// Add modifier classes to change text and background color on individual items.
// Organizationally, this must come after the `:hover` states.
@each $color, $value in $theme-colors {
@include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
}
+8
View File
@@ -0,0 +1,8 @@
.media {
display: flex;
align-items: flex-start;
}
.media-body {
flex: 1;
}
+47
View File
@@ -0,0 +1,47 @@
// Toggles
//
// Used in conjunction with global variables to enable certain theme features.
// Vendor
@import "vendor/rfs";
// Deprecate
@import "mixins/deprecate";
// Utilities
@import "mixins/breakpoints";
@import "mixins/hover";
@import "mixins/image";
@import "mixins/badge";
@import "mixins/resize";
@import "mixins/screen-reader";
@import "mixins/size";
@import "mixins/reset-text";
@import "mixins/text-emphasis";
@import "mixins/text-hide";
@import "mixins/text-truncate";
@import "mixins/visibility";
// Components
@import "mixins/alert";
@import "mixins/buttons";
@import "mixins/caret";
@import "mixins/pagination";
@import "mixins/lists";
@import "mixins/list-group";
@import "mixins/nav-divider";
@import "mixins/forms";
@import "mixins/table-row";
// Skins
@import "mixins/background-variant";
@import "mixins/border-radius";
@import "mixins/box-shadow";
@import "mixins/gradients";
@import "mixins/transition";
// Layout
@import "mixins/clearfix";
@import "mixins/grid-framework";
@import "mixins/grid";
@import "mixins/float";
+240
View File
@@ -0,0 +1,240 @@
// .modal-open - body class for killing the scroll
// .modal - container to scroll within
// .modal-dialog - positioning shell for the actual modal
// .modal-content - actual modal w/ bg and corners and stuff
.modal-open {
// Kill the scroll on the body
overflow: hidden;
.modal {
overflow-x: hidden;
overflow-y: auto;
}
}
// Container that the modal scrolls within
.modal {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal;
display: none;
width: 100%;
height: 100%;
overflow: hidden;
// Prevent Chrome on Windows from adding a focus outline. For details, see
// https://github.com/twbs/bootstrap/pull/10951.
outline: 0;
// We deliberately don't use `-webkit-overflow-scrolling: touch;` due to a
// gnarly iOS Safari bug: https://bugs.webkit.org/show_bug.cgi?id=158342
// See also https://github.com/twbs/bootstrap/issues/17695
}
// Shell div to position the modal with bottom padding
.modal-dialog {
position: relative;
width: auto;
margin: $modal-dialog-margin;
// allow clicks to pass through for custom click handling to close modal
pointer-events: none;
// When fading in the modal, animate it to slide down
.modal.fade & {
@include transition($modal-transition);
transform: $modal-fade-transform;
}
.modal.show & {
transform: $modal-show-transform;
}
// When trying to close, animate focus to scale
.modal.modal-static & {
transform: $modal-scale-transform;
}
}
.modal-dialog-scrollable {
display: flex; // IE10/11
max-height: subtract(100%, $modal-dialog-margin * 2);
.modal-content {
max-height: subtract(100vh, $modal-dialog-margin * 2); // IE10/11
overflow: hidden;
}
.modal-header,
.modal-footer {
flex-shrink: 0;
}
.modal-body {
overflow-y: auto;
}
}
.modal-dialog-centered {
display: flex;
align-items: center;
min-height: subtract(100%, $modal-dialog-margin * 2);
// Ensure `modal-dialog-centered` extends the full height of the view (IE10/11)
&::before {
display: block; // IE10
height: subtract(100vh, $modal-dialog-margin * 2);
height: min-content; // Reset height to 0 except on IE
content: "";
}
// Ensure `.modal-body` shows scrollbar (IE10/11)
&.modal-dialog-scrollable {
flex-direction: column;
justify-content: center;
height: 100%;
.modal-content {
max-height: none;
}
&::before {
content: none;
}
}
}
// Actual modal
.modal-content {
position: relative;
display: flex;
flex-direction: column;
width: 100%; // Ensure `.modal-content` extends the full width of the parent `.modal-dialog`
// counteract the pointer-events: none; in the .modal-dialog
color: $modal-content-color;
pointer-events: auto;
background-color: $modal-content-bg;
background-clip: padding-box;
border: $modal-content-border-width solid $modal-content-border-color;
@include border-radius($modal-content-border-radius);
@include box-shadow($modal-content-box-shadow-xs);
// Remove focus outline from opened modal
outline: 0;
}
// Modal background
.modal-backdrop {
position: fixed;
top: 0;
left: 0;
z-index: $zindex-modal-backdrop;
width: 100vw;
height: 100vh;
background-color: $modal-backdrop-bg;
// Fade for backdrop
&.fade { opacity: 0; }
&.show { opacity: $modal-backdrop-opacity; }
}
// Modal header
// Top section of the modal w/ title and dismiss
.modal-header {
display: flex;
align-items: flex-start; // so the close btn always stays on the upper right corner
justify-content: space-between; // Put modal header elements (title and dismiss) on opposite ends
padding: $modal-header-padding;
border-bottom: $modal-header-border-width solid $modal-header-border-color;
@include border-top-radius($modal-content-inner-border-radius);
.close {
padding: $modal-header-padding;
// auto on the left force icon to the right even when there is no .modal-title
margin: (-$modal-header-padding-y) (-$modal-header-padding-x) (-$modal-header-padding-y) auto;
}
}
// Title text within header
.modal-title {
margin-bottom: 0;
line-height: $modal-title-line-height;
}
// Modal body
// Where all modal content resides (sibling of .modal-header and .modal-footer)
.modal-body {
position: relative;
// Enable `flex-grow: 1` so that the body take up as much space as possible
// when there should be a fixed height on `.modal-dialog`.
flex: 1 1 auto;
padding: $modal-inner-padding;
}
// Footer (for actions)
.modal-footer {
display: flex;
flex-wrap: wrap;
align-items: center; // vertically center
justify-content: flex-end; // Right align buttons with flex property because text-align doesn't work on flex items
padding: $modal-inner-padding - $modal-footer-margin-between / 2;
border-top: $modal-footer-border-width solid $modal-footer-border-color;
@include border-bottom-radius($modal-content-inner-border-radius);
// Place margin between footer elements
// This solution is far from ideal because of the universal selector usage,
// but is needed to fix https://github.com/twbs/bootstrap/issues/24800
> * {
margin: $modal-footer-margin-between / 2;
}
}
// Measure scrollbar width for padding body during modal show/hide
.modal-scrollbar-measure {
position: absolute;
top: -9999px;
width: 50px;
height: 50px;
overflow: scroll;
}
// Scale up the modal
@include media-breakpoint-up(sm) {
// Automatically set modal's width for larger viewports
.modal-dialog {
max-width: $modal-md;
margin: $modal-dialog-margin-y-sm-up auto;
}
.modal-dialog-scrollable {
max-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
.modal-content {
max-height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
}
}
.modal-dialog-centered {
min-height: subtract(100%, $modal-dialog-margin-y-sm-up * 2);
&::before {
height: subtract(100vh, $modal-dialog-margin-y-sm-up * 2);
height: min-content;
}
}
.modal-content {
@include box-shadow($modal-content-box-shadow-sm-up);
}
.modal-sm { max-width: $modal-sm; }
}
@include media-breakpoint-up(lg) {
.modal-lg,
.modal-xl {
max-width: $modal-lg;
}
}
@include media-breakpoint-up(xl) {
.modal-xl { max-width: $modal-xl; }
}
+123
View File
@@ -0,0 +1,123 @@
// Base class
//
// Kickstart any navigation component with a set of style resets. Works with
// `<nav>`s, `<ul>`s or `<ol>`s.
.nav {
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.nav-link {
display: block;
padding: $nav-link-padding-y $nav-link-padding-x;
text-decoration: if($link-decoration == none, null, none);
@include hover-focus() {
text-decoration: none;
}
// Disabled state lightens text
&.disabled {
color: $nav-link-disabled-color;
pointer-events: none;
cursor: default;
}
}
//
// Tabs
//
.nav-tabs {
border-bottom: $nav-tabs-border-width solid $nav-tabs-border-color;
.nav-item {
margin-bottom: -$nav-tabs-border-width;
}
.nav-link {
border: $nav-tabs-border-width solid transparent;
@include border-top-radius($nav-tabs-border-radius);
@include hover-focus() {
border-color: $nav-tabs-link-hover-border-color;
}
&.disabled {
color: $nav-link-disabled-color;
background-color: transparent;
border-color: transparent;
}
}
.nav-link.active,
.nav-item.show .nav-link {
color: $nav-tabs-link-active-color;
background-color: $nav-tabs-link-active-bg;
border-color: $nav-tabs-link-active-border-color;
}
.dropdown-menu {
// Make dropdown border overlap tab border
margin-top: -$nav-tabs-border-width;
// Remove the top rounded corners here since there is a hard edge above the menu
@include border-top-radius(0);
}
}
//
// Pills
//
.nav-pills {
.nav-link {
@include border-radius($nav-pills-border-radius);
}
.nav-link.active,
.show > .nav-link {
color: $nav-pills-link-active-color;
background-color: $nav-pills-link-active-bg;
}
}
//
// Justified variants
//
.nav-fill {
> .nav-link,
.nav-item {
flex: 1 1 auto;
text-align: center;
}
}
.nav-justified {
> .nav-link,
.nav-item {
flex-basis: 0;
flex-grow: 1;
text-align: center;
}
}
// Tabbable tabs
//
// Hide tabbable panes to start, show them when `.active`
.tab-content {
> .tab-pane {
display: none;
}
> .active {
display: block;
}
}
+324
View File
@@ -0,0 +1,324 @@
// Contents
//
// Navbar
// Navbar brand
// Navbar nav
// Navbar text
// Navbar divider
// Responsive navbar
// Navbar position
// Navbar themes
// Navbar
//
// Provide a static navbar from which we expand to create full-width, fixed, and
// other navbar variations.
.navbar {
position: relative;
display: flex;
flex-wrap: wrap; // allow us to do the line break for collapsing content
align-items: center;
justify-content: space-between; // space out brand from logo
padding: $navbar-padding-y $navbar-padding-x;
// Because flex properties aren't inherited, we need to redeclare these first
// few properties so that content nested within behave properly.
%container-flex-properties {
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
}
.container,
.container-fluid {
@extend %container-flex-properties;
}
@each $breakpoint, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($breakpoint, $container-max-widths)} {
@extend %container-flex-properties;
}
}
}
// Navbar brand
//
// Used for brand, project, or site names.
.navbar-brand {
display: inline-block;
padding-top: $navbar-brand-padding-y;
padding-bottom: $navbar-brand-padding-y;
margin-right: $navbar-padding-x;
@include font-size($navbar-brand-font-size);
line-height: inherit;
white-space: nowrap;
@include hover-focus() {
text-decoration: none;
}
}
// Navbar nav
//
// Custom navbar navigation (doesn't require `.nav`, but does make use of `.nav-link`).
.navbar-nav {
display: flex;
flex-direction: column; // cannot use `inherit` to get the `.navbar`s value
padding-left: 0;
margin-bottom: 0;
list-style: none;
.nav-link {
padding-right: 0;
padding-left: 0;
}
.dropdown-menu {
position: static;
float: none;
}
}
// Navbar text
//
//
.navbar-text {
display: inline-block;
padding-top: $nav-link-padding-y;
padding-bottom: $nav-link-padding-y;
}
// Responsive navbar
//
// Custom styles for responsive collapsing and toggling of navbar contents.
// Powered by the collapse Bootstrap JavaScript plugin.
// When collapsed, prevent the toggleable navbar contents from appearing in
// the default flexbox row orientation. Requires the use of `flex-wrap: wrap`
// on the `.navbar` parent.
.navbar-collapse {
flex-basis: 100%;
flex-grow: 1;
// For always expanded or extra full navbars, ensure content aligns itself
// properly vertically. Can be easily overridden with flex utilities.
align-items: center;
}
// Button for toggling the navbar when in its collapsed state
.navbar-toggler {
padding: $navbar-toggler-padding-y $navbar-toggler-padding-x;
@include font-size($navbar-toggler-font-size);
line-height: 1;
background-color: transparent; // remove default button style
border: $border-width solid transparent; // remove default button style
@include border-radius($navbar-toggler-border-radius);
@include hover-focus() {
text-decoration: none;
}
}
// Keep as a separate element so folks can easily override it with another icon
// or image file as needed.
.navbar-toggler-icon {
display: inline-block;
width: 1.5em;
height: 1.5em;
vertical-align: middle;
content: "";
background: no-repeat center center;
background-size: 100% 100%;
}
// Generate series of `.navbar-expand-*` responsive classes for configuring
// where your navbar collapses.
.navbar-expand {
@each $breakpoint in map-keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
&#{$infix} {
@include media-breakpoint-down($breakpoint) {
%container-navbar-expand-#{$breakpoint} {
padding-right: 0;
padding-left: 0;
}
> .container,
> .container-fluid {
@extend %container-navbar-expand-#{$breakpoint};
}
@each $size, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($size, $container-max-widths)} {
@extend %container-navbar-expand-#{$breakpoint};
}
}
}
@include media-breakpoint-up($next) {
flex-flow: row nowrap;
justify-content: flex-start;
.navbar-nav {
flex-direction: row;
.dropdown-menu {
position: absolute;
}
.nav-link {
padding-right: $navbar-nav-link-padding-x;
padding-left: $navbar-nav-link-padding-x;
}
}
// For nesting containers, have to redeclare for alignment purposes
%container-nesting-#{$breakpoint} {
flex-wrap: nowrap;
}
> .container,
> .container-fluid {
@extend %container-nesting-#{$breakpoint};
}
@each $size, $container-max-width in $container-max-widths {
> .container#{breakpoint-infix($size, $container-max-widths)} {
@extend %container-nesting-#{$breakpoint};
}
}
.navbar-collapse {
display: flex !important; // stylelint-disable-line declaration-no-important
// Changes flex-bases to auto because of an IE10 bug
flex-basis: auto;
}
.navbar-toggler {
display: none;
}
}
}
}
}
// Navbar themes
//
// Styles for switching between navbars with light or dark background.
// Dark links against a light background
.navbar-light {
.navbar-brand {
color: $navbar-light-brand-color;
@include hover-focus() {
color: $navbar-light-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-light-color;
@include hover-focus() {
color: $navbar-light-hover-color;
}
&.disabled {
color: $navbar-light-disabled-color;
}
}
.show > .nav-link,
.active > .nav-link,
.nav-link.show,
.nav-link.active {
color: $navbar-light-active-color;
}
}
.navbar-toggler {
color: $navbar-light-color;
border-color: $navbar-light-toggler-border-color;
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-light-toggler-icon-bg);
}
.navbar-text {
color: $navbar-light-color;
a {
color: $navbar-light-active-color;
@include hover-focus() {
color: $navbar-light-active-color;
}
}
}
}
// White links against a dark background
.navbar-dark {
.navbar-brand {
color: $navbar-dark-brand-color;
@include hover-focus() {
color: $navbar-dark-brand-hover-color;
}
}
.navbar-nav {
.nav-link {
color: $navbar-dark-color;
@include hover-focus() {
color: $navbar-dark-hover-color;
}
&.disabled {
color: $navbar-dark-disabled-color;
}
}
.show > .nav-link,
.active > .nav-link,
.nav-link.show,
.nav-link.active {
color: $navbar-dark-active-color;
}
}
.navbar-toggler {
color: $navbar-dark-color;
border-color: $navbar-dark-toggler-border-color;
}
.navbar-toggler-icon {
background-image: escape-svg($navbar-dark-toggler-icon-bg);
}
.navbar-text {
color: $navbar-dark-color;
a {
color: $navbar-dark-active-color;
@include hover-focus() {
color: $navbar-dark-active-color;
}
}
}
}
@@ -0,0 +1,74 @@
.pagination {
display: flex;
@include list-unstyled();
@include border-radius();
}
.page-link {
position: relative;
display: block;
padding: $pagination-padding-y $pagination-padding-x;
margin-left: -$pagination-border-width;
line-height: $pagination-line-height;
color: $pagination-color;
text-decoration: if($link-decoration == none, null, none);
background-color: $pagination-bg;
border: $pagination-border-width solid $pagination-border-color;
&:hover {
z-index: 2;
color: $pagination-hover-color;
text-decoration: none;
background-color: $pagination-hover-bg;
border-color: $pagination-hover-border-color;
}
&:focus {
z-index: 3;
outline: $pagination-focus-outline;
box-shadow: $pagination-focus-box-shadow;
}
}
.page-item {
&:first-child {
.page-link {
margin-left: 0;
@include border-left-radius($border-radius);
}
}
&:last-child {
.page-link {
@include border-right-radius($border-radius);
}
}
&.active .page-link {
z-index: 3;
color: $pagination-active-color;
background-color: $pagination-active-bg;
border-color: $pagination-active-border-color;
}
&.disabled .page-link {
color: $pagination-disabled-color;
pointer-events: none;
// Opinionated: remove the "hand" cursor set previously for .page-link
cursor: auto;
background-color: $pagination-disabled-bg;
border-color: $pagination-disabled-border-color;
}
}
//
// Sizing
//
.pagination-lg {
@include pagination-size($pagination-padding-y-lg, $pagination-padding-x-lg, $font-size-lg, $line-height-lg, $border-radius-lg);
}
.pagination-sm {
@include pagination-size($pagination-padding-y-sm, $pagination-padding-x-sm, $font-size-sm, $line-height-sm, $border-radius-sm);
}
+170
View File
@@ -0,0 +1,170 @@
.popover {
position: absolute;
top: 0;
left: 0;
z-index: $zindex-popover;
display: block;
max-width: $popover-max-width;
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size($popover-font-size);
// Allow breaking very long words so they don't overflow the popover's bounds
word-wrap: break-word;
background-color: $popover-bg;
background-clip: padding-box;
border: $popover-border-width solid $popover-border-color;
@include border-radius($popover-border-radius);
@include box-shadow($popover-box-shadow);
.arrow {
position: absolute;
display: block;
width: $popover-arrow-width;
height: $popover-arrow-height;
margin: 0 $popover-border-radius;
&::before,
&::after {
position: absolute;
display: block;
content: "";
border-color: transparent;
border-style: solid;
}
}
}
.bs-popover-top {
margin-bottom: $popover-arrow-height;
> .arrow {
bottom: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
bottom: 0;
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
border-top-color: $popover-arrow-outer-color;
}
&::after {
bottom: $popover-border-width;
border-width: $popover-arrow-height ($popover-arrow-width / 2) 0;
border-top-color: $popover-arrow-color;
}
}
}
.bs-popover-right {
margin-left: $popover-arrow-height;
> .arrow {
left: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
left: 0;
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
border-right-color: $popover-arrow-outer-color;
}
&::after {
left: $popover-border-width;
border-width: ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2) 0;
border-right-color: $popover-arrow-color;
}
}
}
.bs-popover-bottom {
margin-top: $popover-arrow-height;
> .arrow {
top: subtract(-$popover-arrow-height, $popover-border-width);
&::before {
top: 0;
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
border-bottom-color: $popover-arrow-outer-color;
}
&::after {
top: $popover-border-width;
border-width: 0 ($popover-arrow-width / 2) $popover-arrow-height ($popover-arrow-width / 2);
border-bottom-color: $popover-arrow-color;
}
}
// This will remove the popover-header's border just below the arrow
.popover-header::before {
position: absolute;
top: 0;
left: 50%;
display: block;
width: $popover-arrow-width;
margin-left: -$popover-arrow-width / 2;
content: "";
border-bottom: $popover-border-width solid $popover-header-bg;
}
}
.bs-popover-left {
margin-right: $popover-arrow-height;
> .arrow {
right: subtract(-$popover-arrow-height, $popover-border-width);
width: $popover-arrow-height;
height: $popover-arrow-width;
margin: $popover-border-radius 0; // make sure the arrow does not touch the popover's rounded corners
&::before {
right: 0;
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
border-left-color: $popover-arrow-outer-color;
}
&::after {
right: $popover-border-width;
border-width: ($popover-arrow-width / 2) 0 ($popover-arrow-width / 2) $popover-arrow-height;
border-left-color: $popover-arrow-color;
}
}
}
.bs-popover-auto {
&[x-placement^="top"] {
@extend .bs-popover-top;
}
&[x-placement^="right"] {
@extend .bs-popover-right;
}
&[x-placement^="bottom"] {
@extend .bs-popover-bottom;
}
&[x-placement^="left"] {
@extend .bs-popover-left;
}
}
// Offset the popover to account for the popover arrow
.popover-header {
padding: $popover-header-padding-y $popover-header-padding-x;
margin-bottom: 0; // Reset the default from Reboot
@include font-size($font-size-base);
color: $popover-header-color;
background-color: $popover-header-bg;
border-bottom: $popover-border-width solid darken($popover-header-bg, 5%);
@include border-top-radius($popover-inner-border-radius);
&:empty {
display: none;
}
}
.popover-body {
padding: $popover-body-padding-y $popover-body-padding-x;
color: $popover-body-color;
}
+141
View File
@@ -0,0 +1,141 @@
// stylelint-disable declaration-no-important, selector-no-qualifying-type
// Source: https://github.com/h5bp/main.css/blob/master/src/_print.css
// ==========================================================================
// Print styles.
// Inlined to avoid the additional HTTP request:
// https://www.phpied.com/delay-loading-your-print-css/
// ==========================================================================
@if $enable-print-styles {
@media print {
*,
*::before,
*::after {
// Bootstrap specific; comment out `color` and `background`
//color: $black !important; // Black prints faster
text-shadow: none !important;
//background: transparent !important;
box-shadow: none !important;
}
a {
&:not(.btn) {
text-decoration: underline;
}
}
// Bootstrap specific; comment the following selector out
//a[href]::after {
// content: " (" attr(href) ")";
//}
abbr[title]::after {
content: " (" attr(title) ")";
}
// Bootstrap specific; comment the following selector out
//
// Don't show links that are fragment identifiers,
// or use the `javascript:` pseudo protocol
//
//a[href^="#"]::after,
//a[href^="javascript:"]::after {
// content: "";
//}
pre {
white-space: pre-wrap !important;
}
pre,
blockquote {
border: $border-width solid $gray-500; // Bootstrap custom code; using `$border-width` instead of 1px
page-break-inside: avoid;
}
//
// Printing Tables:
// https://web.archive.org/web/20180815150934/http://css-discuss.incutio.com/wiki/Printing_Tables
//
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
// Bootstrap specific changes start
// Specify a size and min-width to make printing closer across browsers.
// We don't set margin here because it breaks `size` in Chrome. We also
// don't use `!important` on `size` as it breaks in Chrome.
@page {
size: $print-page-size;
}
body {
min-width: $print-body-min-width !important;
}
.container {
min-width: $print-body-min-width !important;
}
// Bootstrap components
.navbar {
display: none;
}
.badge {
border: $border-width solid $black;
}
.table {
border-collapse: collapse !important;
td,
th {
background-color: $white !important;
}
}
.table-bordered {
th,
td {
border: 1px solid $gray-300 !important;
}
}
.table-dark {
color: inherit;
th,
td,
thead th,
tbody + tbody {
border-color: $table-border-color;
}
}
.table .thead-dark th {
color: inherit;
border-color: $table-border-color;
}
// Bootstrap specific changes end
}
}
+47
View File
@@ -0,0 +1,47 @@
// Disable animation if transitions are disabled
@if $enable-transitions {
@keyframes progress-bar-stripes {
from { background-position: $progress-height 0; }
to { background-position: 0 0; }
}
}
.progress {
display: flex;
height: $progress-height;
overflow: hidden; // force rounded corners by cropping it
line-height: 0;
@include font-size($progress-font-size);
background-color: $progress-bg;
@include border-radius($progress-border-radius);
@include box-shadow($progress-box-shadow);
}
.progress-bar {
display: flex;
flex-direction: column;
justify-content: center;
overflow: hidden;
color: $progress-bar-color;
text-align: center;
white-space: nowrap;
background-color: $progress-bar-bg;
@include transition($progress-bar-transition);
}
.progress-bar-striped {
@include gradient-striped();
background-size: $progress-height $progress-height;
}
@if $enable-transitions {
.progress-bar-animated {
animation: progress-bar-stripes $progress-bar-animation-timing;
@if $enable-prefers-reduced-motion-media-query {
@media (prefers-reduced-motion: reduce) {
animation: none;
}
}
}
}
+480
View File
@@ -0,0 +1,480 @@
// stylelint-disable at-rule-no-vendor-prefix, declaration-no-important, selector-no-qualifying-type, property-no-vendor-prefix
// Reboot
//
// Normalization of HTML elements, manually forked from Normalize.css to remove
// styles targeting irrelevant browsers while applying new styles.
//
// Normalize is licensed MIT. https://github.com/necolas/normalize.css
// Document
//
// 1. Change from `box-sizing: content-box` so that `width` is not affected by `padding` or `border`.
// 2. Change the default font family in all browsers.
// 3. Correct the line height in all browsers.
// 4. Prevent adjustments of font size after orientation changes in IE on Windows Phone and in iOS.
// 5. Change the default tap highlight to be completely transparent in iOS.
*,
*::before,
*::after {
box-sizing: border-box; // 1
}
html {
font-family: sans-serif; // 2
line-height: 1.15; // 3
-webkit-text-size-adjust: 100%; // 4
-webkit-tap-highlight-color: rgba($black, 0); // 5
}
// Shim for "new" HTML5 structural elements to display correctly (IE10, older browsers)
// TODO: remove in v5
// stylelint-disable-next-line selector-list-comma-newline-after
article, aside, figcaption, figure, footer, header, hgroup, main, nav, section {
display: block;
}
// Body
//
// 1. Remove the margin in all browsers.
// 2. As a best practice, apply a default `background-color`.
// 3. Set an explicit initial text-align value so that we can later use
// the `inherit` value on things like `<th>` elements.
body {
margin: 0; // 1
font-family: $font-family-base;
@include font-size($font-size-base);
font-weight: $font-weight-base;
line-height: $line-height-base;
color: $body-color;
text-align: left; // 3
background-color: $body-bg; // 2
}
// Future-proof rule: in browsers that support :focus-visible, suppress the focus outline
// on elements that programmatically receive focus but wouldn't normally show a visible
// focus outline. In general, this would mean that the outline is only applied if the
// interaction that led to the element receiving programmatic focus was a keyboard interaction,
// or the browser has somehow determined that the user is primarily a keyboard user and/or
// wants focus outlines to always be presented.
//
// See https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible
// and https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/
[tabindex="-1"]:focus:not(:focus-visible) {
outline: 0 !important;
}
// Content grouping
//
// 1. Add the correct box sizing in Firefox.
// 2. Show the overflow in Edge and IE.
hr {
box-sizing: content-box; // 1
height: 0; // 1
overflow: visible; // 2
}
//
// Typography
//
// Remove top margins from headings
//
// By default, `<h1>`-`<h6>` all receive top and bottom margins. We nuke the top
// margin for easier control within type scales as it avoids margin collapsing.
// stylelint-disable-next-line selector-list-comma-newline-after
h1, h2, h3, h4, h5, h6 {
margin-top: 0;
margin-bottom: $headings-margin-bottom;
}
// Reset margins on paragraphs
//
// Similarly, the top margin on `<p>`s get reset. However, we also reset the
// bottom margin to use `rem` units instead of `em`.
p {
margin-top: 0;
margin-bottom: $paragraph-margin-bottom;
}
// Abbreviations
//
// 1. Duplicate behavior to the data-* attribute for our tooltip plugin
// 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
// 3. Add explicit cursor to indicate changed behavior.
// 4. Remove the bottom border in Firefox 39-.
// 5. Prevent the text-decoration to be skipped.
abbr[title],
abbr[data-original-title] { // 1
text-decoration: underline; // 2
text-decoration: underline dotted; // 2
cursor: help; // 3
border-bottom: 0; // 4
text-decoration-skip-ink: none; // 5
}
address {
margin-bottom: 1rem;
font-style: normal;
line-height: inherit;
}
ol,
ul,
dl {
margin-top: 0;
margin-bottom: 1rem;
}
ol ol,
ul ul,
ol ul,
ul ol {
margin-bottom: 0;
}
dt {
font-weight: $dt-font-weight;
}
dd {
margin-bottom: .5rem;
margin-left: 0; // Undo browser default
}
blockquote {
margin: 0 0 1rem;
}
b,
strong {
font-weight: $font-weight-bolder; // Add the correct font weight in Chrome, Edge, and Safari
}
small {
@include font-size(80%); // Add the correct font size in all browsers
}
//
// Prevent `sub` and `sup` elements from affecting the line height in
// all browsers.
//
sub,
sup {
position: relative;
@include font-size(75%);
line-height: 0;
vertical-align: baseline;
}
sub { bottom: -.25em; }
sup { top: -.5em; }
//
// Links
//
a {
color: $link-color;
text-decoration: $link-decoration;
background-color: transparent; // Remove the gray background on active links in IE 10.
@include hover() {
color: $link-hover-color;
text-decoration: $link-hover-decoration;
}
}
// And undo these styles for placeholder links/named anchors (without href).
// It would be more straightforward to just use a[href] in previous block, but that
// causes specificity issues in many other styles that are too complex to fix.
// See https://github.com/twbs/bootstrap/issues/19402
a:not([href]):not([class]) {
color: inherit;
text-decoration: none;
@include hover() {
color: inherit;
text-decoration: none;
}
}
//
// Code
//
pre,
code,
kbd,
samp {
font-family: $font-family-monospace;
@include font-size(1em); // Correct the odd `em` font sizing in all browsers.
}
pre {
// Remove browser default top margin
margin-top: 0;
// Reset browser default of `1em` to use `rem`s
margin-bottom: 1rem;
// Don't allow content to break outside
overflow: auto;
// Disable auto-hiding scrollbar in IE & legacy Edge to avoid overlap,
// making it impossible to interact with the content
-ms-overflow-style: scrollbar;
}
//
// Figures
//
figure {
// Apply a consistent margin strategy (matches our type styles).
margin: 0 0 1rem;
}
//
// Images and content
//
img {
vertical-align: middle;
border-style: none; // Remove the border on images inside links in IE 10-.
}
svg {
// Workaround for the SVG overflow bug in IE10/11 is still required.
// See https://github.com/twbs/bootstrap/issues/26878
overflow: hidden;
vertical-align: middle;
}
//
// Tables
//
table {
border-collapse: collapse; // Prevent double borders
}
caption {
padding-top: $table-cell-padding;
padding-bottom: $table-cell-padding;
color: $table-caption-color;
text-align: left;
caption-side: bottom;
}
th {
// Matches default `<td>` alignment by inheriting from the `<body>`, or the
// closest parent with a set `text-align`.
text-align: inherit;
}
//
// Forms
//
label {
// Allow labels to use `margin` for spacing.
display: inline-block;
margin-bottom: $label-margin-bottom;
}
// Remove the default `border-radius` that macOS Chrome adds.
//
// Details at https://github.com/twbs/bootstrap/issues/24093
button {
// stylelint-disable-next-line property-blacklist
border-radius: 0;
}
// Work around a Firefox/IE bug where the transparent `button` background
// results in a loss of the default `button` focus styles.
//
// Credit: https://github.com/suitcss/base/
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
input,
button,
select,
optgroup,
textarea {
margin: 0; // Remove the margin in Firefox and Safari
font-family: inherit;
@include font-size(inherit);
line-height: inherit;
}
button,
input {
overflow: visible; // Show the overflow in Edge
}
button,
select {
text-transform: none; // Remove the inheritance of text transform in Firefox
}
// Set the cursor for non-`<button>` buttons
//
// Details at https://github.com/twbs/bootstrap/pull/30562
[role="button"] {
cursor: pointer;
}
// Remove the inheritance of word-wrap in Safari.
//
// Details at https://github.com/twbs/bootstrap/issues/24990
select {
word-wrap: normal;
}
// 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
// controls in Android 4.
// 2. Correct the inability to style clickable types in iOS and Safari.
button,
[type="button"], // 1
[type="reset"],
[type="submit"] {
-webkit-appearance: button; // 2
}
// Opinionated: add "hand" cursor to non-disabled button elements.
@if $enable-pointer-cursor-for-buttons {
button,
[type="button"],
[type="reset"],
[type="submit"] {
&:not(:disabled) {
cursor: pointer;
}
}
}
// Remove inner border and padding from Firefox, but don't restore the outline like Normalize.
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
padding: 0;
border-style: none;
}
input[type="radio"],
input[type="checkbox"] {
box-sizing: border-box; // 1. Add the correct box sizing in IE 10-
padding: 0; // 2. Remove the padding in IE 10-
}
textarea {
overflow: auto; // Remove the default vertical scrollbar in IE.
// Textareas should really only resize vertically so they don't break their (horizontal) containers.
resize: vertical;
}
fieldset {
// Browsers set a default `min-width: min-content;` on fieldsets,
// unlike e.g. `<div>`s, which have `min-width: 0;` by default.
// So we reset that to ensure fieldsets behave more like a standard block element.
// See https://github.com/twbs/bootstrap/issues/12359
// and https://html.spec.whatwg.org/multipage/#the-fieldset-and-legend-elements
min-width: 0;
// Reset the default outline behavior of fieldsets so they don't affect page layout.
padding: 0;
margin: 0;
border: 0;
}
// 1. Correct the text wrapping in Edge and IE.
// 2. Correct the color inheritance from `fieldset` elements in IE.
legend {
display: block;
width: 100%;
max-width: 100%; // 1
padding: 0;
margin-bottom: .5rem;
@include font-size(1.5rem);
line-height: inherit;
color: inherit; // 2
white-space: normal; // 1
}
progress {
vertical-align: baseline; // Add the correct vertical alignment in Chrome, Firefox, and Opera.
}
// Correct the cursor style of increment and decrement buttons in Chrome.
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
// This overrides the extra rounded corners on search inputs in iOS so that our
// `.form-control` class can properly style them. Note that this cannot simply
// be added to `.form-control` as it's not specific enough. For details, see
// https://github.com/twbs/bootstrap/issues/11586.
outline-offset: -2px; // 2. Correct the outline style in Safari.
-webkit-appearance: none;
}
//
// Remove the inner padding in Chrome and Safari on macOS.
//
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
//
// 1. Correct the inability to style clickable types in iOS and Safari.
// 2. Change font properties to `inherit` in Safari.
//
::-webkit-file-upload-button {
font: inherit; // 2
-webkit-appearance: button; // 1
}
//
// Correct element displays
//
output {
display: inline-block;
}
summary {
display: list-item; // Add the correct display in all browsers
cursor: pointer;
}
template {
display: none; // Add the correct display in IE
}
// Always hide an element with the `hidden` HTML attribute (from PureCSS).
// Needed for proper display in IE 10-.
[hidden] {
display: none !important;
}
+20
View File
@@ -0,0 +1,20 @@
// Do not forget to update getting-started/theming.md!
:root {
// Custom variable values only support SassScript inside `#{}`.
@each $color, $value in $colors {
--#{$color}: #{$value};
}
@each $color, $value in $theme-colors {
--#{$color}: #{$value};
}
@each $bp, $value in $grid-breakpoints {
--breakpoint-#{$bp}: #{$value};
}
// Use `inspect` for lists so that quoted items keep the quotes.
// See https://github.com/sass/sass/issues/2383#issuecomment-336349172
--font-family-sans-serif: #{inspect($font-family-sans-serif)};
--font-family-monospace: #{inspect($font-family-monospace)};
}
+56
View File
@@ -0,0 +1,56 @@
//
// Rotating border
//
@keyframes spinner-border {
to { transform: rotate(360deg); }
}
.spinner-border {
display: inline-block;
width: $spinner-width;
height: $spinner-height;
vertical-align: text-bottom;
border: $spinner-border-width solid currentColor;
border-right-color: transparent;
// stylelint-disable-next-line property-blacklist
border-radius: 50%;
animation: spinner-border .75s linear infinite;
}
.spinner-border-sm {
width: $spinner-width-sm;
height: $spinner-height-sm;
border-width: $spinner-border-width-sm;
}
//
// Growing circle
//
@keyframes spinner-grow {
0% {
transform: scale(0);
}
50% {
opacity: 1;
transform: none;
}
}
.spinner-grow {
display: inline-block;
width: $spinner-width;
height: $spinner-height;
vertical-align: text-bottom;
background-color: currentColor;
// stylelint-disable-next-line property-blacklist
border-radius: 50%;
opacity: 0;
animation: spinner-grow .75s linear infinite;
}
.spinner-grow-sm {
width: $spinner-width-sm;
height: $spinner-height-sm;
}
+185
View File
@@ -0,0 +1,185 @@
//
// Basic Bootstrap table
//
.table {
width: 100%;
margin-bottom: $spacer;
color: $table-color;
background-color: $table-bg; // Reset for nesting within parents with `background-color`.
th,
td {
padding: $table-cell-padding;
vertical-align: top;
border-top: $table-border-width solid $table-border-color;
}
thead th {
vertical-align: bottom;
border-bottom: (2 * $table-border-width) solid $table-border-color;
}
tbody + tbody {
border-top: (2 * $table-border-width) solid $table-border-color;
}
}
//
// Condensed table w/ half padding
//
.table-sm {
th,
td {
padding: $table-cell-padding-sm;
}
}
// Border versions
//
// Add or remove borders all around the table and between all the columns.
.table-bordered {
border: $table-border-width solid $table-border-color;
th,
td {
border: $table-border-width solid $table-border-color;
}
thead {
th,
td {
border-bottom-width: 2 * $table-border-width;
}
}
}
.table-borderless {
th,
td,
thead th,
tbody + tbody {
border: 0;
}
}
// Zebra-striping
//
// Default zebra-stripe styles (alternating gray and transparent backgrounds)
.table-striped {
tbody tr:nth-of-type(#{$table-striped-order}) {
background-color: $table-accent-bg;
}
}
// Hover effect
//
// Placed here since it has to come after the potential zebra striping
.table-hover {
tbody tr {
@include hover() {
color: $table-hover-color;
background-color: $table-hover-bg;
}
}
}
// Table backgrounds
//
// Exact selectors below required to override `.table-striped` and prevent
// inheritance to nested tables.
@each $color, $value in $theme-colors {
@include table-row-variant($color, theme-color-level($color, $table-bg-level), theme-color-level($color, $table-border-level));
}
@include table-row-variant(active, $table-active-bg);
// Dark styles
//
// Same table markup, but inverted color scheme: dark background and light text.
// stylelint-disable-next-line no-duplicate-selectors
.table {
.thead-dark {
th {
color: $table-dark-color;
background-color: $table-dark-bg;
border-color: $table-dark-border-color;
}
}
.thead-light {
th {
color: $table-head-color;
background-color: $table-head-bg;
border-color: $table-border-color;
}
}
}
.table-dark {
color: $table-dark-color;
background-color: $table-dark-bg;
th,
td,
thead th {
border-color: $table-dark-border-color;
}
&.table-bordered {
border: 0;
}
&.table-striped {
tbody tr:nth-of-type(#{$table-striped-order}) {
background-color: $table-dark-accent-bg;
}
}
&.table-hover {
tbody tr {
@include hover() {
color: $table-dark-hover-color;
background-color: $table-dark-hover-bg;
}
}
}
}
// Responsive tables
//
// Generate series of `.table-responsive-*` classes for configuring the screen
// size of where your table will overflow.
.table-responsive {
@each $breakpoint in map-keys($grid-breakpoints) {
$next: breakpoint-next($breakpoint, $grid-breakpoints);
$infix: breakpoint-infix($next, $grid-breakpoints);
&#{$infix} {
@include media-breakpoint-down($breakpoint) {
display: block;
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
// Prevent double border on horizontal scroll due to use of `display: block;`
> .table-bordered {
border: 0;
}
}
}
}
}
+46
View File
@@ -0,0 +1,46 @@
.toast {
// Prevents from shrinking in IE11, when in a flex container
// See https://github.com/twbs/bootstrap/issues/28341
flex-basis: $toast-max-width;
max-width: $toast-max-width;
@include font-size($toast-font-size);
color: $toast-color;
background-color: $toast-background-color;
background-clip: padding-box;
border: $toast-border-width solid $toast-border-color;
box-shadow: $toast-box-shadow;
opacity: 0;
@include border-radius($toast-border-radius);
&:not(:last-child) {
margin-bottom: $toast-padding-x;
}
&.showing {
opacity: 1;
}
&.show {
display: block;
opacity: 1;
}
&.hide {
display: none;
}
}
.toast-header {
display: flex;
align-items: center;
padding: $toast-padding-y $toast-padding-x;
color: $toast-header-color;
background-color: $toast-header-background-color;
background-clip: padding-box;
border-bottom: $toast-border-width solid $toast-header-border-color;
@include border-top-radius(subtract($toast-border-radius, $toast-border-width));
}
.toast-body {
padding: $toast-padding-x; // apply to both vertical and horizontal
}
+115
View File
@@ -0,0 +1,115 @@
// Base class
.tooltip {
position: absolute;
z-index: $zindex-tooltip;
display: block;
margin: $tooltip-margin;
// Our parent element can be arbitrary since tooltips are by default inserted as a sibling of their target element.
// So reset our font and text properties to avoid inheriting weird values.
@include reset-text();
@include font-size($tooltip-font-size);
// Allow breaking very long words so they don't overflow the tooltip's bounds
word-wrap: break-word;
opacity: 0;
&.show { opacity: $tooltip-opacity; }
.arrow {
position: absolute;
display: block;
width: $tooltip-arrow-width;
height: $tooltip-arrow-height;
&::before {
position: absolute;
content: "";
border-color: transparent;
border-style: solid;
}
}
}
.bs-tooltip-top {
padding: $tooltip-arrow-height 0;
.arrow {
bottom: 0;
&::before {
top: 0;
border-width: $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
border-top-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-right {
padding: 0 $tooltip-arrow-height;
.arrow {
left: 0;
width: $tooltip-arrow-height;
height: $tooltip-arrow-width;
&::before {
right: 0;
border-width: ($tooltip-arrow-width / 2) $tooltip-arrow-height ($tooltip-arrow-width / 2) 0;
border-right-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-bottom {
padding: $tooltip-arrow-height 0;
.arrow {
top: 0;
&::before {
bottom: 0;
border-width: 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
border-bottom-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-left {
padding: 0 $tooltip-arrow-height;
.arrow {
right: 0;
width: $tooltip-arrow-height;
height: $tooltip-arrow-width;
&::before {
left: 0;
border-width: ($tooltip-arrow-width / 2) 0 ($tooltip-arrow-width / 2) $tooltip-arrow-height;
border-left-color: $tooltip-arrow-color;
}
}
}
.bs-tooltip-auto {
&[x-placement^="top"] {
@extend .bs-tooltip-top;
}
&[x-placement^="right"] {
@extend .bs-tooltip-right;
}
&[x-placement^="bottom"] {
@extend .bs-tooltip-bottom;
}
&[x-placement^="left"] {
@extend .bs-tooltip-left;
}
}
// Wrapper for the tooltip content
.tooltip-inner {
max-width: $tooltip-max-width;
padding: $tooltip-padding-y $tooltip-padding-x;
color: $tooltip-color;
text-align: center;
background-color: $tooltip-bg;
@include border-radius($tooltip-border-radius);
}
@@ -0,0 +1,20 @@
.fade {
@include transition($transition-fade);
&:not(.show) {
opacity: 0;
}
}
.collapse {
&:not(.show) {
display: none;
}
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
@include transition($transition-collapse);
}
+125
View File
@@ -0,0 +1,125 @@
// stylelint-disable declaration-no-important, selector-list-comma-newline-after
//
// Headings
//
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
margin-bottom: $headings-margin-bottom;
font-family: $headings-font-family;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
color: $headings-color;
}
h1, .h1 { @include font-size($h1-font-size); }
h2, .h2 { @include font-size($h2-font-size); }
h3, .h3 { @include font-size($h3-font-size); }
h4, .h4 { @include font-size($h4-font-size); }
h5, .h5 { @include font-size($h5-font-size); }
h6, .h6 { @include font-size($h6-font-size); }
.lead {
@include font-size($lead-font-size);
font-weight: $lead-font-weight;
}
// Type display classes
.display-1 {
@include font-size($display1-size);
font-weight: $display1-weight;
line-height: $display-line-height;
}
.display-2 {
@include font-size($display2-size);
font-weight: $display2-weight;
line-height: $display-line-height;
}
.display-3 {
@include font-size($display3-size);
font-weight: $display3-weight;
line-height: $display-line-height;
}
.display-4 {
@include font-size($display4-size);
font-weight: $display4-weight;
line-height: $display-line-height;
}
//
// Horizontal rules
//
hr {
margin-top: $hr-margin-y;
margin-bottom: $hr-margin-y;
border: 0;
border-top: $hr-border-width solid $hr-border-color;
}
//
// Emphasis
//
small,
.small {
@include font-size($small-font-size);
font-weight: $font-weight-normal;
}
mark,
.mark {
padding: $mark-padding;
background-color: $mark-bg;
}
//
// Lists
//
.list-unstyled {
@include list-unstyled();
}
// Inline turns list items into inline-block
.list-inline {
@include list-unstyled();
}
.list-inline-item {
display: inline-block;
&:not(:last-child) {
margin-right: $list-inline-padding;
}
}
//
// Misc
//
// Builds on `abbr`
.initialism {
@include font-size(90%);
text-transform: uppercase;
}
// Blockquotes
.blockquote {
margin-bottom: $spacer;
@include font-size($blockquote-font-size);
}
.blockquote-footer {
display: block;
@include font-size($blockquote-small-font-size);
color: $blockquote-small-color;
&::before {
content: "\2014\00A0"; // em dash, nbsp
}
}
@@ -0,0 +1,18 @@
@import "utilities/align";
@import "utilities/background";
@import "utilities/borders";
@import "utilities/clearfix";
@import "utilities/display";
@import "utilities/embed";
@import "utilities/flex";
@import "utilities/float";
@import "utilities/interactions";
@import "utilities/overflow";
@import "utilities/position";
@import "utilities/screenreaders";
@import "utilities/shadows";
@import "utilities/sizing";
@import "utilities/spacing";
@import "utilities/stretched-link";
@import "utilities/text";
@import "utilities/visibility";
File diff suppressed because it is too large Load Diff
+29
View File
@@ -0,0 +1,29 @@
/*!
* Bootstrap Grid v4.5.2 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
html {
box-sizing: border-box;
-ms-overflow-style: scrollbar;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
@import "functions";
@import "variables";
@import "mixins/breakpoints";
@import "mixins/grid-framework";
@import "mixins/grid";
@import "grid";
@import "utilities/display";
@import "utilities/flex";
@import "utilities/spacing";
+12
View File
@@ -0,0 +1,12 @@
/*!
* Bootstrap Reboot v4.5.2 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
* Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md)
*/
@import "functions";
@import "variables";
@import "mixins";
@import "reboot";
+44
View File
@@ -0,0 +1,44 @@
/*!
* Bootstrap v4.5.2 (https://getbootstrap.com/)
* Copyright 2011-2020 The Bootstrap Authors
* Copyright 2011-2020 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
*/
@import "functions";
@import "variables";
@import "mixins";
@import "root";
@import "reboot";
@import "type";
@import "images";
@import "code";
@import "grid";
@import "tables";
@import "forms";
@import "buttons";
@import "transitions";
@import "dropdown";
@import "button-group";
@import "input-group";
@import "custom-forms";
@import "nav";
@import "navbar";
@import "card";
@import "breadcrumb";
@import "pagination";
@import "badge";
@import "jumbotron";
@import "alert";
@import "progress";
@import "media";
@import "list-group";
@import "close";
@import "toasts";
@import "modal";
@import "tooltip";
@import "popover";
@import "carousel";
@import "spinners";
@import "utilities";
@import "print";
@@ -0,0 +1,13 @@
@mixin alert-variant($background, $border, $color) {
color: $color;
@include gradient-bg($background);
border-color: $border;
hr {
border-top-color: darken($border, 5%);
}
.alert-link {
color: darken($color, 10%);
}
}
@@ -0,0 +1,23 @@
// stylelint-disable declaration-no-important
// Contextual backgrounds
@mixin bg-variant($parent, $color, $ignore-warning: false) {
#{$parent} {
background-color: $color !important;
}
a#{$parent},
button#{$parent} {
@include hover-focus() {
background-color: darken($color, 10%) !important;
}
}
@include deprecate("The `bg-variant` mixin", "v4.4.0", "v5", $ignore-warning);
}
@mixin bg-gradient-variant($parent, $color, $ignore-warning: false) {
#{$parent} {
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important;
}
@include deprecate("The `bg-gradient-variant` mixin", "v4.5.0", "v5", $ignore-warning);
}
@@ -0,0 +1,17 @@
@mixin badge-variant($bg) {
color: color-yiq($bg);
background-color: $bg;
@at-root a#{&} {
@include hover-focus() {
color: color-yiq($bg);
background-color: darken($bg, 10%);
}
&:focus,
&.focus {
outline: 0;
box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5);
}
}
}
@@ -0,0 +1,76 @@
// stylelint-disable property-blacklist
// Single side border-radius
// Helper function to replace negative values with 0
@function valid-radius($radius) {
$return: ();
@each $value in $radius {
@if type-of($value) == number {
$return: append($return, max($value, 0));
} @else {
$return: append($return, $value);
}
}
@return $return;
}
@mixin border-radius($radius: $border-radius, $fallback-border-radius: false) {
@if $enable-rounded {
border-radius: valid-radius($radius);
}
@else if $fallback-border-radius != false {
border-radius: $fallback-border-radius;
}
}
@mixin border-top-radius($radius) {
@if $enable-rounded {
border-top-left-radius: valid-radius($radius);
border-top-right-radius: valid-radius($radius);
}
}
@mixin border-right-radius($radius) {
@if $enable-rounded {
border-top-right-radius: valid-radius($radius);
border-bottom-right-radius: valid-radius($radius);
}
}
@mixin border-bottom-radius($radius) {
@if $enable-rounded {
border-bottom-right-radius: valid-radius($radius);
border-bottom-left-radius: valid-radius($radius);
}
}
@mixin border-left-radius($radius) {
@if $enable-rounded {
border-top-left-radius: valid-radius($radius);
border-bottom-left-radius: valid-radius($radius);
}
}
@mixin border-top-left-radius($radius) {
@if $enable-rounded {
border-top-left-radius: valid-radius($radius);
}
}
@mixin border-top-right-radius($radius) {
@if $enable-rounded {
border-top-right-radius: valid-radius($radius);
}
}
@mixin border-bottom-right-radius($radius) {
@if $enable-rounded {
border-bottom-right-radius: valid-radius($radius);
}
}
@mixin border-bottom-left-radius($radius) {
@if $enable-rounded {
border-bottom-left-radius: valid-radius($radius);
}
}
@@ -0,0 +1,20 @@
@mixin box-shadow($shadow...) {
@if $enable-shadows {
$result: ();
@if (length($shadow) == 1) {
// We can pass `@include box-shadow(none);`
$result: $shadow;
} @else {
// Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;`
@for $i from 1 through length($shadow) {
@if nth($shadow, $i) != "none" {
$result: append($result, nth($shadow, $i), "comma");
}
}
}
@if (length($result) > 0) {
box-shadow: $result;
}
}
}
@@ -0,0 +1,123 @@
// Breakpoint viewport sizes and media queries.
//
// Breakpoints are defined as a map of (name: minimum width), order from small to large:
//
// (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px)
//
// The map defined in the `$grid-breakpoints` global variable is used as the `$breakpoints` argument by default.
// Name of the next breakpoint, or null for the last breakpoint.
//
// >> breakpoint-next(sm)
// md
// >> breakpoint-next(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// md
// >> breakpoint-next(sm, $breakpoint-names: (xs sm md lg xl))
// md
@function breakpoint-next($name, $breakpoints: $grid-breakpoints, $breakpoint-names: map-keys($breakpoints)) {
$n: index($breakpoint-names, $name);
@return if($n != null and $n < length($breakpoint-names), nth($breakpoint-names, $n + 1), null);
}
// Minimum breakpoint width. Null for the smallest (first) breakpoint.
//
// >> breakpoint-min(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 576px
@function breakpoint-min($name, $breakpoints: $grid-breakpoints) {
$min: map-get($breakpoints, $name);
@return if($min != 0, $min, null);
}
// Maximum breakpoint width. Null for the largest (last) breakpoint.
// The maximum value is calculated as the minimum of the next one less 0.02px
// to work around the limitations of `min-` and `max-` prefixes and viewports with fractional widths.
// See https://www.w3.org/TR/mediaqueries-4/#mq-min-max
// Uses 0.02px rather than 0.01px to work around a current rounding bug in Safari.
// See https://bugs.webkit.org/show_bug.cgi?id=178261
//
// >> breakpoint-max(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// 767.98px
@function breakpoint-max($name, $breakpoints: $grid-breakpoints) {
$next: breakpoint-next($name, $breakpoints);
@return if($next, breakpoint-min($next, $breakpoints) - .02, null);
}
// Returns a blank string if smallest breakpoint, otherwise returns the name with a dash in front.
// Useful for making responsive utilities.
//
// >> breakpoint-infix(xs, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "" (Returns a blank string)
// >> breakpoint-infix(sm, (xs: 0, sm: 576px, md: 768px, lg: 992px, xl: 1200px))
// "-sm"
@function breakpoint-infix($name, $breakpoints: $grid-breakpoints) {
@return if(breakpoint-min($name, $breakpoints) == null, "", "-#{$name}");
}
// Media of at least the minimum breakpoint width. No query for the smallest breakpoint.
// Makes the @content apply to the given breakpoint and wider.
@mixin media-breakpoint-up($name, $breakpoints: $grid-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
@if $min {
@media (min-width: $min) {
@content;
}
} @else {
@content;
}
}
// Media of at most the maximum breakpoint width. No query for the largest breakpoint.
// Makes the @content apply to the given breakpoint and narrower.
@mixin media-breakpoint-down($name, $breakpoints: $grid-breakpoints) {
$max: breakpoint-max($name, $breakpoints);
@if $max {
@media (max-width: $max) {
@content;
}
} @else {
@content;
}
}
// Media that spans multiple breakpoint widths.
// Makes the @content apply between the min and max breakpoints
@mixin media-breakpoint-between($lower, $upper, $breakpoints: $grid-breakpoints) {
$min: breakpoint-min($lower, $breakpoints);
$max: breakpoint-max($upper, $breakpoints);
@if $min != null and $max != null {
@media (min-width: $min) and (max-width: $max) {
@content;
}
} @else if $max == null {
@include media-breakpoint-up($lower, $breakpoints) {
@content;
}
} @else if $min == null {
@include media-breakpoint-down($upper, $breakpoints) {
@content;
}
}
}
// Media between the breakpoint's minimum and maximum widths.
// No minimum for the smallest breakpoint, and no maximum for the largest one.
// Makes the @content apply only to the given breakpoint, not viewports any wider or narrower.
@mixin media-breakpoint-only($name, $breakpoints: $grid-breakpoints) {
$min: breakpoint-min($name, $breakpoints);
$max: breakpoint-max($name, $breakpoints);
@if $min != null and $max != null {
@media (min-width: $min) and (max-width: $max) {
@content;
}
} @else if $max == null {
@include media-breakpoint-up($name, $breakpoints) {
@content;
}
} @else if $min == null {
@include media-breakpoint-down($name, $breakpoints) {
@content;
}
}
}
@@ -0,0 +1,110 @@
// Button variants
//
// Easily pump out default styles, as well as :hover, :focus, :active,
// and disabled options for all buttons
@mixin button-variant($background, $border, $hover-background: darken($background, 7.5%), $hover-border: darken($border, 10%), $active-background: darken($background, 10%), $active-border: darken($border, 12.5%)) {
color: color-yiq($background);
@include gradient-bg($background);
border-color: $border;
@include box-shadow($btn-box-shadow);
@include hover() {
color: color-yiq($hover-background);
@include gradient-bg($hover-background);
border-color: $hover-border;
}
&:focus,
&.focus {
color: color-yiq($hover-background);
@include gradient-bg($hover-background);
border-color: $hover-border;
@if $enable-shadows {
@include box-shadow($btn-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
}
}
// Disabled comes first so active can properly restyle
&.disabled,
&:disabled {
color: color-yiq($background);
background-color: $background;
border-color: $border;
// Remove CSS gradients if they're enabled
@if $enable-gradients {
background-image: none;
}
}
&:not(:disabled):not(.disabled):active,
&:not(:disabled):not(.disabled).active,
.show > &.dropdown-toggle {
color: color-yiq($active-background);
background-color: $active-background;
@if $enable-gradients {
background-image: none; // Remove the gradient for the pressed/active state
}
border-color: $active-border;
&:focus {
@if $enable-shadows and $btn-active-box-shadow != none {
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5));
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: 0 0 0 $btn-focus-width rgba(mix(color-yiq($background), $border, 15%), .5);
}
}
}
}
@mixin button-outline-variant($color, $color-hover: color-yiq($color), $active-background: $color, $active-border: $color) {
color: $color;
border-color: $color;
@include hover() {
color: $color-hover;
background-color: $active-background;
border-color: $active-border;
}
&:focus,
&.focus {
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
}
&.disabled,
&:disabled {
color: $color;
background-color: transparent;
}
&:not(:disabled):not(.disabled):active,
&:not(:disabled):not(.disabled).active,
.show > &.dropdown-toggle {
color: color-yiq($active-background);
background-color: $active-background;
border-color: $active-border;
&:focus {
@if $enable-shadows and $btn-active-box-shadow != none {
@include box-shadow($btn-active-box-shadow, 0 0 0 $btn-focus-width rgba($color, .5));
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: 0 0 0 $btn-focus-width rgba($color, .5);
}
}
}
}
// Button sizes
@mixin button-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
padding: $padding-y $padding-x;
@include font-size($font-size);
line-height: $line-height;
// Manually declare to provide an override to the browser default
@include border-radius($border-radius, 0);
}
@@ -0,0 +1,62 @@
@mixin caret-down() {
border-top: $caret-width solid;
border-right: $caret-width solid transparent;
border-bottom: 0;
border-left: $caret-width solid transparent;
}
@mixin caret-up() {
border-top: 0;
border-right: $caret-width solid transparent;
border-bottom: $caret-width solid;
border-left: $caret-width solid transparent;
}
@mixin caret-right() {
border-top: $caret-width solid transparent;
border-right: 0;
border-bottom: $caret-width solid transparent;
border-left: $caret-width solid;
}
@mixin caret-left() {
border-top: $caret-width solid transparent;
border-right: $caret-width solid;
border-bottom: $caret-width solid transparent;
}
@mixin caret($direction: down) {
@if $enable-caret {
&::after {
display: inline-block;
margin-left: $caret-spacing;
vertical-align: $caret-vertical-align;
content: "";
@if $direction == down {
@include caret-down();
} @else if $direction == up {
@include caret-up();
} @else if $direction == right {
@include caret-right();
}
}
@if $direction == left {
&::after {
display: none;
}
&::before {
display: inline-block;
margin-right: $caret-spacing;
vertical-align: $caret-vertical-align;
content: "";
@include caret-left();
}
}
&:empty::after {
margin-left: 0;
}
}
}
@@ -0,0 +1,7 @@
@mixin clearfix() {
&::after {
display: block;
clear: both;
content: "";
}
}
@@ -0,0 +1,10 @@
// Deprecate mixin
//
// This mixin can be used to deprecate mixins or functions.
// `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to
// some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap)
@mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) {
@if ($enable-deprecation-messages != false and $ignore-warning != true) {
@warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}.";
}
}
@@ -0,0 +1,14 @@
// stylelint-disable declaration-no-important
@mixin float-left() {
float: left !important;
@include deprecate("The `float-left` mixin", "v4.3.0", "v5");
}
@mixin float-right() {
float: right !important;
@include deprecate("The `float-right` mixin", "v4.3.0", "v5");
}
@mixin float-none() {
float: none !important;
@include deprecate("The `float-none` mixin", "v4.3.0", "v5");
}
@@ -0,0 +1,178 @@
// Form control focus state
//
// Generate a customized focus state and for any input with the specified color,
// which defaults to the `$input-focus-border-color` variable.
//
// We highly encourage you to not customize the default value, but instead use
// this to tweak colors on an as-needed basis. This aesthetic change is based on
// WebKit's default styles, but applicable to a wider range of browsers. Its
// usability and accessibility should be taken into account with any change.
//
// Example usage: change the default blue border and shadow to white for better
// contrast against a dark gray background.
@mixin form-control-focus($ignore-warning: false) {
&:focus {
color: $input-focus-color;
background-color: $input-focus-bg;
border-color: $input-focus-border-color;
outline: 0;
@if $enable-shadows {
@include box-shadow($input-box-shadow, $input-focus-box-shadow);
} @else {
// Avoid using mixin so we can pass custom focus shadow properly
box-shadow: $input-focus-box-shadow;
}
}
@include deprecate("The `form-control-focus()` mixin", "v4.4.0", "v5", $ignore-warning);
}
// This mixin uses an `if()` technique to be compatible with Dart Sass
// See https://github.com/sass/sass/issues/1873#issuecomment-152293725 for more details
@mixin form-validation-state-selector($state) {
@if ($state == "valid" or $state == "invalid") {
.was-validated #{if(&, "&", "")}:#{$state},
#{if(&, "&", "")}.is-#{$state} {
@content;
}
} @else {
#{if(&, "&", "")}.is-#{$state} {
@content;
}
}
}
@mixin form-validation-state($state, $color, $icon) {
.#{$state}-feedback {
display: none;
width: 100%;
margin-top: $form-feedback-margin-top;
@include font-size($form-feedback-font-size);
color: $color;
}
.#{$state}-tooltip {
position: absolute;
top: 100%;
left: 0;
z-index: 5;
display: none;
max-width: 100%; // Contain to parent when possible
padding: $form-feedback-tooltip-padding-y $form-feedback-tooltip-padding-x;
margin-top: .1rem;
@include font-size($form-feedback-tooltip-font-size);
line-height: $form-feedback-tooltip-line-height;
color: color-yiq($color);
background-color: rgba($color, $form-feedback-tooltip-opacity);
@include border-radius($form-feedback-tooltip-border-radius);
}
@include form-validation-state-selector($state) {
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
}
}
.form-control {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-image: escape-svg($icon);
background-repeat: no-repeat;
background-position: right $input-height-inner-quarter center;
background-size: $input-height-inner-half $input-height-inner-half;
}
&:focus {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
// stylelint-disable-next-line selector-no-qualifying-type
textarea.form-control {
@include form-validation-state-selector($state) {
@if $enable-validation-icons {
padding-right: $input-height-inner;
background-position: top $input-height-inner-quarter right $input-height-inner-quarter;
}
}
}
.custom-select {
@include form-validation-state-selector($state) {
border-color: $color;
@if $enable-validation-icons {
padding-right: $custom-select-feedback-icon-padding-right;
background: $custom-select-background, escape-svg($icon) $custom-select-bg no-repeat $custom-select-feedback-icon-position / $custom-select-feedback-icon-size;
}
&:focus {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
.form-check-input {
@include form-validation-state-selector($state) {
~ .form-check-label {
color: $color;
}
~ .#{$state}-feedback,
~ .#{$state}-tooltip {
display: block;
}
}
}
.custom-control-input {
@include form-validation-state-selector($state) {
~ .custom-control-label {
color: $color;
&::before {
border-color: $color;
}
}
&:checked {
~ .custom-control-label::before {
border-color: lighten($color, 10%);
@include gradient-bg(lighten($color, 10%));
}
}
&:focus {
~ .custom-control-label::before {
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
&:not(:checked) ~ .custom-control-label::before {
border-color: $color;
}
}
}
}
// custom file
.custom-file-input {
@include form-validation-state-selector($state) {
~ .custom-file-label {
border-color: $color;
}
&:focus {
~ .custom-file-label {
border-color: $color;
box-shadow: 0 0 0 $input-focus-width rgba($color, .25);
}
}
}
}
}
@@ -0,0 +1,45 @@
// Gradients
@mixin gradient-bg($color) {
@if $enable-gradients {
background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x;
} @else {
background-color: $color;
}
}
// Horizontal gradient, from left to right
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
@mixin gradient-x($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
background-image: linear-gradient(to right, $start-color $start-percent, $end-color $end-percent);
background-repeat: repeat-x;
}
// Vertical gradient, from top to bottom
//
// Creates two color stops, start and end, by specifying a color and position for each color stop.
@mixin gradient-y($start-color: $gray-700, $end-color: $gray-800, $start-percent: 0%, $end-percent: 100%) {
background-image: linear-gradient(to bottom, $start-color $start-percent, $end-color $end-percent);
background-repeat: repeat-x;
}
@mixin gradient-directional($start-color: $gray-700, $end-color: $gray-800, $deg: 45deg) {
background-image: linear-gradient($deg, $start-color, $end-color);
background-repeat: repeat-x;
}
@mixin gradient-x-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
background-image: linear-gradient(to right, $start-color, $mid-color $color-stop, $end-color);
background-repeat: no-repeat;
}
@mixin gradient-y-three-colors($start-color: $blue, $mid-color: $purple, $color-stop: 50%, $end-color: $red) {
background-image: linear-gradient($start-color, $mid-color $color-stop, $end-color);
background-repeat: no-repeat;
}
@mixin gradient-radial($inner-color: $gray-700, $outer-color: $gray-800) {
background-image: radial-gradient(circle, $inner-color, $outer-color);
background-repeat: no-repeat;
}
@mixin gradient-striped($color: rgba($white, .15), $angle: 45deg) {
background-image: linear-gradient($angle, $color 25%, transparent 25%, transparent 50%, $color 50%, $color 75%, transparent 75%, transparent);
}
@@ -0,0 +1,80 @@
// Framework grid generation
//
// Used only by Bootstrap to generate the correct number of grid classes given
// any value of `$grid-columns`.
@mixin make-grid-columns($columns: $grid-columns, $gutter: $grid-gutter-width, $breakpoints: $grid-breakpoints) {
// Common properties for all breakpoints
%grid-column {
position: relative;
width: 100%;
padding-right: $gutter / 2;
padding-left: $gutter / 2;
}
@each $breakpoint in map-keys($breakpoints) {
$infix: breakpoint-infix($breakpoint, $breakpoints);
@if $columns > 0 {
// Allow columns to stretch full width below their breakpoints
@for $i from 1 through $columns {
.col#{$infix}-#{$i} {
@extend %grid-column;
}
}
}
.col#{$infix},
.col#{$infix}-auto {
@extend %grid-column;
}
@include media-breakpoint-up($breakpoint, $breakpoints) {
// Provide basic `.col-{bp}` classes for equal-width flexbox columns
.col#{$infix} {
flex-basis: 0;
flex-grow: 1;
max-width: 100%;
}
@if $grid-row-columns > 0 {
@for $i from 1 through $grid-row-columns {
.row-cols#{$infix}-#{$i} {
@include row-cols($i);
}
}
}
.col#{$infix}-auto {
@include make-col-auto();
}
@if $columns > 0 {
@for $i from 1 through $columns {
.col#{$infix}-#{$i} {
@include make-col($i, $columns);
}
}
}
.order#{$infix}-first { order: -1; }
.order#{$infix}-last { order: $columns + 1; }
@for $i from 0 through $columns {
.order#{$infix}-#{$i} { order: $i; }
}
@if $columns > 0 {
// `$columns - 1` because offsetting by the width of an entire row isn't possible
@for $i from 0 through ($columns - 1) {
@if not ($infix == "" and $i == 0) { // Avoid emitting useless .offset-0
.offset#{$infix}-#{$i} {
@include make-col-offset($i, $columns);
}
}
}
}
}
}
}
@@ -0,0 +1,69 @@
/// Grid system
//
// Generate semantic grid columns with these mixins.
@mixin make-container($gutter: $grid-gutter-width) {
width: 100%;
padding-right: $gutter / 2;
padding-left: $gutter / 2;
margin-right: auto;
margin-left: auto;
}
@mixin make-row($gutter: $grid-gutter-width) {
display: flex;
flex-wrap: wrap;
margin-right: -$gutter / 2;
margin-left: -$gutter / 2;
}
// For each breakpoint, define the maximum width of the container in a media query
@mixin make-container-max-widths($max-widths: $container-max-widths, $breakpoints: $grid-breakpoints) {
@each $breakpoint, $container-max-width in $max-widths {
@include media-breakpoint-up($breakpoint, $breakpoints) {
max-width: $container-max-width;
}
}
@include deprecate("The `make-container-max-widths` mixin", "v4.5.2", "v5");
}
@mixin make-col-ready($gutter: $grid-gutter-width) {
position: relative;
// Prevent columns from becoming too narrow when at smaller grid tiers by
// always setting `width: 100%;`. This works because we use `flex` values
// later on to override this initial width.
width: 100%;
padding-right: $gutter / 2;
padding-left: $gutter / 2;
}
@mixin make-col($size, $columns: $grid-columns) {
flex: 0 0 percentage($size / $columns);
// Add a `max-width` to ensure content within each column does not blow out
// the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
// do not appear to require this.
max-width: percentage($size / $columns);
}
@mixin make-col-auto() {
flex: 0 0 auto;
width: auto;
max-width: 100%; // Reset earlier grid tiers
}
@mixin make-col-offset($size, $columns: $grid-columns) {
$num: $size / $columns;
margin-left: if($num == 0, 0, percentage($num));
}
// Row columns
//
// Specify on a parent element(e.g., .row) to force immediate children into NN
// numberof columns. Supports wrapping to new lines, but does not do a Masonry
// style grid.
@mixin row-cols($count) {
& > * {
flex: 0 0 100% / $count;
max-width: 100% / $count;
}
}
@@ -0,0 +1,37 @@
// Hover mixin and `$enable-hover-media-query` are deprecated.
//
// Originally added during our alphas and maintained during betas, this mixin was
// designed to prevent `:hover` stickiness on iOS-an issue where hover styles
// would persist after initial touch.
//
// For backward compatibility, we've kept these mixins and updated them to
// always return their regular pseudo-classes instead of a shimmed media query.
//
// Issue: https://github.com/twbs/bootstrap/issues/25195
@mixin hover() {
&:hover { @content; }
}
@mixin hover-focus() {
&:hover,
&:focus {
@content;
}
}
@mixin plain-hover-focus() {
&,
&:hover,
&:focus {
@content;
}
}
@mixin hover-focus-active() {
&:hover,
&:focus,
&:active {
@content;
}
}
@@ -0,0 +1,36 @@
// Image Mixins
// - Responsive image
// - Retina image
// Responsive image
//
// Keep images from scaling beyond the width of their parents.
@mixin img-fluid() {
// Part 1: Set a maximum relative to the parent
max-width: 100%;
// Part 2: Override the height to auto, otherwise images will be stretched
// when setting a width and height attribute on the img element.
height: auto;
}
// Retina image
//
// Short retina mixin for setting background-image and -size.
@mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
background-image: url($file-1x);
// Autoprefixer takes care of adding -webkit-min-device-pixel-ratio and -o-min-device-pixel-ratio,
// but doesn't convert dppx=>dpi.
// There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
// Compatibility info: https://caniuse.com/#feat=css-media-resolution
@media only screen and (min-resolution: 192dpi), // IE9-11 don't support dppx
only screen and (min-resolution: 2dppx) { // Standardized
background-image: url($file-2x);
background-size: $width-1x $height-1x;
}
@include deprecate("`img-retina()`", "v4.3.0", "v5");
}

Some files were not shown because too many files have changed in this diff Show More