"The structure is always subject to function, which is the immutable rule," said Louis Sullivan, the architect of skyscraper's father. Because engineers don't want innocent people to be crushed under huge buildings, this thumb-like rule is quite useful. In design you should always focus on functionality , and then let the structure appear in the results. If you take the structure as a priority, although it can build a beautiful skyscraper, the price is to bury a lot of very dangerous seeds.
These are all about architects, so what about front-end architects or "non-real architects"? Do we need to obey this rule or ignore it?
With the advent of object-oriented css (OOCSS), more and more people tend to "detach the semantics of rendering from the document Semantics". With the non-specific meaning of Class (classes), we can manage the appearance of a document and a document in a separate way.
In this article, we'll explore a variety of ways to add styles to Web documents that combine document semantics with visual design. With the use of "smart" selectors, we show you how to query the existing functional features of semantically formatted HTML documents as a reward for well-formed markup. If your code is correct, you will certainly get what you expect to design.
I think that if you are developing several different projects at the same time as me, I hope that these methods will simplify your workflow and make it easier to travel through these projects. In addition, in the final section we'll talk about a more passive approach: we'll make a CSS bookmark that contains a property selector to test those poorly written HTML documents and use pseudo elements to feed back errors.
Smart Selector.
The invention of the stylesheet enabled us to isolate code that beautified HTML documents from HTML documents. But it does not help us to write standard HTML documents in the same way as the remote control for the television to bring a higher quality television. It simply makes the job easier. Because we can use a selector to add styles to multiple elements. (for example, p can be used for all paragraph elements), the consistency and maintainability of the page is not as daunting as it used to be.
The simplest form of the P selector is a representation of the smart selector. Because the P selector has a natural basis for semantic categorization. Without the developers doing extra things, it already knows how to confirm a paragraph and when to add a style to them, very simple and effective, especially if you want to add styles to all the paragraph elements that are generated by the WYSIWYG editor.
But if it's a smart selector, what about the smart selector? All selectors that require developers to intervene and change documents to cause changes in style are called non intelligent selectors. Class is a classic, non-intelligent selector because it doesn't appear as part of a semantic convention. You can name and organize your classes flexibly, but you need to think about them, and they won't do anything automatically unless you apply them to the document.
Using a non-intelligent selector is very time-consuming, because we need to manually add a different style to each selector and copy the class name to every element that needs to be applied to the class. If we do not have the P tag, we have to use a non-intelligent selector to manage the paragraph, for example using a class in each paragraph element.paragraphto indicate. One disadvantage of doing this is that these stylesheets are not portable, because you can no longer apply these styles to the desired element without specifying the corresponding class name for the label of the HTML document.
Non-intelligent selectors are sometimes necessary, and few of us are completely dependent on the smart selector. However, some non-intelligent selectors may become "stupid" selectors because they are improperly paired with the structure and performance of the document. I'm going to talk about.buttonthis "stupid" selector with a very high frequency.
Benefits of different combinations
The smart selector is not limited to the underlying elements that are provided to us in the HTML specification. To build a complex intelligent selector, you can differentiate the underlying elements by following a combination of context and feature attributes . Some elements, for example, provide a large number of functional differences for developers to consider and exploit. Other elements, such as
elements, have no difference in explicit functionality in any scenario, but also assume slightly different roles based on context.
Header p {/
* styles for prologic paragraphs/
}
footer p {/
* styles for epilogic paragraphs />}
Simple descendant selectors like this are useful because they allow us to visually see the different types of an element without physically changing the underlying document. This is the reason for the entire stylesheet invention: to facilitate physical separation without destroying the conceptual interrelationships that exist between documents and design.
Inevitably, some oocss fans are a bit less agreeable to this descendant selector, and they prefer to mark it like the following example, which is found in the BEM "definition" document.
1
I'm not going to go into further discussion of descendant selectors because I'm sure you're using them every day, unless you prefer an overview of this excess. In other words, we'll focus on the difference between the features described in the property selector and the attribute.
Hyperlink Properties
Even proponents of the notion of separation between CSS and HTML are happy to admit that some attributes--most of the attributes except class and custom data attributes--actually have an important relationship to the internal work of the document. Nohrefattributes your hyperlink won't link to anything. Withouttypeattributes, browsers cannot know which type of input element is rendered. Withouttitleattributes, yourabbrelement may represent anything.
Attributes like this help improve the semantics of document details, or you need to verify that the theme elements are properly rendered and operational. If they do not exist, then they should be created, and if they already exist, why not apply them? You can't just write CSS without writing HTML.
Rel Property
relA property is a standard attribute of a link relationship and is a method of describing the specific purpose of a link. Not all links have the same functionality. Benefit from the numerous WordPress usersrel="prev"andrel="next"become the two most widely adopted values, and help describe the relationship between each individual page of the paging blog content. Semantically, a tag with arelproperty is still aalabel, but we've been able to show it more specifically. This is not the same as the class, which is semantically indirect.
relAttributes should be used only where appropriate, because they are maintained by the HTML functionality specification and can therefore be used by different user agents to improve user experience and search engine accuracy. So, have you ever added a style to a link as follows? Use a simple property selector, such as:
[rel= "Prev"] {/
* styling for "previous links"/
}
[rel= "Next"] {/
* styling for "Next" links */
}
The property selector is supported by all browsers except the oldest and backward browsers (IE6), so there is no reason not to use them as long as the attribute exists in the label. In terms of its priority, it has the same weight as the class. However, I remember it was suggested that we should separate the document from the presentation semantics. I don't want to waste thisrelattribute, so I'd better element set a meaningless attribute and use it to add style.
1 previous page
The first thing to note here is that the only one of the above elements that does not help the semantics of the document is the attribute of the class. In other words, class is the only thing in the document Chinese that does not have a functional role to play. In practice, this means that the class is the only one that breaks the law of Separation and is interpreted as: it actually exists in the document without any help for the structure of the document.
OK, so many abstract concepts, but what about maintainability? Everyone accepts usingclassas a style hook, let's see what happens when you remove some attributes by editing or refactoring. Suppose we use a pseudo element to[rel="prev"]add a left-pointing arrow to the text of the link:
1
. prev:before {
2
content: ' \2190 ';/* encoding for a left-pointing arrow ("←") * *
3}
Removing a class also removes the pseudo element at the same time, which in turn removes the arrows. But without this arrow, there will be nothing else to tell us about the existing relationship of the linkprev. For the same reason, removingrelattributes also causes the arrows to be incomplete: Because whileclassthis arrow will continue to be displayed, it always causes the document's state relationship to be lost. Only by giving the style and application directly through the semantic attributes can you keep your code and yourself real. As long as it is the real function that exists in the document, you must let it be seen.
Property string
I can imagine what you're thinking: "It's interesting, but how many of these semantic-style hooks are there in hyperlinks?" I would still have to rely on classes to apply styles. "Then take a look at the incomplete list of different link features below, all based onaelements:
- links to external resources,
- links to secure pages,
- links to author pages,
- Lin KS to help pages,
- links to previous pages (the example above),
- links to next pages (for example Abov E again),
- links to PDFs,
- links to documents,
- links to ZIP folders,
- li Nks to executables,
- links to internal page fragments,
- links that are the really buttons (more in these L ater),
- links that is are really buttons and are toggle-able,
- links that open mail clients,
- l Inks that cue up telephone numbers on smartphones,
- links to the source view of pages,
- links that Ope N New tabs and Windows,
- links to JavaScript and JSON files,
- links to RSS feeds and XML files.
This is the difference in link functionality, and all types can be identified by the user agent. Now let's think about a problem, and in order for all of these specific link types to perform different functions, they must have different attributes. In other words, in order to perform different functions, the writing form of the link needs to be changed, and if they are written in different forms, they can add different styles.
In preparing this article, I made a test of an idea, named Auticons. Auticons is an icon font and style sheet that you can use to automatically add styles to a link. All the selectors inside are property selectors without a class that invokes the style for a well-formed hyperlink.
In many cases, auticonshrefqueries a subset of values to determine the functionality of hyperlinks. It is also possible to use the beginning or end of their property values to add styles to the corresponding elements, or to find the corresponding elements based on whether their property values contain a specified string. Here are some common examples.
security protocols each well-formed URL (for example, the URL of an absolute address) starts with a URI scheme plus a colon. The most common thing we have in the network ishttp:, butmailTo:(for Simple Mail Transfer Protocol SMTP) andtel:(for phone numbers) is also very common. If we can know how the value of the hyperlinkhrefwill start, we can use this convention as a style hook. In the following example for a secure page, we use the^=comparator, meaning "to ... Start. "
1
[href^= "https:"] {
2/
* style properties exclusive to secure pages */
3}
In Auticons, a link to a secure page is decorated with a lock, based on a specifichrefsemantic pattern for identifying attributes. The advantages of doing this are:
- A link to a secure page--and just a security page--can be done with a padlock to make it look like a secure page link.
- Links that are no longer linked to secure pages lose thehttpprotocol. The padlock used as a metaphor also disappears.
- A link to the new secure page will also automatically use this padlock to mark the link.
When applied to dynamic content , this selector appears to be quite intelligent. Because the security link has its specific URI scheme, the property selector can anticipate its invocation: once the editor types in some content that contains a secure link, the link automatically applies the style to give the user a feeling that it is a secure link. Because you don't need any classes and edits to HTML, the links in the simple markdown are as follows:
[Link to secure page] (https://payment.example.com/)
But note that the use is[href^="https:"]not always correct, because it is not all HTTPS really secure. However, this is only when the browser itself is not very reliable. Professional browsers will render a padlock in the address bar when HTTPS is displayed.
File type
As I said, you can also add ahrefstyle to the hyperlink by what end of the attribute. In practice, this means that you can use CSS to indicate the type of file the link points to. Auticons support.txt,.pdf,.doc,.exeand some other formats, below are.zipan example of the format used$=to decidehrefwhat ends with:
1
[href$= ". zip"]:before, 2
[href$= ". Gz"]:before {
3
content: ' \e004 ';/* Unicode for the zip folder icon */
4}
Combination
Do you know how to add multiple classes to an element to create a style? Well, you can actually use the attribute selector to help you automate these tasks. Let's compare:
/* The CSS for the class approach
/. New-window-icon:after {
content: ' [new Window icon] '
;
Twitter-icon:before {
content: ' [Twitter icon] ';
}
/* The CSS for the attribute selector approach * *
[target= "_blank"]:after {
content: ' [new Window icon] ';}
[href*= "twitter.com/"]:before {
content: ' [Twitter icon] ';
}
(Note that the*=comparer means "content", and ifhrefthe value contains a stringtwitter.com/, the style should be on that element)
@heydonworks @heydonworks
Any Content editor that is responsible for adding a hyperlink to a Twitter page needs to know just two things: the URL and how to open it in a new tab. Because the property selector can help them find the corresponding hyperlink.
Inherited
Some of the other places you don't take into account are: What if you have a link that doesn't match any of the attribute selectors? What if this hyperlink is a regular old hyperlink? This selector is a very easy to remember and the pursuit of performance will be happy to hear the words "there is no other than it is more concise."
The inheritance of cascading property selectors is the same as when stacked with classes. First, it will add to yourastyle-assuming a rule to improve the accessibility of thetext-decoration: underlinelink, and then use the property selector you provide toafurther add cascading styles to the corresponding elements. Browsers such as IE7 do not fully support pseudo elements. However, because of inherited relationships, the link will still applyathe styles in the selector.
a {
color:blue;
text-decoration:underline;
}
A[rel= "external"]:after {
content: ' [icon for external links] ';
}
The actual button should be real.
In the following sections, we will detail the structure of our CSS bookmark to explain the error on the code. Before doing this, let's first look at what might be a bad selector sneaking into our workflow.
Oocss believers are still insisting on using classes because they are reusable, like components. So.buttonbetter than that#button. However, I can think of a better button-style selector. Its name is also easy to remember.
The
Topcoat is a oocss, BEM-based UI framework from Adobe. The various button-style codes in the topcoat are more than 450 lines , if you add the annotation blocks. The annotation block inside suggests that we apply the style of the button in the same way as this example.
1 Button
This is not a button. Because, if it is a button, it should be usedto make a label. In fact, in every browser we know, if you useit to represent a button without adding any style, it will look like a button by default. But the above example is not, because it uses alabel, it should be a hyperlink, in fact, it lacks onehref, which means it is not even a hyperlink. Technically, it's just a placeholder, an incomplete hyperlink that isn't complete.
a puppy in a shark costume is not a shark.
The example in Topcoat's CSS is just an example, but the premise is that the class defines the element and that the HTML is not deceptive (you should use the button tag instead of a tag to describe it). Adding more "meaningful hyphenation" to the class name does not make up for the ugliness of your use of the non-intelligent selector and the error of the code you are committing.
Update: because this article was written, Topcoat.io has used thetag to replace the example above. This is amazing! However, I have reservations about using.is-disabledclasses to indicate that the button is disabled and ignoresdisabledattributes. You can see the discussion in this area between me and topcoat representatives in the comments section. For the disaster with the Web standards that promote OOCSS, you can discover in semantic-ui.com that the "standard button" in the example is a label that contains an emptylabel
.
See, what is it?
"If it looks like a duck and swims like a duck and cries like a duck, it may be a duck," he said. ”
A button-like link, and it triggers a JavaScript event like a button click, and for many people it's a button. However, this only means that it has passed the first two stages of the "duck test". In order for all users to be able to use inductive and distinguishing buttons, it must also be like this. Because it is still a link, try to avoid this unnecessary confusion, because the user of this assistive technology does not pursue a perfect semantics but that is exactly what we should assume.
Still, some people insist on usingathe label as a button. A hyperlink is an element that is more easily styled completely again. If you chooseaa label as an element, there is only one way to get it closer to the real button. You guessed right: you must use the Wai ARIA role attribute value to indicate its meaning. You can confirm a hyperlink simply by using the following property selector for some reason that looks like a button.
1
[role= "button"] {
2/
* Semantic CSS for modified elements this are announced as "button" in assistive techno Logies * *
3}
Quality-assured Property Selector
CSS gives the class attribute the power to design their "document language" based on elements that have no representation (such as div and span) and to give them style information through the class attribute. The author should avoid this behavior even though the structural elements of this document language are often recognized and accepted by everyone. "– Selector," CSS Level 2, the Consortium
athe reason we have andbuttontwo elements is to divide the semantics between two completely different functional interactions. A hyperlink represents a symbol of a location you will go to, and a button is the trigger for an event or action. One is about position movement, and the other is focused on conversion. One is the promotion of secession, the other is the promotion of integration.
To make sure we don't do anything stupid to confuse our buttons and hyperlinks. We will create a CSS bookmark that uses the Smart property selector to test the effectiveness and quality of the two elements.
Inspired by Eric Meyer's article and some clues from diagnosticss, this stylesheet combines the attribute selector and:notselector (or not pseudo class) to highlight the problem in HTML. Unlike its two implementations, it uses pseudo elements to print errors to the screen. Each error is displayed in a cartoon font and a pink background.
By connecting the features to the form, we can see that ugly html indirectly leads to ugly CSS. This is the result of the misuse of documents by designers. Try torevenge.csssave it in your CSS bookmark and click the bookmark to trigger it on any page you like. Note: It does not work on a page in which the service is on the HTTPS protocol.
Revenge. Css
Drag to your bookmarks bar.
Rule 1
If it's a hyperlink, it should have ahrefproperty.
A:not ([href]): After {
content: ' Does you mean ' is a ' to ' is a button, because it does not link to anything !';
Display:block!important;
Background:pink!important;
Padding:0.5em!important;
Font-family: ' Comic Sans MS ', cursive!important;
Color: #000!important;
FONT-SIZE:16PX!important;
}
Note: In this example I am not going to test the value of the attribute, but to test whether the attribute is set, that is, [href] matches any element that contains the href attribute. This test applies only to hyperlinks. This test allows you to understand that "for each element that does not have an HREF attribute, add a pseudo element to it and report an error hint in the pseudo element." ”
Rule 2
"If the hyperlink has an href attribute, then this property should have a value." ”
1 a[href= ""]:after, a[href$= "#"]:after, a[href^= "JavaScript"]:after {
2 content: ' Do your mean for this link is a button, because it does not go anywhere! ';
3/* ... ugly styles ... * *
4}
Note: If the value of the href attribute is empty or ends with a # or uses JavaScript, it should be used as a button for a non-tag implementation. Note that I am using "start with JavaScript", which avoids the use of a value such as javascript:void (0). But we can't expect it to always be written in this way.
Rule 3
"If it uses the button class, it should be a button, at least on the accessibility layer." ”
1. Button:not (Button): Not ([role= "button"]): Not ([type= "button"]): Not ([type= ' Submit ']): Not ([type= "Reset"]): After,
2. Btn:not (Button): Not ([role= "button"]): Not ([type= "button"]): Not ([type= ' Submit ']): Not ([type= "Reset"]): After,
3 a[class*= "button"]:not ([role= "button"]): after {
4 content: ' If you are going the IT look like a button, make it a button, damn it! ';
5/* ... ugly styles ... * *
6}
Note: In this example, we show you how you can use chain negation when testing the value of a property. Each selector can be understood like this: "If an element has a class that indicates it is a button, but it is not a button element, and does not have a correct role value to make it a button in the accessibility layer, and it is not a button type INPUT element, well ... You're lying. "I had to use [class*= button] to capture the different classes (up to 62) that were not applied in the hyperlinks in the topcoat that didn't use role to be the actual button. )。 I noticed that some developers use Button-container and other similar class names on the parent of the button, which is why a modifier is contained inside. You may notice that the BTN class is used in the Twitter Bootstrap, (if you read its component documentation carefully) you will know that it is not sure whether to use a link or a button as a button.
Rule 4
If an element has a role= "button", it should be able to link to a place even without JavaScript.
1 a[role= "button"]:not ([href*= "/"]): Not ([href*= ".]): Not ([href*="?]): After {
2 content: ' Either use a link fallback, or just use a BUTTON element. '
3/* ... ugly styles ... * *
4}
Note: We can be quite sure that we do not include/,. (usually in front of the filename extension) or? (the beginning of the query string) One of the href should be false. Make the link appear as a button and it's good to have JavaScript open and return:false. The reason is that when JavaScript closes, it can also be linked to a place. In fact, this is just a reasonable reason I can think of not using.
Rule 5
"You are not able to disable a hyperlink." ”
1 a.button[class*= "Disabled"]:after,
2 A.btn.disabled:after,
3 a[class*= "button"][class*= "disabled"]:after {
4 content: ' You cannot disable a hyperlink. Use a BUTTON element with disabled= "disabled".
5/* ... ugly styles ... * *
6}
Note: Even a very old user agent can recognize the disabled attribute, so we can use it appropriately in some of the appropriate elements. As can be seen from the example above, you can connect a property selector as if you were connected to multiple classes: In the last three selectors, we declared, "If a hyperlink's class contains a button string and a disabled string, the error message is printed for it." "Twitter Bootstrap uses the second form,. btn.disabled, in its style sheet, but does not contain a prefix. If it's used in a hyperlink, we'll just think it's a mistake.
Rule 6
"The buttons in the form should have an explicit type. ”
1 Form Button:not ([type]): after {
2 content: ' Is this a submit button, a reset button or what? Use type= "Submit", type= "reset" or type= "button";
9 ·
Note: We need to determine whether the buttons in the form have a definite type, because some browsers will set all button elements without an explicit type to type= "submit". If the button in our form has another parent, we must absolutely guarantee that the type of the button is not a submit.
Rule 7
"Either a button or a hyperlink should have some content in it or a aria label." ”
A:empty:not ([Aria-label]): Not ([Aria-labelledby]): After,
Button:empty:not ([Aria-label]): Not ([Aria-labelledby]): After,
Button:not ([Aria-label]): Not ([Aria-labelledby]) Img:only-child:not ([Alt]): After,
A:not ([Aria-label]): Not ([Aria-labelledby]) Img:only-child:not ([Alt]): after {
Content: ' All buttons and links should have text content, a image with alt-text or an ARIA label ';
/* ... ugly styles ... * *
}
Note: buttons and links do not have a clear purpose--in the form of text and images--are quite bogus. The last two selectors are the most complex selectors I've ever written. For the version of the hyperlink, this selector should read, "If a hyperlink does not have aaria-labelproperty oraria-labelledbyproperty, and it contains only one picture element as content, but the picture does not havealtattributes, then the associated error message is printed." "Also, note this:emptyselector." The argument is that elements that are not automatically closed should never be empty.
Summarize
The selectors and patterns I used to describe in the example above are not trying to write something different. The property selector is no novelty. IE 6 is the only browser that does not support it. The reason I use them is that I don't have the time and energy to write the selector over the CSS again and write it in completely HTML. I use the head on my page[role="banner"]instead of using.page-headerit because it's the only way I know--based on seeing the desired visual effects--and being able to put the navigation signs in the right place.
There is no semantic css, only semantic HTML and its visible form. I've shown these things in this article, and by combining the functionality and composition of a Web page directly, you can create rewards and penalties. On the one hand, you can set the selector to add visible patterns to those tags that are correctly used; On the other hand, you can find the ugly wrong way to apply the tag structure and print their errors on the page.
To be honest, not all style hooks are completely semantic and intelligent. Classes are described as elements that need to be applied and fillers that have not yet become standard attributes. So you can see that it.footerbecomesas welltype="text"(through JavaScript to validate the URL) that it can be used directlytype="url"to validate the URL. At other times, it is useful for making the non semantic layout of scaffolding based on the grid framework.
However, when you decide to give CSS a completely independent logic, there will be an unnecessary disagreement between the function and the structure. In this case, you only have to improve your vigilance to make them not difficult to understand and ineffective. Worse, the pursuit of fully semantic classes tends to plunge you into the endless discussion of what is a semantic class. You will start to spend less time using the remote control to operate the TV and become more time to stand in front of you and think about how to use your remote control.
Life is very short, please cherish the time.
Translator's Sign Language: the entire translation is carried out according to the original line, and in the process of translation slightly individual understanding of the technology. If the translation has the wrong place, but also please peer friends pointing. Thank you!