I have a variable called --primary-color defined at root like this:
:root {
--primary-color: red;
}
In a small section in my site I want to change the primary-color for all nested elements. I currently change the primary color like this:
<button class="PrimaryButton">red</button>
<div style="--primary-color: purple">
<button class="PrimaryButton">purple</button>
</div>
However notice i had to put the purple style on a div. This changes layout. Is there some element or someway I can change the variable without using a layout element like a div? I can't use as that affects global.
Here is example:
:root {
--primary-color: red;
}
.PrimaryButton {
background-color: var(--primary-color);
width: 100px;
height: 40px;
}
<button class="PrimaryButton">red</button>
<div style="--primary-color: purple">
<button class="PrimaryButton">purple</button>
</div>
Thank you!
Solution #1. If I understood your question correctly, you can keep a div in the structure, but make it not affect the layout too much with display: contents;. I've extended your example (with a CSS grid and a couple of elements added for clarity) so you can see that the div with display: content; has no effect on the structure:
:root {
--primary-color: red;
}
.PrimaryButton {
background-color: var(--primary-color);
width: 100px;
height: 40px;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
<section class="grid">
<button class="PrimaryButton">red 1</button>
<div style="--primary-color: purple; display: contents;">
<button class="PrimaryButton">purple 1</button>
<button class="PrimaryButton">purple 2</button>
</div>
<div style="--primary-color: aquamarine; display: contents;">
<button class="PrimaryButton">aquamarine 1</button>
<button class="PrimaryButton">aquamarine 2</button>
</div>
<div style="--primary-color: pink; display: contents;">
<button class="PrimaryButton">pink 1</button>
</div>
</section>
Solution #2.. If you need to support older browsers, then CSS Combinators such as ~ or + (+ display:none for third-party elements) can help you. Example below:
:root {
--primary-color: red;
}
.PrimaryButton {
background-color: var(--primary-color);
width: 100px;
height: 40px;
}
.grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.primary-color-changer,
.primary-color-only-one {
display: none;
}
.primary-color-only-one.purple+.PrimaryButton,
.primary-color-changer.purple~.PrimaryButton {
--primary-color: purple;
}
.primary-color-only-one.aquamarine+.PrimaryButton,
.primary-color-changer.aquamarine~.PrimaryButton {
--primary-color: aquamarine;
}
.primary-color-only-one.pink+.PrimaryButton,
.primary-color-changer.pink~.PrimaryButton {
--primary-color: pink;
}
.primary-color-only-one.green+.PrimaryButton,
.primary-color-changer.green~.PrimaryButton {
--primary-color: green;
}
.primary-color-only-one.color-default+.PrimaryButton,
.primary-color-changer.color-default~.PrimaryButton {
--primary-color: inherit;
}
<section class="grid">
<button class="PrimaryButton">red 1 (default)</button>
<div class="primary-color-only-one green"></div>
<button class="PrimaryButton">green 1(only one)</button>
<div class="primary-color-changer purple"></div>
<button class="PrimaryButton">purple 1</button>
<button class="PrimaryButton">purple 2</button>
<div class="primary-color-changer aquamarine"></div>
<button class="PrimaryButton">aquamarine 1</button>
<button class="PrimaryButton">aquamarine 2</button>
<div class="primary-color-changer pink"></div>
<button class="PrimaryButton">pink 1</button>
<div class="primary-color-changer color-default"></div>
<button class="PrimaryButton">red 2 (default)</button>
<button class="PrimaryButton">red 3 (default)</button>
</section>
Related
I need to display a list of scheduled jobs in an endless scroll list of angular material,
for each element in the list, I need to divide it into 3 columns using flexbox.
in each column, I want to display certain data.
for some reason, I'm not able to add space between columns inside the list.
here is my code in html
<app-nav>
<div class="grid-container">
<div class="row1">
<mat-grid-list cols="6" rowHeight="100px">
<mat-grid-tile [colspan]="1" [rowspan]="1" [style.background]="lightgreen">
<h2>All Scheduled Jobs</h2>
</mat-grid-tile>
<mat-grid-tile [colspan]="4" [rowspan]="1" [style.background]="lightgreen">
</mat-grid-tile>
<mat-grid-tile [colspan]="1" [rowspan]="1" [style.background]="lightgreen">
<button (click)="openCreateScheduledJobDialog()" mat-mini-fab color="primary"
aria-label="Example icon button with a plus one icon">
<mat-icon>plus_one</mat-icon>
</button>
</mat-grid-tile>
</mat-grid-list>
</div>
<div class="row2"> // the problem is in this part:
<cdk-virtual-scroll-viewport itemSize="70" class="example-viewport">
<mat-list>
<mat-list-item *cdkVirtualFor="let scheduledjob of scheduledJobs" class="example-item">
<div class="flex-container-list-item"> // here is the flex that i need to fix
<div class="details">
<h3 matLine>{{getJob(scheduledjob.jobID)}} Job</h3>
<h4 matLine> Status: {{getJobStatus(scheduledjob.isActive)}}</h4>
<p matLine>
<span> Start time: {{scheduledjob.startTime | date}} </span>
</p>
<p matLine>
<span> End time: {{scheduledjob.endTime | date}}</span>
</p>
<p matLine>
<span> Runs Every: {{scheduledjob.daysFrequency}} days
</span>
</p>
<p matLine>
<button mat-stroked-button color="primary"
(click)="openMachineDetailsDialog(scheduledjob.machineSerialNumber)">Machine Details</button>
</p>
</div>
<div class="edit"> <button mat-flat-button color="primary" (click)="openUpdateScheduledJobDialog(scheduledjob)">Edit</button></div>
<div class="delete"> <button mat-raised-button (click)="delete(scheduledjob)" color="warn">Delete</button>
</div>
</div>
<mat-divider></mat-divider>
</mat-list-item>
</mat-list>
</cdk-virtual-scroll-viewport>
</div>
<div class="row3">
</div>
</div>
</app-nav>
note that im using angular material cdk-virtual-scroll-viewport
here is the css:
.row1 {
grid-area: row1;
}
.row2 {
grid-area: row2;
}
.row3 {
grid-area: row3;
}
.grid-container {
display: grid;
grid-template-areas:
'row1 row1 row1'
'row2 row2 row2'
'row3 row3 row3 '
;
grid-gap: 2px;
padding: 2px;
}
.grid-container>div {
text-align: center;
padding: 10px 0;
font-size: 15px;
}
.example-viewport {
height: 600px;
border: 2px solid gray;
}
.example-item {
height: 50px;
}
/* ******************* list item flex ***************** */
.details {
background-color:lightcoral ;
}
.edit {
background-color: lightgreen;
}
.delete {
background-color: lightskyblue;
}
.flex-container-list-item {
display: flex;
border: 6px solid red;
justify-content: space-between;
--gap: 10rem;
flex-wrap: wrap;
}
.grid-container-list-item>div {
text-align: center;
padding: 10px 0;
font-size: 15px;
}
Use either the gap property on the flex container, or set [margin](http://developer.mozilla.org/en-US/docs/Web/CSS/margin) on your flex items.
Your current solution doesn’t seem to be working because you set a CSS custom property --gap: 10rem on your flex container, but then don’t actually apply that property (at least in the provided code).
You can use gap, and that will ensure a fixed amount between the flex items. Browser support for gap is good, with the exception of Safari before version 14.1.
Alternatively, you could set margin-right on all your flex items with the exception of the last item to achieve a similar effect.
Here’s a working (simplified) example:
.flex-container-list-item {
display: flex;
border: 6px solid red;
gap: 2rem;
flex-wrap: wrap;
}
.details {
background-color: lightcoral;
}
.edit {
background-color: lightgreen;
}
.delete {
background-color: lightskyblue;
}
<div class="flex-container-list-item">
<div class="details">
<h3>Job</h3>
<h4>Status: active</h4>
<p>
<span> Start time: 2 PM</span>
</p>
<p>
<span> End time: 4 PM</span>
</p>
<p>
<span> Runs Every: 3 days </span>
</p>
<p>
<button>Machine Details</button>
</p>
</div>
<div class="edit">
<button
mat-flat-button
color="primary"
(click)="openUpdateScheduledJobDialog(scheduledjob)"
>
Edit
</button>
</div>
<div class="delete">
<button mat-raised-button (click)="delete(scheduledjob)" color="warn">
Delete
</button>
</div>
</div>
Ideally you should do the followings and it should work :
.container{
display : flex;
flex-flow: row wrap;
justify-content: space-between;
}
.item{
margin: 10px;
height: 100px;
width: 100px;
}
.item1{
background-color: red;
}
.item2{
background-color: yellow;
}
<div class="container">
<div class="item item1"></div>
<div class="item item2"></div>
</div>
even though your question is not so clear. you can do following update on your HTML and css files :
.flex-container-list-item{
display: flex;
flex-flow: row wrap;
justify-content: space-between;
}
<div class="flex-container-list-item">
<div class="details">details contents</div>
<div class="action">
<button
mat-flat-button
color="primary"
(click)="openUpdateScheduledJobDialog(scheduledjob)"
>
Edit
</button>
<button mat-raised-button (click)="delete(scheduledjob)" color="warn">
Delete
</button>
</div>
</div>
I might or might not need flexbox for this issue, but I'm still learning and trying to understand how I can get the title to be on top of the add button, which should fill about 96% of the row's width under the title.
I created a stackblitz to demonstrate current code. Also the desktop version should allow title and add button to occupy same row at 70% 30% grid like in stackblitz demo.
This is the desired result when you collapse the browser window to mobile
html
<div class="listingBody">
<div class="listingParent">
<div class="listingCard">
<div class="topRow">
<span id="title">title</span><span
id="addButtonSpan">
<button id="addButton" type="button">
Add Button</button>
</span>
</div>
</div>
</div>
</div>
css
#title {
text-align:center;
}
.topRow {
display: grid;
grid-template-columns: 70% 30%;
}
This is how I would go about it using just flexbox not css grid.
I use a media query to do the mobile stacked layout with flex-direction: column
.topRow {
display: flex;
}
.topRow #title {
width: 70%;
}
.topRow #addButtonSpan {
width: 30%;
}
#media only screen and (max-width: 600px) {
.topRow {
flex-direction: column;
}
.topRow span {
margin: 0 auto;
text-align: center;
}
.topRow #title {
width: 96%;
}
.topRow #addButtonSpan {
width: 96%;
}
}
<div class="listingBody">
<div class="listingParent">
<div class="listingCard">
<div class="topRow">
<span id="title">title</span>
<span id="addButtonSpan">
<button id="addButton" type="button">
Add Button
</button>
</span>
</div>
</div>
</div>
</div>
Ive been working on this form but I am now having trouble getting things to line up properly. On smaller sizes its not to big an issue, but on large screens the problem is very noticeable.
Two main issues I am finding is that I have some social links that is getting extra spacing from somewhere, though there is no padding or margins between them that I can see. Also the actual form itself is not filling in the whole space. Im not exactly sure how to fix the spacing issues here.
Anyone offer any tips?
Here is a JsFiddle of the code the code saved to SO and Jsfiddle are exact same, though it appears they are giving different results. Not sure why, though clearly I probably messed something up here.
https://jsfiddle.net/Tsukiyono/aq9Laaew/283640/
Here is another link showing things on my gitpages link:
https://tsukiyonocm.github.io/test/
edit A image of the layout I am trying to achieve.
https://imgur.com/a/al8KEMh
body {
background-color: black;
}
/** Contact
---------------------------------------------------------*/
#contactus {
color: black;
max-height: 62.5rem;
width: auto;
}
.contact-title {
font-family: futura-pt-condensed, sans-serif;
font-weight: 700;
padding: 1rem 0;
}
.contact-info {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.custom-contact {
max-height: 15rem;
}
.social {
font-weight: 700;
}
.custom-social {
max-height: 15rem;
width: auto;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.social-contact ul {
list-style: none;
display: flex;
justify-content: center;
padding: 0;
}
.social-contact ul li {
padding: 0 1rem;
}
.btn-sub {
letter-spacing: 1.5;
color: black;
background-color: #fff;
font-weight: 700;
border-radius: 0.15rem;
white-space: normal;
}
.btn-form {
width: 100%;
letter-spacing: 1.5;
color: black;
background-color: #fff;
font-weight: 700;
border-radius: 0.15rem;
}
form {
max-width: 100%;
margin: 0 .5rem;
}
.form-control {
background-color: rgb(46, 46, 46);
border: 1px solid white;
border-radius: 0.2rem;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet" />
<section id="contactus">
<div class="container">
<div class="row">
<div class="col-12 text-center">
<h1 class="display-3 contact-title">Contact Us</h1>
</div>
</div>
<div class="row">
<div class="col-12 col-lg-6">
<div class="row contact-info d-flex flex-md-row flex-lg-column">
<div class="col-12 col-md-6 custom-contact">
<h3>- Our Office -</h3>
<address>
SOCKEROO Marketing<br>
123 Address Rd.<br>
Pittsburgh, PA<br>
15222<br>
TEL - 555.555.5555<br>
Email - sockeroomarketing#gmail.com
</address>
</div>
<div class="col-12 col-md-6 custom-social">
<p class="social">- Say Hello -</p>
<div class="social-contact">
<ul class="">
<li><i class="fab fa-inverse fa-twitter-square fa-lg"></i></li>
<li><i class="fab fa-inverse fa-facebook-square fa-lg"></i></li>
<li><i class="fab fa-inverse fa-linkedin fa-lg"></i></li>
<li><i class="fab fa-inverse fa-instagram fa-lg"></i></li>
</ul>
</div>
<button class="btn btn-sub">Subscribe to Our Newsletter</button>
</div>
</div>
</div>
<div class="col-12 col-lg-6 m-0 p-0">
<form action="">
<div class="form-group">
<input type="text" class="form-control" placeholder="Name">
</div>
<div class="form-group">
<input type="text" class="form-control" placeholder="Company or Organization">
</div>
<div class="form-group">
<input type="email" class="form-control" placeholder="Email Address">
</div>
<div class="form-group">
<input type="tel" class="form-control" placeholder="Phone Number">
</div>
<div class="form-group">
<textarea name="comment" class="form-control" placeholder="Tell us a bit about your project, timeline, and budget"></textarea>
</div>
<button class="btn btn-form">Submit</button>
</form>
</div>
</div>
</div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
In regards to the inconsistency between JSFiddle and Github pages, I believe the problem lies in the way bootstrap implements their col-md-6 class. Namely, the flex-basis property.
For reference, this is what I see their class to be, based on the element inspector in chrome:
#media (min-width: 768px)
.col-md-6 {
-ms-flex: 0 0 50%;
flex: 0 0 50%;
max-width: 50%;
}
(A little context: flex is shorthand for defining flex-grow, flex-shrink, and flex-basis, in that order. You can find that info in this article on CSS-Tricks: here and a little more detail on flex basis just above it, here).
As you can see, they're setting flex basis to 50%. Once I set both the jsfiddle and gitpages' flex property to flex: 0 0 auto, the spacing was consistent on both of those pages, leading me to wonder if flex-basis is calculating 50% to be one value in the JSFiddle and another value in your Github pages. As for a solution, what you can do is create a custom class, let's say .cust-col-md-6, and copy the ruleset defined by bootstrap, but change the flex-basis of the property to auto:
#media (min-width: 768px)
.cust-col-md-6 {
-ms-flex: 0 0 auto;
flex: 0 0 auto;
max-width: 50%;
}
Then from here you can set that as your class instead of using .col-md-6:
<div class="col-12 cust-col-md-6 custom-social">
I have a flexbox and I would like my form-control (width: 100%) button to extend to the same length as the h2, not the h1. Unfortunately, because the div that both the h2 and the button are placed in does not have a width declared, the form-control class is extending the width of the button to the parent that has a width declared.
I have tried setting the parent div (.landing-header div) to position relative, and I have tried setting a min-width on it but it has not worked.
The reason I don't want to explicitly declare a width is because I don't want my h2 to wrap around, rather I want my h2 to dictate the width of the div and therefore the width of the button.
Screenshot:
screenshot
#landing-page {
.row {
height: 100vh;
}
.btn-custom {
margin-top: 50px;
}
}
.landing-header {
padding-left: 5%;
div {
min-width: 60%;
}
}
.landing-graphic {
background: $blue;
width: 40%;
}
// Extra large devices (large desktops, 1200px and up)
#media (min-width: 1200px) {
}
<div class="container-fluid">
<div class="row d-flex flex-row justify-content-between align-items-stretch">
<div class="landing-header d-flex flex-column justify-content-center">
<h1>SAMUEL COLE</h1>
<div>
<h2>Web Development and Design</h2>
<button class="btn form-control btn-custom about-nav">Get Started</button>
</div>
</div>
<div class="landing-graphic">
test
</div>
</div>
</div>
To achieve what you wanted to do I would set display: inline-block to the parent div of the h2 and the button.
With this change your snippet will look like this:
If you remove the flex characteristics from your landing-header div this is possible.
Then set the div holding the h2 and button to display:table and width:1%.
This will collapse the div to its own width.
Apply white-space:nowrap; to the h1 and h2 so the text doesn't wrap and...
#landing-page .row {
height: 100vh;
}
#landing-page .btn-custom {
margin-top: 50px;
}
.landing-header {
padding-left: 5%;
}
.landing-header div {
min-width: 60%;
}
.landing-graphic {
background: blue;
width: 40%;
}
button.about-nav {
background: limegreen;
}
.this-one {
display: table;
width: 1%;
}
.this-one h2 {
white-space: nowrap;
font-size: 14px;
}
.landing-header h1 {
white-space: nowrap;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css" rel="stylesheet" />
<div class="container-fluid">
<div class="row d-flex flex-row justify-content-between align-items-stretch">
<div class="landing-header ">
<h1>SAMUEL COLE</h1>
<div class="this-one">
<h2>Web Development and Design</h2>
<button class="btn form-control btn-custom about-nav">Get Started</button>
</div>
</div>
<div class="landing-graphic">
test
</div>
</div>
</div>
I have this header bar.
<div id="header">
<div class="container">
<img src="img/logo.png"/>
<div id="searchBar">
<input type="text" />
</div>
<div class="buttonsHolder">
<div class="button orange inline" id="myAccount">
My Account
</div>
<div class="button red inline" id="basket">
Basket (2)
</div>
</div>
</div>
</div>
I need the searchBar to fill whatever the remaining gap is in the div. How would I do this?
Here's my CSS
#header {
background-color: #323C3E;
width:100%;
}
.button {
padding:22px;
}
.orange {
background-color: #FF5A0B;
}
.red {
background-color: #FF0000;
}
.inline {
display:inline;
}
#searchBar {
background-color: #FFF2BC;
}
Use calc!
https://jsbin.com/wehixalome/edit?html,css,output
HTML:
<div class="left">
100 px wide!
</div><!-- Notice there isn't a space between the divs! *see edit for alternative* --><div class="right">
Fills width!
</div>
CSS:
.left {
display: inline-block;
width: 100px;
background: red;
color: white;
}
.right {
display: inline-block;
width: calc(100% - 100px);
background: blue;
color: white;
}
Update: As an alternative to not having a space between the divs you can set font-size: 0 on the outer element.
You can realize this layout using CSS table-cells.
Modify your HTML slightly as follows:
<div id="header">
<div class="container">
<div class="logoBar">
<img src="http://placehold.it/50x40" />
</div>
<div id="searchBar">
<input type="text" />
</div>
<div class="button orange" id="myAccount">My Account</div>
<div class="button red" id="basket">Basket (2)</div>
</div>
</div>
Just remove the wrapper element around the two .button elements.
Apply the following CSS:
#header {
background-color: #323C3E;
width:100%;
}
.container {
display: table;
width: 100%;
}
.logoBar, #searchBar, .button {
display: table-cell;
vertical-align: middle;
width: auto;
}
.logoBar img {
display: block;
}
#searchBar {
background-color: #FFF2BC;
width: 90%;
padding: 0 50px 0 10px;
}
#searchBar input {
width: 100%;
}
.button {
white-space: nowrap;
padding:22px;
}
Apply display: table to .container and give it 100% width.
For .logoBar, #searchBar, .button, apply display: table-cell.
For the #searchBar, set the width to 90%, which force all the other elements to compute a shrink-to-fit width and the search bar will expand to fill in the rest of the space.
Use text-align and vertical-align in the table cells as needed.
See demo at: http://jsfiddle.net/audetwebdesign/zWXQt/
I know its quite late to answer this, but I guess it will help anyone ahead.
Well using CSS3 FlexBox. It can be acheived.
Make you header as display:flex and divide its entire width into 3 parts. In the first part I have placed the logo, the searchbar in second part and buttons container in last part.
apply justify-content: space-between to the header container and flex-grow:1 to the searchbar.
That's it. The sample code is below.
#header {
background-color: #323C3E;
justify-content: space-between;
display: flex;
}
#searchBar, img{
align-self: center;
}
#searchBar{
flex-grow:1;
background-color: orange;
padding: 10px;
}
#searchBar input {
width: 100%;
}
.button {
padding: 22px;
}
.buttonsHolder{
display:flex;
}
<div id="header" class="d-flex justify-content-between">
<img src="img/logo.png" />
<div id="searchBar">
<input type="text" />
</div>
<div class="buttonsHolder">
<div class="button orange inline" id="myAccount">
My Account
</div>
<div class="button red inline" id="basket">
Basket (2)
</div>
</div>
</div>
This can be achieved by wrapping the image and search bar in their own container and floating the image to the left with a specific width.
This takes the image out of the "flow" which means that any items rendered in normal flow will not adjust their positioning to take account of this.
To make the "in flow" searchBar appear correctly positioned to the right of the image you give it a left padding equal to the width of the image plus a gutter.
The effect is to make the image a fixed width while the rest of the container block is fluidly filled up by the search bar.
<div class="container">
<img src="img/logo.png"/>
<div id="searchBar">
<input type="text" />
</div>
</div>
and the css
.container {
width: 100%;
}
.container img {
width: 50px;
float: left;
}
.searchBar {
padding-left: 60px;
}
in css:
width: -webkit-fill-available
I would probably do something along the lines of
<div id='search-logo-bar'><input type='text'/></div>
with css
div#search-logo-bar {
padding-left:10%;
background:#333 url(logo.png) no-repeat left center;
background-size:10%;
}
input[type='text'] {
display:block;
width:100%;
}
DEMO
http://jsfiddle.net/5MHnt/
Include your image in the searchBar div, it will do the task for you
<div id="searchBar">
<img src="img/logo.png" />
<input type="text" />
</div>
I did a quick experiment after looking at a number of potential solutions all over the place. This is what I ended up with:
http://jsbin.com/hapelawake