My problem is that I want to overwrite a style of a site. Thing is, there is a way to do this, using the !important sentence, as seen in this example.
However, there are thousands of CSS instructions in my file, is there a more quick/efficient way to do this, i.e. not putting !important on each and every single line?
The approach I've found easiest and most effective is to wrap whatever html template you're injecting in a div with a very specific id.
<div id="my-specific-id">
// Your injected HTML template or section of the website you want to change
</div>
Once you've done this, reset all of the CSS that might affect that section.
#my-specific-id {
// A comprehensive CSS reset
}
// The rest of your CSS will override the reset above
Here is one such reset: http://html5doctor.com/html-5-reset-stylesheet/
Note that you probably won't need everything from the CSS Reset, so remove what isn't relevant to take some load off the browser. I can't imagine that you really want to reset figcaption, for example.
As someone writing an extension, you should care a lot about whether or not your extension ruins the user experience on websites you inject scripts into.
The approach I've outlined will guarantee that only the sections of the website that you specifically care about are changed.
You can do this with your own templates (say you wanted to add a weather widget to every page without using an iframe) or with specific parts of the page. You could, for example, wrap all <p> elements in a highly specific id that you define.
Here's an example using Sass from a recent project I've been working on...
#specific-id-css-ultimate-reset {
html, button, input, div, p, img, form {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
#import "modules/all";
#import "components/all";
#import "popups/all";
}
<div id="my-superspecific-html-template-wrapper">
<HTML TEMPLATE>
</div>
Maybe it will be faster for you to include all styles from the original CSS that you don't wish to override in your injected stylesheet? If so, you can then remove the original stylesheet from page using content script/code injection or blocking the browser request for CSS file.
You can also write a small script that does some regex magic and adds !important to every line of given CSS file.
Related
I am currently using the following css to display a list of items with a flexbox
section ol li div ul {
display:flex;
flex-direction:row;
flex-wrap: wrap;
gap:7px;
row-gap:0;
list-style-type: none;
}
This satisfies me on all but one problem:
when I have a big item that will not fit entirely on the rest of the line, it will be set at the beginning of a new line, thus possibly making a huge part of the line before unused. I do not wish that (note that for small items, this is exactly what I want).
Initial goal (probably not achievable): I have been thinking on what kind of rule I would like and it would be something like "if more than x% of the line is wasted, then display the item inline instead". This would enable to continue filling the line.
I have currently abandoned on doing that with only html and css and I might consider trying to write such a rule in js later, but not for now (unless somebody has a very nice solution).
Current goal: I have thus decided to manually specify some items (that are "big") that should be inlined (sometimes using media queries, but we can ignore them for now). The idea is to add the following class to those objects.
.inlineitem {
display:inline;
}
Problem: display:inline; within a flex container does not work and I do not wish to change the whole flex container for the other items... Is there a way to achieve what I want ?
Has anyone solved or knows how to solve the following situation given the implementation of the header in Spartacus?
I would like to show in the header, a layout on the right of two level blocks, and on the left of a single level block.
Objective Header Layout
I can't think of how to do it since I can't see how to wrap certain slots, given the Spartacus implementation for the header.
Given the implementation of the header in Spartacus, inside the StorefrontComponent I cannot replace it using the ConfigModule.withConfig ({...}, as CmsConfig)
I understand and already tried that I can replace the header, implementing an Outlet (cxOutletRef = "header"), but this makes it impossible to edit it through SmartEdit, which is not acceptable to me.
Any suggestion? Or possible solution?
As a last option it occurs to me that I can create a component type from the back, and map it from Angular using "ConfigModule.withConfig ({...}, as CmsConfig)" implementing the "conflicting two-level" block from scratch or even the entire header.
Thank you !
////// CORRECTION 09/23/20 //////
Outlets do not prevent editing via SmartEdit. It's necessary to indicate the Slot to which the component corresponds, this is easy to implement using the PageSlotComponent.
✔ Example:
<ng-template cxOutletRef="cx-header">
<header
cxSkipLink="cx-header"
[cxFocus]="{ disableMouseFocus: true }"
[class.is-expanded]="isExpanded$ | async"
(keydown.escape)="collapseMenu()"
(click)="collapseMenuIfClickOutside($event)"
>
<cx-page-slot position="MiniCart"></cx-page-slot>
</header>
<cx-page-slot position="BottomHeaderSlot"> </cx-page-slot>
<cx-global-message></cx-global-message>
</ng-template>
In this way, SmartEdit does allow you to edit the MiniCart component, within its corresponding slot.
🚫 Wrong way:
<ng-template cxOutletRef="cx-header">
<header
cxSkipLink="cx-header"
[cxFocus]="{ disableMouseFocus: true }"
[class.is-expanded]="isExpanded$ | async"
(keydown.escape)="collapseMenu()"
(click)="collapseMenuIfClickOutside($event)"
>
<cx-mini-cart></cx-mini-cart>
</header>
<cx-page-slot position="BottomHeaderSlot"> </cx-page-slot>
<cx-global-message></cx-global-message>
</ng-template>
you can indeed solve this with a custom layout configuration and additional CSS, but it's not necessary. I give you a few options to consider:
Option 1: Change the generated DOM
You can either provide a custom layout config as #pwavg suggests, or even introducing a custom storefront component.
If you introduce a custom layout config, you're limited by the sections we use in the storefront component. If you insist on custom sections (ie. an element that wraps the searchbox, login, mincart and nav), you need to introduce a custom storefront component. The disadvantage here is that you'll deviating away from standard Spartacus component, which might result in missing features in the future.
Option 2: Pure CSS
A pure CSS solution is the easiest. You do not need to change any actual DOM, but apply some custom CSS rules to the standard DOM. Grid system is indeed designed for this. It's a bit complex to start with, but would do the job.
You can actually achieve this with flexbox as well, but you'd need to move the logo slot out of the flexbox flow.
Here's an actual quick and dirty code snippet to demonstrate changing by a few CSS rules only. It comes with a few assumptions/limitations, but for most cases it might be fine.
header {
cx-page-slot.SiteLogo {
// we absolute position the logo, so it flows outside the flexbox system. this requires
// an hard-coded top position, that might be fine, but I don't know the details.
position: absolute;
top: 60px;
}
cx-page-slot.SearchBox {
// align searchbox to the left, not sure if that's required, but looks better
margin: 14px auto 14px 150px;
}
cx-page-slot.NavigationBar {
margin-left: 150px;
overflow: hidden;
}
// manipulate a very high logo to demonstrate this works
cx-page-slot.SiteLogo img {
height: 100px;
}
}
Result (sorry for the logo ;) )
Option 3: cx-header Outlet
I would say you should be able to use outlets as well, as this will get you closer to option 1 (changing the actual DOM). I can't think of a reason why it would not work in SmartEdit - but happy to learn if it is the case. I'd recommend in this case to use the cx-header outletRef, so you would replace the entire header.
I am not super experienced with Spartacus so this might not be the correct way. Just trying to think with you on this.
I think you can just extend you layoutconfig and style the slots with CSSGrid. So for example you layout could be something like this:
layoutSlots: {
header: {
lg: {
slots: [
'SiteLinks',
'SiteLogin',
'HeaderLinks',
'SiteLogo',
'NavigationBar',
'SearchBox',
'MiniCart',
'NavigationBar2',
],
},
slots: ... (for mobile view)
},
},
And create a custom css grid for the positions of the slot.
If you want to have more markup control you could use cxOutletRef to replace the header with something like:
<ng-template cxOutletRef="cx-header">
<header>
<div class="header-top">
<cx-page-layout section="headerTop"></cx-page-layout>
</div>
<div class="header-bottom">
<cx-page-layout section="headerBottom"></cx-page-layout>
</div>
</header>
</ng-template>
And then divide the slots between headerTop and headerBottom in you config.
I'm attempting to move from font icons (icomoon.io) to SVG sprites. Is it possible to use SVG sprites without needing < svg > markup for each icon instance?
What I really liked about the font icons was that I didn't have to clutter my HTML with any additional elements to get the icon to display. I usually just targeted a simple class on whatever element I wanted the icon to display and then used pseudo selectors to display the icon, e.g.:
<h1 class="news">News</h1>
h1.user:before {
font-family: 'icons';
content: '\news';
}
That made a lot of sense to me, and all of my icons were easily managed almost completely in CSS. I rarely had to touch my HTML as long as my markup contained appropriate classes.
I've since switched my build system to Grunt and thought I'd give SVG sprites a try. Almost every1 article2 I3 can4 find5 on the subject says you need to add an additional SVG element to your markup wherever you want each instance to display, e.g.:
<h1>
<svg class="icon">
<use xlink:href="#icon-news">
</svg>
News
</h1>
That seems like a step backwards to me, at least in the management of markup. To me, an icon is usually presentation that should be separate from document structure. Are we doing it this way simply because of the state of SVG support in browsers?
Ideally, I'd love to be able to do something like this:
<h1 class="news">News</h1>
h1.news:before {
display: inline-block;
width: px;
height: px;
background: url(icons.svg#news) no-repeat;
}
This post seems to be closer to what I'm looking for, but I'm not sure of browser support and how to do it automatically in a build system like Grunt.
SVGs can be loaded as files exactly the same way as other images using <img> tags or CSS background, and can be used as sprites exactly the same way too. The only difference is that you have to specify the size you want it (because it's scalable, so the browser doesn't automatically know how big it is like it does with PNGs).
Depending on how you want to use the image, loading them this way may or may not be suitable as some SVG features aren't available, but it can be done.
I'm trying to use macros in a CSS file (in site manager-> development).
This is my CSS code:
#import url('/CMSPages/GetResource.ashx?stylesheetname=sitecss{$=|en-US=eng$}');
a, a:visited, a:active {
color:#407a1f;
}
....
This doesn't seem to work dynamically on the site as I switch between default culture and English.
The only time that it works is if I SAVE the CSS file (in site manager) while the site itself is in a certain culture.
In short: the macro "takes" the culture when the CSS file is saved and is not dynamic upon page loading.
How can I solve this?
THANKS :)
As far as I know, you cannot make you CSS code dynamic. However, you can do this easily as explained below:
Kentico adds a special class to the body tag of the document. Check your source code and you will see that the body tag has a class ENUS if the current culture is en-US, ENGB if the current culture is en-GB and so on.
Then you can change your CSS code accordingly by defining rules like:
body.ENUS .container { float: left; }
body.ENGB .container { float: right; }
body.FRFR .container { float: none; }
Hope this helps.
In version 6 and later you can do it by
#import url('/CMSPages/GetResource.ashx?stylesheetname=sitecss{%CurrentCulture%}');
or you can directly resolve target CSS by
{% CSS["<stylesheet code name>"] %}
See more on http://devnet.kentico.com/docs/devguide/index.html?combining_stylesheets.htm
Hey guys I'm currently having trouble with my CSS linking. Basically I want the colour of my links to change when I hover over them, and click on them and such. But for some reason it is not working when I view it on a browser. Below is my HTML code and my CSS code, they are seperate files and are linked togather. Thanks in advance. (I apologise if the codes are not appearing correctly but it is all there)
EDIT: Don't worry its fixed now :D thanks for the help
from what I see, you don't have a:hover,a:vistied, or a:active defined anywhere, which is what controls the behavior you're looking for.
Are you coding by hand or using Dreamweaver as a WYSIWYG?
NOTE: This could be because the files aren't formatted well in your question, so Markdown could have dropped some characters from the display.
From what I can see, the CSS file isn't written correctly. I'm going to give one example for you which fits for the whole file:
content {
width: 510px;
float: left;
}
This snippet above looks for the <content> tag in the HTML, and when it finds that tag, it will give it a width of 510px and floats it to the left. The problem here is that there are no <content> tags in your HTML page OR in HTML 4.01 itself. What you need to do is change it to this:
.content {
width: 510px;
float: left;
}
By adding the '.' before 'content' in the CSS, it changes 'content' from <content> to finding a tag that has class="content" as an attribute.
Also, to get the <a> tags to change on hover, etc, use the pseudo-elements (pseudo-attributes?) of :hover, :active, and :visited, for when a user hovers over a link, clicks on a link, and has previously visited a link, respectively.
Example:
a {
color: blue;
}
a:hover {
color: red;
}
In this example, a link will display as blue unless the user has their mouse on the link.